diff --git a/examples/behaviorTemplate.lua b/examples/behaviorTemplate.lua deleted file mode 100644 index 383eb5f..0000000 --- a/examples/behaviorTemplate.lua +++ /dev/null @@ -1,20 +0,0 @@ --- -- Make sure to include filename in the init (prefix of the .lua)Utility = Utility or Require("lib/utility/client/utility.lua") --- local ParticlesBehaviors = { --- tag = "isTemplate", --- default = { --- } - --- } - --- function ParticlesBehaviors.OnSpawn(entityData) --- end - - --- function ParticlesBehaviors.OnRemove(entityData) --- end - --- function ParticlesBehaviors.OnUpdate(entityData) - --- end - --- return ParticlesBehaviors diff --git a/examples/cache.lua b/examples/cache.lua deleted file mode 100644 index c144bca..0000000 --- a/examples/cache.lua +++ /dev/null @@ -1,19 +0,0 @@ -AddEventHandler('onResourceStart', function(resource) - if resource == GetCurrentResourceName() then - Bridge.Cache.OnChange("Ped", function(newValue, oldValue) - print("Ped changed from " .. tostring(oldValue) .. " to " .. tostring(newValue)) - end) - end -end) - - -RegisterCommand("testcache", function(source, args, rawCommand) - -- local cache = Bridge.Cache.Get("Ped") - Bridge.Cache.Create("TestCache", function() - return math.random(1, 100) - end, 1000) - - Bridge.Cache.OnChange("TestCache", function(newValue, oldValue) - print("TestCache changed from " .. tostring(oldValue) .. " to " .. tostring(newValue)) - end) -end) \ No newline at end of file diff --git a/examples/callbacks.lua b/examples/callbacks.lua deleted file mode 100644 index ada0ea7..0000000 --- a/examples/callbacks.lua +++ /dev/null @@ -1,40 +0,0 @@ --- ▄▀▀ ▄▀▄ █ █ ██▄ ▄▀▄ ▄▀▀ █▄▀ ▄▀▀ ▄▀▀ █▄█ ▄▀▄ █▀▄ ██▀ █▀▄ █ █ █▄ █ █ ▀█▀ ▀█▀ ██▀ ▄▀▀ ▀█▀ --- ▀▄▄ █▀█ █▄▄ █▄▄ █▄█ █▀█ ▀▄▄ █ █ ▄█▀ ▄█▀ █ █ █▀█ █▀▄ █▄▄ █▄▀ ▀▄█ █ ▀█ █ █ █ █▄▄ ▄█▀ █ - --- -- -- -- -- -- -- -- -- -- --- ▄▀▀ ██▀ █▀▄ █ █ ██▀ █▀▄ --- ▄█▀ █▄▄ █▀▄ ▀▄▀ █▄▄ █▀▄ --- -- -- -- -- -- -- -- -- -- -if not IsDuplicityVersion() then goto client end - -Bridge.Callbacks.Register('callback_test1_name_here', function(src, var1) - if var1 == "herpaderpa" then - print("this is a test") - end - return 'some random string', "some other string" -end) - -RegisterCommand('callback_test2', function(source) - local someData, other = Bridge.Callbacks.Trigger('callback_test2_name_here', source, "herpaderpa") - print("Data From Client: ", someData, other) -end) - --- -- -- -- -- -- -- -- -- -- --- ▄▀▀ █ █ ██▀ █▄ █ ▀█▀ --- ▀▄▄ █▄▄ █ █▄▄ █ ▀█ █ --- -- -- -- -- -- -- -- -- -- -if IsDuplicityVersion() then return end -::client:: - -RegisterCommand('callback_test1', function() - local somerandomstring, someotherrandomstring = Bridge.Callbacks.Trigger('callback_test1_name_here', "herpaderpa") - print("Data From Server: ", somerandomstring, someotherrandomstring) -end) - --- exports.community_bridge:RegisterRebound('callback_test1', function(src, cb, ftpcsftug) --- print("this is a rebound to all players") --- end) - -Bridge.Callbacks.Register('callback_test2_name_here', function(ftpcsftug) - return ftpcsftug, 'TestyMcTesterton' -end) diff --git a/examples/cliententities.lua b/examples/cliententities.lua deleted file mode 100644 index a303466..0000000 --- a/examples/cliententities.lua +++ /dev/null @@ -1,367 +0,0 @@ -Bridge = Bridge or exports['community_bridge']:Bridge() --- RegisterCommand("ClientEntityParticles", function() --- local position = GetEntityCoords(PlayerPedId()) --- local data = Bridge.ClientEntity.Create({ --- id = "particle_" .. math.random(1, 10000), --- model = "mp_m_freemode_01", --- coords = position, --- entityType = "ped", --- freeze = false, --- follow = { --- target = 1, --- }, --- weapon = { --- name = "WEAPON_PISTOL", --- ammo = 100 --- }, --- stash = { --- -- id = "generate from server", --- label = "Test Stash", --- target = { --- label = "Open Stash", --- description = "Access the stash to store or retrieve items.", --- icon = "fas fa-boxes" --- } --- }, --- attach = { --- target = 1, --- bone = 57005, -- right hand --- }, --- scenarios = { --- name = "WORLD_HUMAN_CLIPBOARD", --- introClip = true, --- duration = 20000 --- }, --- anim = { --- dict = "anim@mp_player_intcelebrationmale@wave", --- name = "wave", --- flags = 49, --- duration = -1, --- onComplete = function(entityData) --- Bridge.ClientEntity.Set(entityData.id, "anim", { --- dict = "rcmnigel1c", --- name = "hailing_whistle_waive_a", --- flags = entityData.anim.flags, --- duration = 10000, --- onComplete = function(entityData) --- Bridge.ClientEntity.Set(entityData.id, "anim", { --- dict = "timetable@denice@ig_1", --- name = "idle_b", --- flags = entityData.anim.flags, --- duration = 10000, --- onComplete = function(entityData) --- print("hello") --- end --- }) --- end --- }) --- end --- }, --- clothing = { --- components = { --- { drawable = 0, texture = 0, component_id = 0 }, --- { drawable = 0, texture = 0, component_id = 1 }, --- { drawable = 19, texture = 0, component_id = 2 }, --- { drawable = 6, texture = 0, component_id = 3 }, --- { drawable = 0, texture = 0, component_id = 4 }, --- { drawable = 0, texture = 0, component_id = 5 }, --- { drawable = 0, texture = 0, component_id = 6 }, --- { drawable = 0, texture = 0, component_id = 7 }, --- { drawable = 23, texture = 0, component_id = 8 }, --- { drawable = 0, texture = 0, component_id = 9 }, --- { drawable = 0, texture = 0, component_id = 10 }, --- { drawable = 4, texture = 2, component_id = 11 } --- }, --- props = { --- { drawable = 27, prop_id = 0, texture = 0 }, --- { drawable = 0, prop_id = 1, texture = 0 }, --- { drawable = 0, prop_id = 2, texture = 0 }, --- { drawable = 0, prop_id = 3, texture = 0 }, --- { drawable = 0, prop_id = 4, texture = 0 }, --- { drawable = 0, prop_id = 5, texture = 0 }, --- { drawable = 0, prop_id = 6, texture = 0 }, --- { drawable = 0, prop_id = 7, texture = 0 }, --- { drawable = 0, prop_id = 8, texture = 0 }, --- { drawable = 0, prop_id = 9, texture = 0 }, --- { drawable = 0, prop_id = 10, texture = 0 }, --- { drawable = 0, prop_id = 11, texture = 0 }, --- { drawable = 0, prop_id = 12, texture = 0 }, --- { drawable = 0, prop_id = 13, texture = 0 } --- } --- }, --- particles = { --- { --- dict = "core", --- ptfx = "ent_dst_electrical", --- offset = vector3(0.0, 1.0, 0.0), --- looped = true --- }, --- { --- dict = "core", --- ptfx = "ent_dst_electrical", --- offset = vector3(0.0, -1.0, 0.0), --- rotation = vector3(0.0, 0.0, 180.0), --- looped = true, --- loopLength = 1000 --- } --- }, --- targets = { --- { --- label = "Follow Test", --- distance = 2, --- description = "A test particle for demonstration purposes.", --- onSelect = function (entityData, entity) --- FreezeEntityPosition(entity, false) --- Bridge.ClientEntity.Set(entityData.id, "follow", { --- target = PlayerPedId() --- }) --- end --- } --- }, --- -- OnUpdate = function(entityData) - --- -- end, --- }) --- -- Wait(5000) --- Bridge.ClientEntity.Set(data.id, "targets", { --- label = "This should be the new label", --- distance = 2, --- description = "Herpa derpa gihad", --- onSelect = function (entityData, entity) --- print("round 2 baby", entityData.id) --- end --- }) --- end, false) - - --- Bridge.ClientEntity.Behaviors.Create("plate", { --- tag = "something", --- OnCreate = function(entityData) - --- end, --- OnSpawn = function(entityData) - --- end, --- OnUpdate = function(entityData) --- -- Update logic here --- end, --- OnRemove = function(entityData) - --- end, --- OnDestroy = function(entityData) - --- end --- }) - -RegisterCommand("ClientEntityFreeze", function() - local position = GetEntityCoords(PlayerPedId()) - local data = Bridge.ClientEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - freeze = true - }) - Wait(10000) - Bridge.ClientEntity.Set(data.id, "freeze", false) -end, false) - -RegisterCommand("ClientEntityFollow", function() - local position = GetEntityCoords(PlayerPedId()) - local serverId = GetPlayerServerId(PlayerId()) - local data = Bridge.ClientEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - freeze = false, - follow = { - speed = 3.0, - target = serverId, - distance = 5.0 - } - }) - print(data.id) -end, false) - -RegisterCommand("ClientEntityWeapon", function() - local position = GetEntityCoords(PlayerPedId()) - local data = Bridge.ClientEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - weapon = { - name = "WEAPON_PISTOL", - ammo = 100 - } - }) -end, false) - - -RegisterCommand("ClientEntityAttach", function() - local position = GetEntityCoords(PlayerPedId()) - local serverId = GetPlayerServerId(PlayerId()) - Bridge.ClientEntity.Create({ - id = "attach_" .. math.random(1, 10000), - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - attach = { - target = serverId, - bone = 57005 - } - }) -end, false) - -RegisterCommand("ClientEntityScenarios", function() - local position = GetEntityCoords(PlayerPedId()) - Bridge.ClientEntity.Create({ - id = "scenarios_" .. math.random(1, 10000), - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - scenarios = { - name = "WORLD_HUMAN_CLIPBOARD", - introClip = true, - duration = 20000 - } - }) -end, false) - -RegisterCommand("ClientEntityAnim", function() - local position = GetEntityCoords(PlayerPedId()) - Bridge.ClientEntity.Create({ - id = "anim_" .. math.random(1, 10000), - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - anim = { - dict = "anim@mp_player_intcelebrationmale@wave", - name = "wave", - flags = 49, - duration = -1, - onComplete = function(entityData) - Bridge.ClientEntity.Set(entityData.id, "anim", { - dict = "rcmnigel1c", - name = "hailing_whistle_waive_a", - flags = entityData.anim.flags, - duration = 10000, - onComplete = function(entityData) - Bridge.ClientEntity.Set(entityData.id, "anim", { - dict = "timetable@denice@ig_1", - name = "idle_b", - flags = entityData.anim.flags, - duration = 10000, - onComplete = function(entityData) - print("hello") - end - }) - end - }) - end - } - }) -end, false) - -RegisterCommand("ClientEntityClothing", function() - local position = GetEntityCoords(PlayerPedId()) - Bridge.ClientEntity.Create({ - id = "clothing_" .. math.random(1, 10000), - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - clothing = { - components = { - { drawable = 0, texture = 0, component_id = 0 }, - { drawable = 0, texture = 0, component_id = 1 }, - { drawable = 19, texture = 0, component_id = 2 }, - { drawable = 6, texture = 0, component_id = 3 }, - { drawable = 0, texture = 0, component_id = 4 }, - { drawable = 0, texture = 0, component_id = 5 }, - { drawable = 0, texture = 0, component_id = 6 }, - { drawable = 0, texture = 0, component_id = 7 }, - { drawable = 23, texture = 0, component_id = 8 }, - { drawable = 0, texture = 0, component_id = 9 }, - { drawable = 0, texture = 0, component_id = 10 }, - { drawable = 4, texture = 2, component_id = 11 } - }, - props = { - { drawable = 27, prop_id = 0, texture = 0 }, - { drawable = 0, prop_id = 1, texture = 0 }, - { drawable = 0, prop_id = 2, texture = 0 }, - { drawable = 0, prop_id = 3, texture = 0 }, - { drawable = 0, prop_id = 4, texture = 0 }, - { drawable = 0, prop_id = 5, texture = 0 }, - { drawable = 0, prop_id = 6, texture = 0 }, - { drawable = 0, prop_id = 7, texture = 0 }, - { drawable = 0, prop_id = 8, texture = 0 }, - { drawable = 0, prop_id = 9, texture = 0 }, - { drawable = 0, prop_id = 10, texture = 0 }, - { drawable = 0, prop_id = 11, texture = 0 }, - { drawable = 0, prop_id = 12, texture = 0 }, - { drawable = 0, prop_id = 13, texture = 0 } - } - } - }) -end, false) - -RegisterCommand("ClientEntityParticles", function() - local position = GetEntityCoords(PlayerPedId()) - Bridge.ClientEntity.Create({ - id = "particles_" .. math.random(1, 10000), - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - particles = { - { - dict = "core", - ptfx = "ent_dst_electrical", - offset = vector3(0.0, 1.0, 0.0), - looped = true - }, - { - dict = "core", - ptfx = "ent_dst_electrical", - offset = vector3(0.0, -1.0, 0.0), - rotation = vector3(0.0, 0.0, 180.0), - looped = true, - loopLength = 1000 - } - } - }) -end, false) - -RegisterCommand("ClientEntityTargets", function() - local position = GetEntityCoords(PlayerPedId()) - local derp = Bridge.ClientEntity.Create({ - id = "targets_" .. math.random(1, 10000), - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - targets = { - { - label = "Initial test", - distance = 2, - description = "A test particle for demonstration purposes.", - onSelect = function (entityData, entity) - print("Selected entity:", entityData.id) - end - } - } - }) - Wait(10000) - Bridge.ClientEntity.Set(derp.id, "targets", - { - { - label = "Follow Test", - distance = 2, - description = "A test particle for demonstration purposes.", - onSelect = function (entityData, entity) - Bridge.ClientEntity.Set(entityData.id, "freeze", false) - Bridge.ClientEntity.Set(entityData.id, "follow", { - target = PlayerPedId() - }) - end - } - } - ) -end, false) - diff --git a/examples/dialogue.lua b/examples/dialogue.lua deleted file mode 100644 index 53582e9..0000000 --- a/examples/dialogue.lua +++ /dev/null @@ -1,60 +0,0 @@ -Bridge = Bridge or exports['community_bridge']:Bridge() -RegisterCommand("dialogue", function() - local pos = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0, 2.0, 0) - local timeout = 500 - local model = `a_f_y_hipster_01` - RequestModel(model) - while not HasModelLoaded(model) do - Wait(0) - timeout = timeout - 1 - if timeout == 0 then - print("Failed to load model") - return - end - end - local ped = CreatePed(0, model, pos.x, pos.y, pos.z, 0.0, false, false) - SetEntityHeading(ped, 50.0) - local characterData = { - entity = ped, - offset = vector3(0, 0, 0), - rotationOffset = vector3(0, 0, 0) - } - Bridge.Dialogue.Open("Akmed", "Hello how are you doing my friend?", ped, { - { - label = "Trade with me", - id = 'something', - }, - { - label = "Goodbye", - id = 'someotherthing', - }, - }, - function(selectedId) - if selectedId == 'something' then - Dialogue.Open( "Akmed" , "Thank you for wanting to purchase me lucky charms", characterData, { - { - label = "Fuck off", - id = 'something', - }, - { - label = "Goodbye", - id = 'someotherthing', - }, - }, - function(selectedId) - DeleteEntity(ped) - if selectedId == "something" then - print("You hate lucky charms") - else - print("Thanks for keeping it civil") - end - end) - else - DeleteEntity(ped) - end - end) -end) - - - - diff --git a/examples/input.lua b/examples/input.lua deleted file mode 100644 index 9e2635c..0000000 --- a/examples/input.lua +++ /dev/null @@ -1,234 +0,0 @@ --- Test QB Format Input -RegisterCommand('input_test_qb', function() - local qbFormatData = { - inputs = { - { - text = "Player Name", - name = "playername", - type = "text", - isRequired = true, - default = "John Doe" - }, - { - text = "Player ID", - name = "playerid", - type = "number", - isRequired = true - }, - { - text = "Password", - name = "password", - type = "password", - isRequired = false - }, - { - text = "Vehicle Type", - name = "vehicle", - type = "select", - isRequired = true, - options = { - {value = "car", text = "Car"}, - {value = "bike", text = "Motorcycle"}, - {value = "truck", text = "Truck"} - } - }, - { - text = "Enable Notifications", - name = "notifications", - type = "checkbox", - isRequired = false, - options = { - {value = "email", text = "Email", checked = true}, - {value = "sms", text = "SMS", checked = false} - } - } - } - } - - local result = Input.Open("QB Format Test", qbFormatData, true, "Submit") - if result then - print("QB Format Result:") - for k, v in pairs(result) do - print(k .. ": " .. tostring(v)) - end - else - print("QB Format: User cancelled or no input") - end -end, false) - --- Test Ox Format Input -RegisterCommand('input_test_ox', function() - local oxFormatData = { - { - type = "input", - label = "Character Name", - name = "charname", - required = true, - default = "Jane Smith" - }, - { - type = "number", - label = "Age", - name = "age", - required = true, - min = 18, - max = 100 - }, - { - type = "select", - label = "Job Category", - name = "jobcat", - required = true, - options = { - {value = "civ", label = "Civilian"}, - {value = "leo", label = "Law Enforcement"}, - {value = "ems", label = "Emergency Medical"} - } - }, - { - type = "checkbox", - label = "Has License", - name = "license", - required = false - }, - { - type = "color", - label = "Favorite Color", - name = "color", - default = "#ff0000" - }, - { - type = "date", - label = "Birth Date", - name = "birthdate", - format = "DD/MM/YYYY" - } - } - - local result = Input.Open("Ox Format Test", oxFormatData, false) - if result then - print("Ox Format Result:") - for k, v in pairs(result) do - print(k .. ": " .. tostring(v)) - end - else - print("Ox Format: User cancelled or no input") - end -end, false) - --- Test Simple Text Input -RegisterCommand('input_test_simple', function() - local simpleData = { - inputs = { - { - text = "Enter your message", - name = "message", - type = "text", - isRequired = true - } - } - } - - local result = Input.Open("Simple Input", simpleData, true, "Send") - if result then - print("Simple Input Result: " .. (result.message or "No message")) - else - print("Simple Input: Cancelled") - end -end, false) - --- Test All Input Types (QB Format) -RegisterCommand('input_test_all_types', function() - local allTypesData = { - inputs = { - { - text = "Text Input", - name = "text_field", - type = "text", - isRequired = false, - default = "Sample text" - }, - { - text = "Number Input", - name = "number_field", - type = "number", - isRequired = false, - default = 42 - }, - { - text = "Password Input", - name = "password_field", - type = "password", - isRequired = false - }, - { - text = "Radio Selection", - name = "radio_field", - type = "radio", - isRequired = false, - options = { - {value = "option1", text = "Option 1"}, - {value = "option2", text = "Option 2"}, - {value = "option3", text = "Option 3"} - } - }, - { - text = "Checkbox Options", - name = "checkbox_field", - type = "checkbox", - isRequired = false, - options = { - {value = "check1", text = "Check 1", checked = true}, - {value = "check2", text = "Check 2", checked = false}, - {value = "check3", text = "Check 3", checked = false} - } - }, - { - text = "Select Dropdown", - name = "select_field", - type = "select", - isRequired = false, - options = { - {value = "val1", text = "Value 1"}, - {value = "val2", text = "Value 2"}, - {value = "val3", text = "Value 3"} - } - } - } - } - - local result = Input.Open("All Input Types Test", allTypesData, true, "Test Submit") - if result then - print("All Types Result:", json.encode(result)) - - else - print("All Types: User cancelled") - end -end, false) - --- Test Error Handling -RegisterCommand('input_test_error', function() - -- Test with invalid data - local result = Input.Open("Error Test", nil, true) - if result then - print("Error test unexpectedly succeeded") - else - print("Error test correctly handled nil data") - end - - -- Test with empty inputs - local emptyData = {inputs = {}} - local result2 = Input.Open("Empty Test", emptyData, true) - if result2 then - print("Empty test result: " .. json.encode(result2)) - else - print("Empty test: No result") - end -end, false) - --- print("Input unit tests loaded. Available commands:") --- print(" /input_test_qb - Test QB format input") --- print(" /input_test_ox - Test Ox format input") --- print(" /input_test_simple - Test simple text input") --- print(" /input_test_all_types - Test all input types") --- print(" /input_test_error - Test error handling") \ No newline at end of file diff --git a/examples/locale.lua b/examples/locale.lua deleted file mode 100644 index bd046bc..0000000 --- a/examples/locale.lua +++ /dev/null @@ -1,16 +0,0 @@ --- if outside this resource, use local whatever = Require("modules/locales/shared.lua") --- whatever.Locales("some-index-in-language-.json-file") --- Files must be stored in "locales" folder, within the resource. --- Instead of using Require you can also import it via the manifest. --- The Lang variable is available globally, which tells you what the server is using. --- print("Language: ", Lang) --- print("Locale: ", Language.Locale("UNITTEST.locale-unit-test")) - --- Example outside community bridge resource: - --- local Language = Require('modules/locales/shared.lua') --- print("Language: ", Lang) --- print("Locale: ", Language.Locale("UNITTEST.locale-unit-test")) -RegisterCommand("lang", function(source, args, raw) - print( "Oh also this works", Language.Locale("placeable_object.place_object_scroll_down")) -end, false) \ No newline at end of file diff --git a/examples/particle.lua b/examples/particle.lua deleted file mode 100644 index 5e14be1..0000000 --- a/examples/particle.lua +++ /dev/null @@ -1,7 +0,0 @@ - -RegisterCommand("test_particle", function(source, args, rawCommand) - local playerPed = PlayerPedId() - local coords = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 1.0, 0.0) - local heading = GetEntityHeading(playerPed) - Particle.Create("core", "ent_dst_concrete_large", coords, vector3(0.0, 0.0, heading), 1.0, vector3(1.0, 1.0, 1.0), false) -end) \ No newline at end of file diff --git a/examples/placeableObject.lua b/examples/placeableObject.lua deleted file mode 100644 index 2b2f7ad..0000000 --- a/examples/placeableObject.lua +++ /dev/null @@ -1,38 +0,0 @@ -local isPlacing = false -RegisterCommand('startplacer', function(source, args, rawCommand) - if Bridge.PlaceableObject.IsPlacing() then - print("Already placing an object.") - return - end - - local model = args[1] or 'prop_barrel_01a' -- Default model if none provided - local position = GetEntityCoords(PlayerPedId()) - local result = Bridge.PlaceableObject.Create(model, { - allowMovement = true, -- Enable movement mode - allowNormal = true, -- Enable normal mode - allowVertical = false, -- Allow vertical movement in normal mode - startMode = 'normal', -- Start in normal mode - depthMin = 2.0, - depthMax = 15.0, - heightStep = 0.2, -- Height adjustment step - boundary = {min = vector3(position.x - 5, position.y - 5, position.z - 1.5), max = vector3(position.x + 5, position.y + 5, position.z + 10)}, - showInstructionalButtons = true, -- Show instructional buttons - }) - - if result then - print("Object placed!") - print("Position:", result.position) - print("Heading:", result.heading) - else - print("Placement cancelled") - end -end) - - -RegisterCommand("startplacerold", function(source, args, rawCommand) - local model = args[1] or 'prop_barrel_01a' -- Default model if none provided - local distance = tonumber(args[2]) or 5.0 -- Default distance if not provided - local snapToGround = true - local offset = vector3(0.0, 0.0, 0.0) -- No offset - local obj = Bridge.Placeable.PlaceObject(model, distance, snapToGround, {}, offset) -end) \ No newline at end of file diff --git a/examples/serverentities.lua b/examples/serverentities.lua deleted file mode 100644 index bc9a558..0000000 --- a/examples/serverentities.lua +++ /dev/null @@ -1,115 +0,0 @@ -Bridge = Bridge or exports['community_bridge']:Bridge() - -RegisterCommand("ServerEntityStash", function(src) - local position = GetEntityCoords(GetPlayerPed(src)) - vector3(0,0,1) - Bridge.ServerEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - stash = { - label = "Test Stash", - slots = 20, - maxWeight = 10000, - target = { - label = "Open Stash", - description = "Access the stash to store or retrieve items.", - icon = "fas fa-boxes" - } - } - }) -end, false) - -RegisterCommand("ServerEntityScenarios", function(src) - local position = GetEntityCoords(GetPlayerPed(src)) - vector3(0,0,1) - Bridge.ServerEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - scenarios = { - name = "WORLD_HUMAN_CLIPBOARD", - introClip = true, - duration = 20000 - } - }) -end, false) - -RegisterCommand("ServerEntityAnim", function(src) - local position = GetEntityCoords(GetPlayerPed(src)) - vector3(0,0,1) - Bridge.ServerEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - anim = { - dict = "anim@mp_player_intcelebrationmale@wave", - name = "wave", - flags = 49, - duration = -1, - } - }) -end, false) - -RegisterCommand("ServerEntityParticles", function(src) - local position = GetEntityCoords(GetPlayerPed(src)) - vector3(0,0,1) - Bridge.ServerEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - particles = { - { - dict = "core", - ptfx = "ent_dst_electrical", - offset = vector3(0.0, 1.0, 0.0), - looped = true - }, - { - dict = "core", - ptfx = "ent_dst_electrical", - offset = vector3(0.0, -1.0, 0.0), - rotation = vector3(0.0, 0.0, 180.0), - looped = true, - loopLength = 1000 - } - } - }) -end, false) - -RegisterCommand("ServerEntityClothing", function(src) - local position = GetEntityCoords(GetPlayerPed(src)) - vector3(0,0,1) - Bridge.ServerEntity.Create({ - model = "mp_m_freemode_01", - coords = position, - entityType = "ped", - clothing = { - components = { - { drawable = 0, texture = 0, component_id = 0 }, - { drawable = 0, texture = 0, component_id = 1 }, - { drawable = 19, texture = 0, component_id = 2 }, - { drawable = 6, texture = 0, component_id = 3 }, - { drawable = 0, texture = 0, component_id = 4 }, - { drawable = 0, texture = 0, component_id = 5 }, - { drawable = 0, texture = 0, component_id = 6 }, - { drawable = 0, texture = 0, component_id = 7 }, - { drawable = 23, texture = 0, component_id = 8 }, - { drawable = 0, texture = 0, component_id = 9 }, - { drawable = 0, texture = 0, component_id = 10 }, - { drawable = 4, texture = 2, component_id = 11 } - }, - props = { - { drawable = 27, prop_id = 0, texture = 0 }, - { drawable = 0, prop_id = 1, texture = 0 }, - { drawable = 0, prop_id = 2, texture = 0 }, - { drawable = 0, prop_id = 3, texture = 0 }, - { drawable = 0, prop_id = 4, texture = 0 }, - { drawable = 0, prop_id = 5, texture = 0 }, - { drawable = 0, prop_id = 6, texture = 0 }, - { drawable = 0, prop_id = 7, texture = 0 }, - { drawable = 0, prop_id = 8, texture = 0 }, - { drawable = 0, prop_id = 9, texture = 0 }, - { drawable = 0, prop_id = 10, texture = 0 }, - { drawable = 0, prop_id = 11, texture = 0 }, - { drawable = 0, prop_id = 12, texture = 0 }, - { drawable = 0, prop_id = 13, texture = 0 } - } - } - }) -end, false) diff --git a/examples/zones.lua b/examples/zones.lua deleted file mode 100644 index d3f676a..0000000 --- a/examples/zones.lua +++ /dev/null @@ -1,53 +0,0 @@ -Bridge = Bridge or exports['community_bridge']:Bridge() - -RegisterCommand('testboxzone', function(source, args, rawCommand) - local playerPos = GetEntityCoords(PlayerPedId()) - Bridge.Zones.Create("box", { - coords = vector3(playerPos.x, playerPos.y, playerPos.z), - size = vector3(2, 2, 6), - heading = 90, - debug = true, - onEnter = function(data) - print("Entered Zone: " .. data.id) - end, - onExit = function(data) - print("Exited Zone:") - end - }) -end, false) - -RegisterCommand('testpolyzone', function(source, args, rawCommand) - local playerPos = GetEntityCoords(PlayerPedId()) - Bridge.Zones.Create("poly", { - points = { - vector3(playerPos.x - 1, playerPos.y - 1, playerPos.z), - vector3(playerPos.x + 1, playerPos.y - 1, playerPos.z), - vector3(playerPos.x + 1, playerPos.y + 1, playerPos.z), - vector3(playerPos.x - 1, playerPos.y + 1, playerPos.z) - }, - size = vector3(1, 1, 1), - heading = 90, - debug = true, - onEnter = function(data) - print("Entered Zone: " .. data.id) - end, - onExit = function(data) - print("Exited Zone:") - end - }) -end, false) - -RegisterCommand('testspherezone', function(source, args, rawCommand) - local playerPos = GetEntityCoords(PlayerPedId()) - Bridge.Zones.Create("sphere", { - coords = vector3(playerPos.x, playerPos.y, playerPos.z), - radius = 2.0, - debug = true, - onEnter = function(data) - print("Entered Zone: " .. data.id) - end, - onExit = function(data) - print("Exited Zone:") - end - }) -end, false) diff --git a/fxmanifest.lua b/fxmanifest.lua index 7912ab0..3780ee8 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -5,7 +5,7 @@ use_experimental_fxv2_oal 'yes' author 'The Order of the Sacred Framework' name 'community_bridge' description 'A Universal Bridge for Our Community, created by a group of contributors with a shared vision to enhance both user and developer experiences. This bridge connects various frameworks, inventories, target systems, notification systems, and more, fostering compatibility and seamless integration.' -version '0.12.1' +version '0.13.0' shared_scripts { '@ox_lib/init.lua', @@ -62,7 +62,6 @@ client_scripts { 'modules/bossmenu/**/client.lua', 'modules/zones/**/client.lua', 'init.lua', - -- 'unit_tests/*.lua', } ui_page 'web/dist/index.html' diff --git a/lib/entities/client/client_entity.lua b/lib/entities/client/client_entity.lua index 6f16bf4..2f36f9b 100644 --- a/lib/entities/client/client_entity.lua +++ b/lib/entities/client/client_entity.lua @@ -80,9 +80,9 @@ local function UpdateEntity(_entityData) entityData.oldCoords = entityData.oldCoords and vector3(entityData.oldCoords.x, entityData.oldCoords.y, entityData.oldCoords.z) or coords local dist = #(coords - entityData.oldCoords) if entityData.oldCoords and dist > 0.5 then - if entityData.spawned then - SetEntityCoords(entityData.spawned, coords.x, coords.y, coords.z, false, false, false, true) - end + -- if entityData.spawned then + -- SetEntityCoords(entityData.spawned, coords.x, coords.y, coords.z, false, false, false, false) + -- end -- ClientEntity.UpdateCoords(entityData.id, entityData.coords) if entityData.OnMove then pcall(function (...) @@ -167,7 +167,20 @@ end function ClientEntity.Set(id, key, value) local entityData = ClientEntity.Get(id) if not entityData then return print(string.format("[ClientEntity] SetKey: Entity %s does not exist", id)) end - entityData[key] = value + local oldData = entityData[key] + if oldData == value then return end + if entityData.OnSet then + pcall(function (...) + return entityData.OnSet(entityData, key, value, oldData) + end) + end + if value then + entityData[key] = value + Behaviors.Trigger("OnSet", entityData, key, value, oldData) + return + end + Behaviors.Trigger("OnSet", entityData, key, value, oldData) + entityData[key] = nil end function ClientEntity.Get(id) diff --git a/lib/entities/shared/behaviors.lua b/lib/entities/shared/behaviors.lua index d85b4b1..460bb56 100644 --- a/lib/entities/shared/behaviors.lua +++ b/lib/entities/shared/behaviors.lua @@ -51,7 +51,7 @@ function Behaviors.Trigger(actionName, clientEntityData, ...) for property, behavior in pairs(Behaviors.All[invoking] or {}) do local hasBehaviorArgs = Behaviors.Has(property, clientEntityData) -- this is everything that's contained inside the object's individual property if hasBehaviorArgs and behavior[actionName] then - local success, result = pcall(behavior[actionName], clientEntityData, hasBehaviorArgs, ...) + local success, result = pcall(behavior[actionName], clientEntityData, ...) if not success then print(string.format("[ClientEntity] Behavior %s failed: %s", property, result)) end @@ -60,7 +60,7 @@ function Behaviors.Trigger(actionName, clientEntityData, ...) for property, behavior in pairs(Behaviors.All['community_bridge'] or {}) do local hasBehaviorArgs = Behaviors.Has(property, clientEntityData) -- this is everything that's contained inside the object's individual property if hasBehaviorArgs and behavior[actionName] and not Behaviors.All[invoking]?[actionName] then - local success, result = pcall(behavior[actionName], clientEntityData, hasBehaviorArgs, ...) + local success, result = pcall(behavior[actionName], clientEntityData, ...) if not success then print(string.format("[ClientEntity] Behavior %s failed: %s", property, result)) end diff --git a/lib/entities/shared/behaviors/particles.lua b/lib/entities/shared/behaviors/particles.lua index 1160360..3e02b1e 100644 --- a/lib/entities/shared/behaviors/particles.lua +++ b/lib/entities/shared/behaviors/particles.lua @@ -11,7 +11,6 @@ local ParticlesBehaviors = { color = vector3(255, 255, 255), loopLength = 5000, } - } function ParticlesBehaviors.Start(entityData) @@ -76,5 +75,20 @@ function ParticlesBehaviors.OnMove(entityData) end end +function ParticlesBehaviors.OnSet(entityData, key, value, oldValue) + if key ~= "particles" then return end + if oldValue then + ParticlesBehaviors.OnRemove(entityData) + end + if value then + if value.dict then -- single particle + entityData.particles = {value} + else + entityData.particles = value + end + ParticlesBehaviors.Start(entityData) + end +end + Bridge.Entity.RegisterBehavior("particles", ParticlesBehaviors) return ParticlesBehaviors \ No newline at end of file diff --git a/lib/init.lua b/lib/init.lua index 6e84715..e728054 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -11,9 +11,6 @@ function Require(modulePath, resourceName) local id = resourceName .. ":" .. modulePath if loadedModules[id] then - if BridgeSharedConfig.DebugLevel ~= 0 then - print("^2 Returning cached module [" .. id .. "] ^0") - end return loadedModules[id] end @@ -45,8 +42,6 @@ cLib = { Prints = Prints or Require("lib/utility/shared/prints.lua"), Math = Math or Require("lib/utility/shared/math.lua"), LA = LA or Require("lib/utility/shared/la.lua") - -- Zones = Poly or Require("lib/zones/shared/zones.lua"), - -- Action = Action or Require("lib/entities/shared/actions.lua"), } exports('cLib', cLib) diff --git a/lib/logs/server/logs.lua b/lib/logs/server/logs.lua index 2d1a086..9d66c94 100644 --- a/lib/logs/server/logs.lua +++ b/lib/logs/server/logs.lua @@ -1,7 +1,6 @@ Logs = Logs or {} local BridgeServerConfig = BridgeServerConfig or Require('settings/serverConfig.lua') - local pendingLogs = {} local sendTimer = nil @@ -52,10 +51,10 @@ local function queueLogForDiscord(message) end local logHandlers = { - fivemerr = function(logData) + fivemerr = function(message) local fivemerrData = { level = 'info', - message = tostring(logData), + message = tostring(message), resource = GetInvokingResource() or GetCurrentResourceName(), } @@ -69,6 +68,11 @@ local logHandlers = { }) end, + fivemanage = function(message) + if GetResourceState("fmsdk") == "missing" then return print('^1Error:^0 fivemanage log system selected but fmsdk resource is missing.') end + exports.fmsdk:LogMessage('info', message) + end, + qb = function(message) TriggerEvent('qb-log:server:CreateLog', GetCurrentResourceName(), GetInvokingResource(), 'green', message, false) end, @@ -94,9 +98,10 @@ Logs.Notify = function(src, url, image, message) Logs.CreateLog(message) end -Logs.CreateLog = function(logData) +Logs.CreateLog = function(message) local handler = logHandlers[BridgeServerConfig.LogSystem] - if handler then handler(logData) end + if not handler then return end + handler(message) end exports('Logs', Logs) diff --git a/lib/particles/client/particles.lua b/lib/particles/client/particles.lua index a5be4dc..230415a 100644 --- a/lib/particles/client/particles.lua +++ b/lib/particles/client/particles.lua @@ -1,9 +1,8 @@ Particles = {} Particle = {} + ---@diagnostic disable: duplicate-set-field Ids = Ids or Require("lib/utility/shared/ids.lua") -local point = Require("lib/points/client/points.lua") - ---Loads a ptfx asset into memory. ---@param dict string ---@return boolean @@ -26,7 +25,7 @@ end --- @param scale number --- @param color vector3 --- @param looped boolean ---- @param loopLength number|nil +--- @param removeAfter number|nil --- @return number|nil ptfxHandle -- The handle of the particle effect, or nil if it failed to create. function Particle.Play(dict, ptfx, pos, rot, scale, color, looped, removeAfter) LoadPtfxAsset(dict) @@ -93,8 +92,6 @@ function Particle.Stop(particle) Particles[tostring(particle)] = nil end - - RegisterNetEvent("community_bridge:Client:Particle", function(data) if not data then return end Particle.Create(data) @@ -110,12 +107,12 @@ end) RegisterNetEvent("community_bridge:Client:ParticleRemove", function(id) local particle = Particles[id] if not particle then return end - Particle.Remove(Drawing[id]) + Particle.Stop(id) end) RegisterNetEvent("community_bridge:Client:ParticleRemoveBulk", function(ids) for _, id in pairs(ids) do - Particle.Remove(id) + Particle.Stop(id) end end) diff --git a/lib/placers/client/object_Placer.lua b/lib/placers/client/object_Placer.lua index 1bf3984..2dfb395 100644 --- a/lib/placers/client/object_Placer.lua +++ b/lib/placers/client/object_Placer.lua @@ -1,5 +1,6 @@ Placeable = Placeable or {} Utility = Utility or Require("lib/utility/client/utility.lua") +if not lib then Require('init.lua', 'ox_lib') end local activePlacementProp = nil lib.locale() @@ -31,7 +32,7 @@ Placeable.PlaceObject = function(object, distance, snapToGround, allowedMats, of distance = tonumber(distance or 10.0 ) if activePlacementProp then return end - if not object then Prints.Error('placeable_object.no_prop_defined') end + if not object then print('^6 placeable_object.no_prop_defined ^0') end local propObject = type(object) == 'string' and joaat(object) or object local heading = 0.0 diff --git a/lib/placers/client/placeable_object.lua b/lib/placers/client/placeable_object.lua index 46064d1..4f2f658 100644 --- a/lib/placers/client/placeable_object.lua +++ b/lib/placers/client/placeable_object.lua @@ -12,7 +12,7 @@ RegisterKeyMapping('+rotate_left', locale('placeable_object.rotate_left'), 'keyb RegisterKeyMapping('+rotate_right', locale('placeable_object.rotate_right'), 'keyboard', 'RIGHT') RegisterKeyMapping('+scroll_up', locale('placeable_object.object_scroll_up'), 'mouse_wheel', 'IOM_WHEEL_UP') RegisterKeyMapping('+scroll_down', locale('placeable_object.object_scroll_down'), 'mouse_wheel', 'IOM_WHEEL_DOWN') -RegisterKeyMapping('+depth_modifier', locale('placeable_object.depth_modifier'), 'keyboard', 'LCONTROL') +RegisterKeyMapping('+depth_modifier', locale('placeable_object.depth_modifier'), 'keyboard', 'LCONTROL') local state = { isPlacing = false, @@ -50,7 +50,7 @@ local placementText = { string.format(locale('placeable_object.rotate_clockwise'), Utility.GetCommandKey('+scroll_up')), string.format(locale('placeable_object.rotate_counter_clockwise'), Utility.GetCommandKey('+scroll_down')), string.format(locale('placeable_object.depth_modifier'), Utility.GetCommandKey('+depth_modifier')) - + } -- Command handlers for key mappings @@ -134,63 +134,6 @@ local function getMouseWorldPos(depth) return playerPos + normal * depth end --- local function isInBoundary(pos, boundary) --- if not boundary then return true end - --- local x, y, z = table.unpack(pos) - --- -- Handle legacy min/max boundary format for backwards compatibility --- if boundary.min and boundary.max then --- local minX, minY, minZ = table.unpack(boundary.min) --- local maxX, maxY, maxZ = table.unpack(boundary.max) --- return x >= minX and x <= maxX and y >= minY and y <= maxY and z >= minZ and z <= maxZ --- end - --- -- Handle list of points (polygon boundary) --- if boundary.points and #boundary.points > 0 then --- local points = boundary.points --- local minZ = boundary.minZ or -math.huge --- local maxZ = boundary.maxZ or math.huge - --- -- Check Z bounds first --- if z < minZ or z > maxZ then --- return false --- end - --- -- Point-in-polygon test using ray casting algorithm (improved version) --- local inside = false --- local n = #points - --- for i = 1, n do --- local j = i == n and 1 or i + 1 -- Next point (wrap around) - --- local xi, yi = points[i].x or points[i][1], points[i].y or points[i][2] --- local xj, yj = points[j].x or points[j][1], points[j].y or points[j][2] - --- -- Ensure xi, yi, xj, yj are numbers --- if not (xi and yi and xj and yj) then --- goto continue --- end - --- -- Ray casting test --- if ((yi > y) ~= (yj > y)) then --- -- Calculate intersection point --- local intersect = (xj - xi) * (y - yi) / (yj - yi) + xi --- if x < intersect then --- inside = not inside --- end --- end - --- ::continue:: --- end - --- return inside --- end - --- -- Fallback to true if boundary format is not recognized --- return true --- end - local function checkMaterialAndBoundary() if not state.currentEntity then return true end @@ -260,41 +203,6 @@ local function checkMaterialAndBoundaryDetailed() return inBounds, inBounds, customCheckPassed end --- local function setupInstructionalButtons() --- local buttons = {} - --- -- Common buttons --- table.insert(buttons, {type = "SET_DATA_SLOT", name = state.settings.config?.place_object?.name or 'Place Object:', keyIndex = state.settings.config?.place_object?.key or {223}, int = 5}) --- table.insert(buttons, {type = "SET_DATA_SLOT", name = state.settings.config?.cancel_placement?.name or 'Cancel:', keyIndex = state.settings.config?.cancel_placement?.key or {25}, int = 4}) - --- if state.mode == 'normal' then --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Rotate:', keyIndex = {241, 242}, int = 3}) --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Depth:', keyIndex = {224}, int = 2}) --- if state.settings.allowVertical then --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Height:', keyIndex = {16, 17}, int = 1}) --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Toggle Ground Snap:', keyIndex = {19}, int = 0}) --- end --- if state.settings.allowMovement then --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Movement Mode:', keyIndex = {38}, int = 6}) --- end --- elseif state.mode == 'movement' then --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Move:', keyIndex = {32, 33, 34, 35}, int = 3}) --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Rotate:', keyIndex = {174, 175}, int = 2}) --- if state.settings.allowVertical then --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Up/Down:', keyIndex = {85, 48}, int = 1}) --- end --- if state.settings.allowNormal then --- table.insert(buttons, {type = "SET_DATA_SLOT", name = 'Normal Mode:', keyIndex = {38}, int = 0}) --- end --- end - --- table.insert(buttons, {type = "DRAW_INSTRUCTIONAL_BUTTONS"}) --- table.insert(buttons, {type = "SET_BACKGROUND_COLOUR"}) - --- -- return Scaleform.SetupInstructionalButtons(buttons) --- return nil -- Scaleform disabled for now --- end - local function drawBoundaryBox(boundary) if not boundary then return end @@ -567,7 +475,7 @@ local function placementLoop() -- if not state.settings.allowVertical or state.snapToGround then -- local groundZ, _z = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z + 50, false) -- if groundZ then - + -- end -- end coords = vector3(coords.x, coords.y, coords.z - 0.2) -- Adjust Z to ground level diff --git a/lib/points/client/points.lua b/lib/points/client/points.lua index 73b298c..64798e8 100644 --- a/lib/points/client/points.lua +++ b/lib/points/client/points.lua @@ -1,6 +1,5 @@ - -local GRIDE_SIZE_X = 8968.83 / 2 -local GRIDE_SIZE_Y = 126200.40 / 2 +local GRIDE_SIZE_X = 8968.83 +local GRIDE_SIZE_Y = 126200.40 local CELL_SIZE = 500 local Grid = {} @@ -8,6 +7,7 @@ Grid.Generated = false local Grids = {} Point = {} Point.All = {} +Point.LastInside = nil function Grid.Generate() if Grid.Generated then return end @@ -40,31 +40,27 @@ Points.Started = false function Point.StartLoop() if Points.Started then return end Points.Started = true - CreateThread(function() while Points.Started do local playerPed = PlayerPedId() if playerPed ~= -1 then local coords = GetEntityCoords(playerPed) local cell = Grid.GetCellByCoords(coords) - for _, point in pairs(cell or {}) do - if point.isEntity then - local entity = point.target - if DoesEntityExist(entity) then - local entityCoords = GetEntityCoords(entity) - local distance = #(coords - entityCoords) - if distance < point.distance then - if not point.inside then - point.inside = true - point.args = point?.onEnter(point, point.args) or point.args - end - elseif point.inside then - point.inside = false - point.args = point?.onExit(point, point.args) or point.args - end + if Point.LastInside ~= cell then + for _, point in pairs(Point.LastInside or {}) do + if point.inside then + point.inside = false + point.args = point?.onExit(point, point.args) or point.args end - else - local distance = #(vector3(coords.x, coords.y, coords.z) - vector3(point.coords.x, point.coords.y, point.coords.z)) + end + Point.LastInside = cell + end + for _, point in pairs(cell or {}) do + local entity = point.target + local targetCoords = point.isEntity and DoesEntityExist(entity) and GetEntityCoords(entity) or point.coords + if not point.disable and targetCoords then + targetCoords = vector3(targetCoords.x, targetCoords.y, targetCoords.z) + local distance = #(coords - targetCoords) if distance < point.distance then if not point.inside then point.inside = true diff --git a/lib/scaleform/client/scaleform.lua b/lib/scaleform/client/scaleform.lua index f59e659..371c6b2 100644 --- a/lib/scaleform/client/scaleform.lua +++ b/lib/scaleform/client/scaleform.lua @@ -22,8 +22,7 @@ local function setupButton(scaleform, button) N_0xe83a3e3557a56640(GetControlInstructionalButton(CONTROL_TYPE, keyCode, true)) end else - ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(CONTROL_TYPE, button.keyIndex[1], - true)) + ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(CONTROL_TYPE, button.keyIndex[1], true)) end end diff --git a/lib/utility/client/utility.lua b/lib/utility/client/utility.lua index f2e99f6..d8432de 100644 --- a/lib/utility/client/utility.lua +++ b/lib/utility/client/utility.lua @@ -1,6 +1,7 @@ Utility = Utility or {} local blipIDs = {} local spawnedPeds = {} +local spawnedProps = {} Locales = Locales or Require('modules/locales/shared.lua') Point = Point or Require('lib/points/client/points.lua') @@ -39,10 +40,11 @@ end ---@return number|nil function Utility.CreateProp(model, coords, heading, networked) local loaded, hash = ensureModelLoaded(model) - if not loaded then return nil, Prints and Prints.Error and Prints.Error("Model Has Not Loaded") end + if not loaded then return nil, print("^6 Model was unable to load "..tostring(model).." ^0") end local propEntity = CreateObject(hash, coords.x, coords.y, coords.z, networked, false, false) SetEntityHeading(propEntity, heading) SetModelAsNoLongerNeeded(hash) + spawnedProps[tostring(propEntity)] = true return propEntity end @@ -62,7 +64,7 @@ end ---@return number|nil, table function Utility.CreateVehicle(model, coords, heading, networked) local loaded, hash = ensureModelLoaded(model) - if not loaded then return nil, {}, Prints and Prints.Error and Prints.Error("Model Has Not Loaded") end + if not loaded then return nil, {}, print("^6 Model was unable to load "..tostring(model).." ^0") end local vehicle = CreateVehicle(hash, coords.x, coords.y, coords.z, heading, networked, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) @@ -80,7 +82,7 @@ end ---@return number|nil function Utility.CreatePed(model, coords, heading, networked, settings) local loaded, hash = ensureModelLoaded(model) - if not loaded then return nil, Prints and Prints.Error and Prints.Error("Model Has Not Loaded") end + if not loaded then return nil, print("^6 Model was unable to load "..tostring(model).." ^0") end local spawnedEntity = CreatePed(0, hash, coords.x, coords.y, coords.z, heading, networked, false) SetModelAsNoLongerNeeded(hash) spawnedPeds[tostring(spawnedEntity)] = true @@ -124,8 +126,8 @@ function Utility.CreateBlip(coords, sprite, color, scale, label, shortRange, dis SetBlipScale(blip, scale or 0.8) SetBlipDisplay(blip, displayType or 2) SetBlipAsShortRange(blip, shortRange) - AddTextEntry(label, label) - BeginTextCommandSetBlipName(label) + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(label) EndTextCommandSetBlipName(blip) blipIDs[tostring(blip)] = blip return blip @@ -172,7 +174,7 @@ end ---@param blip number ---@return boolean function Utility.RemoveBlip(blip) - if not blipIDs[tostring(blip)] then return false, print("NO BLIP BY ID") end + if not blipIDs[tostring(blip)] then return false, print("^6 No blip to remove with matching ID ^0") end RemoveBlip(blipIDs[tostring(blip)]) blipIDs[tostring(blip)] = nil return true @@ -211,6 +213,18 @@ function Utility.RemovePed(entity) return true end +---Remove a ped if it exists +---@param entity number +---@return boolean +function Utility.RemoveProp(entity) + if not spawnedProps[tostring(entity)] then return false end + spawnedProps[tostring(entity)] = nil + if not DoesEntityExist(entity) then return false end + SetEntityAsMissionEntity(entity, true, true) + DeleteEntity(entity) + return true +end + ---Show a native input menu and return the result ---@param text string ---@param length number @@ -290,9 +304,9 @@ local doingstuff = false ---@param text string The text to show ---@param coords table The coords to show the message at ---@return nil -function Utility.FloatingHelpText(text, coords) +function Utility.FloatingHelpText(text, coords) AddTextEntry("community_bridge_"..text, text) - SetFloatingHelpTextWorldPosition(1, coords.x, coords.y, coords.z) + SetFloatingHelpTextWorldPosition(1, coords.x, coords.y, coords.z) SetFloatingHelpTextStyle(1, 1, 2, -1, 3, 0) BeginTextCommandDisplayHelp("community_bridge_"..text) EndTextCommandDisplayHelp(2, false, false, 100) @@ -313,7 +327,7 @@ function Utility.Draw3DHelpText(coords, text, scale) end local widthFactor = maxLineLen * 0.012 * scale local height = 0.06 * scale * lineCount - + -- Set text properties SetTextScale(scale or 0.35, scale or 0.35) SetTextFont(4) @@ -323,7 +337,7 @@ function Utility.Draw3DHelpText(coords, text, scale) SetTextCentre(true) AddTextComponentString(text) DrawText(x, y) - + -- Draw background rectangle DrawRect(x, y + height / 2, widthFactor + 0.015 + 0.006, height + 0.015 + 0.006, 10, 25, 47, 200) DrawRect(x, y + height / 2, widthFactor + 0.015, height + 0.015, 17, 45, 78, 50) @@ -613,6 +627,11 @@ AddEventHandler('onResourceStop', function(resource) DeleteEntity(tonumber(ped)) end end + for _, prop in pairs(spawnedProps) do + if prop and DoesEntityExist(tonumber(prop)) then + DeleteEntity(tonumber(prop)) + end + end end) exports('Utility', Utility) diff --git a/lib/utility/shared/ids.lua b/lib/utility/shared/ids.lua index e7cdba8..06ae5e6 100644 --- a/lib/utility/shared/ids.lua +++ b/lib/utility/shared/ids.lua @@ -17,7 +17,7 @@ Ids.CreateUniqueId = function(tbl, len, pattern) -- both optional local charIndex = math.random(1, #pattern) char = pattern:sub(charIndex, charIndex) else - char = math.random(1, 2) == 1 and string.char(math.random(65, 90)) or math.random(0, 9) -- CAP letter and number + char = math.random(1, 2) == 1 and string.char(math.random(65, 90)) or string.format("%d", math.random(10) - 1) -- CAP letter and number end id = id .. char end diff --git a/lib/utility/shared/prints.lua b/lib/utility/shared/prints.lua index 6b73522..5c44b64 100644 --- a/lib/utility/shared/prints.lua +++ b/lib/utility/shared/prints.lua @@ -1,34 +1,65 @@ Prints = Prints or {} -local function printMessage(level, color, message) - if type(message) == 'table' then - message = json.encode(message) + +local function handle(result, value) + if type(value) == 'function' then + return tostring(value) end - print(color .. '[' .. level .. ']:', message) + return result end - ----This will print a colored message to the console with the designated prefix. ----@param message string -Prints.Info = function(message) - printMessage('INFO', '^5', message) +local function format(color, ...) + local data = {...} + for i = 1, #data do + if data[i] == nil then + data[i] = 'nil' + end + end + local newForm = {} + local jsonDecode = {sort_keys = true, indent = true, exception = handle} + for k, v in pairs(data) do + local formatted + if type(v) == 'table' then + formatted = json.encode(v, jsonDecode) + elseif type(v) == 'number' then + formatted = tostring(v) + elseif type(v) == 'boolean' then + formatted = tostring(v) + elseif type(v) == 'nil' then + formatted = 'nil Value' + elseif type(v) == 'string' then + formatted = v + elseif type(v) == 'function' then + formatted = tostring(v) + else + formatted = tostring(v) + end + table.insert(newForm, color .. formatted) + end + return table.concat(newForm, color .. ' \n ') end ---This will print a colored message to the console with the designated prefix. ---@param message string -Prints.Warn = function(message) - printMessage('WARN', '^3', message) +Prints.Info = function(...) + print('^5 [INFO] '.. format('^5 ', ...)) end ---This will print a colored message to the console with the designated prefix. ---@param message string -Prints.Error = function(message) - printMessage('ERROR', '^1', message) +Prints.Warn = function(...) + print('^3 [WARN] '.. format('^3', ...)) end ---This will print a colored message to the console with the designated prefix. ---@param message string -Prints.Debug = function(message) - printMessage('DEBUG', '^2', message) +Prints.Error = function(...) + print('^1 [ERROR] '.. format('^1', ...)) end -return Prints \ No newline at end of file +---This will print a colored message to the console with the designated prefix. +---@param message string +Prints.Debug = function(...) + print('^2 [DEBUG] '.. format('^2', ...)) +end + +return Prints diff --git a/locales/af.json b/locales/af.json index 42a60a8..a383475 100644 --- a/locales/af.json +++ b/locales/af.json @@ -4,6 +4,7 @@ "Input": "Hoeveelheid Invoer", "PurchaseAmount": "Aankoop Hoeveelheid", "PurchasedItem": "Jy het gekoop ", + "PurchaseFailed": "Aankoop het misluk, inventaris vol", "CurrencySymbol": "$ %s", "Confirm": "Bevestig Aankoop", "AreYouSure": "Is jy seker jy wil 'n %s koop", @@ -14,12 +15,14 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Winkel Naam" }, - "UNITTEST": { - "UNITTESTA": "Ek is 'n %s %s", - "locale-unit-test": "Dit is 'n toets string" + "Notifications": { + "PlaceholderTitle": "Kennisgewing" }, "clipboard": { - "copy": "Gekopieer na klipbord" + "copy": "Gekopieer na knipbord" + }, + "input": { + "submit_text": "Indien" }, "placeable_object": { "no_prop_defined": "Jy het nie enige voorwerp gedefinieer om te plaas nie", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Kanselleer \n", "object_scroll_up": "[%s] Draai regs \n", "object_scroll_down": "[%s] Draai links \n", + "rotate_left": "Draai links", + "rotate_right": "Draai regs", + "rotate_clockwise": "[%s] Draai Kloksgewys \n", + "rotate_counter_clockwise": "[%s] Draai Antikloksgewys \n", "depth_modifier": "[%s] Diepte Beheer Wysiging \n" + }, + "target": { + "interact": "[E] Interaksie", + "title": "Opsies", + "description": "Geen Beskrywing" } } diff --git a/locales/ar.json b/locales/ar.json index 8eb8ecd..37f74a2 100644 --- a/locales/ar.json +++ b/locales/ar.json @@ -4,6 +4,7 @@ "Input": "إدخال الكمية", "PurchaseAmount": "كمية الشراء", "PurchasedItem": "لقد قمت بشراء ", + "PurchaseFailed": "فشل الشراء، المخزون ممتلئ", "CurrencySymbol": "$ %s", "Confirm": "تأكيد الشراء", "AreYouSure": "هل أنت متأكد أنك تريد شراء %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "اسم المتجر" }, - "UNITTEST": { - "UNITTESTA": "أنا %s %s", - "locale-unit-test": "هذا نص تجريبي" + "Notifications": { + "PlaceholderTitle": "إشعار" }, "clipboard": { "copy": "تم النسخ إلى الحافظة" }, + "input": { + "submit_text": "إرسال" + }, "placeable_object": { "no_prop_defined": "لم تحدد أي كائن للوضع", "cant_place_here": "لا يمكنك وضع هذا الكائن هنا", @@ -32,6 +35,15 @@ "object_cancel": "[%s] إلغاء \n", "object_scroll_up": "[%s] استدارة يمين \n", "object_scroll_down": "[%s] استدارة يسار \n", - "depth_modifier": "[%s] تعديل التحكم بالعمق \n" + "rotate_left": "استدارة يسار", + "rotate_right": "استدارة يمين", + "rotate_clockwise": "[%s] استدارة مع عقارب الساعة \n", + "rotate_counter_clockwise": "[%s] استدارة عكس عقارب الساعة \n", + "depth_modifier": "[%s] معدل التحكم في العمق \n" + }, + "target": { + "interact": "[E] تفاعل", + "title": "خيارات", + "description": "لا يوجد وصف" } } diff --git a/locales/cs.json b/locales/cs.json index ac60736..0bd49f9 100644 --- a/locales/cs.json +++ b/locales/cs.json @@ -4,6 +4,7 @@ "Input": "Zadání množství", "PurchaseAmount": "Množství nákupu", "PurchasedItem": "Zakoupili jste ", + "PurchaseFailed": "Nákup se nezdařil, inventář je plný", "CurrencySymbol": "$ %s", "Confirm": "Potvrdit nákup", "AreYouSure": "Jste si jisti, že chcete koupit %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Název obchodu" }, - "UNITTEST": { - "UNITTESTA": "Jsem %s %s", - "locale-unit-test": "Toto je testovací řetězec" + "Notifications": { + "PlaceholderTitle": "Oznámení" }, "clipboard": { "copy": "Zkopírováno do schránky" }, + "input": { + "submit_text": "Odeslat" + }, "placeable_object": { "no_prop_defined": "Nedefinovali jste žádný objekt k umístění", "cant_place_here": "Tento objekt nemůžete umístit zde", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Zrušit \n", "object_scroll_up": "[%s] Otočit doprava \n", "object_scroll_down": "[%s] Otočit doleva \n", - "depth_modifier": "[%s] Modifikátor kontroly hloubky \n" + "rotate_left": "Otočit doleva", + "rotate_right": "Otočit doprava", + "rotate_clockwise": "[%s] Otočit ve směru hodinových ručiček \n", + "rotate_counter_clockwise": "[%s] Otočit proti směru hodinových ručiček \n", + "depth_modifier": "[%s] Modifikátor řízení hloubky \n" + }, + "target": { + "interact": "[E] Interakce", + "title": "Možnosti", + "description": "Bez popisu" } } diff --git a/locales/da.json b/locales/da.json index dcaccd1..e6bbdbe 100644 --- a/locales/da.json +++ b/locales/da.json @@ -4,6 +4,7 @@ "Input": "Mængde input", "PurchaseAmount": "Købs mængde", "PurchasedItem": "Du har købt ", + "PurchaseFailed": "Køb mislykkedes, inventar fuldt", "CurrencySymbol": "$ %s", "Confirm": "Bekræft køb", "AreYouSure": "Er du sikker på, at du vil købe en %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Butiksnavn" }, - "UNITTEST": { - "UNITTESTA": "Jeg er en %s %s", - "locale-unit-test": "Dette er en test streng" + "Notifications": { + "PlaceholderTitle": "Notifikation" }, "clipboard": { "copy": "Kopieret til udklipsholder" }, + "input": { + "submit_text": "Indsend" + }, "placeable_object": { "no_prop_defined": "Du har ikke defineret noget objekt at placere", "cant_place_here": "Du kan ikke placere dette objekt her", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Annuller \n", "object_scroll_up": "[%s] Drej til højre \n", "object_scroll_down": "[%s] Drej til venstre \n", - "depth_modifier": "[%s] Dybde kontrol modifier \n" + "rotate_left": "Drej til venstre", + "rotate_right": "Drej til højre", + "rotate_clockwise": "[%s] Rotér med uret \n", + "rotate_counter_clockwise": "[%s] Rotér mod uret \n", + "depth_modifier": "[%s] Dybdekontrol Modifier \n" + }, + "target": { + "interact": "[E] Interager", + "title": "Muligheder", + "description": "Ingen beskrivelse" } } diff --git a/locales/de.json b/locales/de.json index 9225859..8a0f52d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -4,6 +4,7 @@ "Input": "Mengen-Eingabe", "PurchaseAmount": "Kaufmenge", "PurchasedItem": "Sie haben gekauft ", + "PurchaseFailed": "Kauf fehlgeschlagen, Inventar voll", "CurrencySymbol": "$ %s", "Confirm": "Kauf bestätigen", "AreYouSure": "Sind Sie sicher, dass Sie einen %s kaufen möchten", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Geschäftsname" }, - "UNITTEST": { - "UNITTESTA": "Ich bin ein %s %s", - "locale-unit-test": "Dies ist ein Test-String" + "Notifications": { + "PlaceholderTitle": "Benachrichtigung" }, "clipboard": { "copy": "In die Zwischenablage kopiert" }, + "input": { + "submit_text": "Absenden" + }, "placeable_object": { "no_prop_defined": "Sie haben kein Objekt zum Platzieren definiert", "cant_place_here": "Sie können dieses Objekt hier nicht platzieren", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Abbrechen \n", "object_scroll_up": "[%s] Nach rechts drehen \n", "object_scroll_down": "[%s] Nach links drehen \n", + "rotate_left": "Nach links drehen", + "rotate_right": "Nach rechts drehen", + "rotate_clockwise": "[%s] Im Uhrzeigersinn drehen \n", + "rotate_counter_clockwise": "[%s] Gegen den Uhrzeigersinn drehen \n", "depth_modifier": "[%s] Tiefenkontrolle Modifikator \n" + }, + "target": { + "interact": "[E] Interagieren", + "title": "Optionen", + "description": "Keine Beschreibung" } } diff --git a/locales/el.json b/locales/el.json index d5de10b..f70f981 100644 --- a/locales/el.json +++ b/locales/el.json @@ -4,6 +4,7 @@ "Input": "Εισαγωγή ποσότητας", "PurchaseAmount": "Ποσότητα αγοράς", "PurchasedItem": "Αγοράσατε ", + "PurchaseFailed": "Η αγορά απέτυχε, το αποθέμα είναι γεμάτο", "CurrencySymbol": "$ %s", "Confirm": "Επιβεβαίωση αγοράς", "AreYouSure": "Είστε βέβαιοι ότι θέλετε να αγοράσετε ένα %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Όνομα καταστήματος" }, - "UNITTEST": { - "UNITTESTA": "Είμαι ένας %s %s", - "locale-unit-test": "Αυτό είναι ένα δοκιμαστικό κείμενο" + "Notifications": { + "PlaceholderTitle": "Ειδοποίηση" }, "clipboard": { "copy": "Αντιγράφηκε στο clipboard" }, + "input": { + "submit_text": "Υποβολή" + }, "placeable_object": { "no_prop_defined": "Δεν ορίσατε κανένα αντικείμενο για τοποθέτηση", "cant_place_here": "Δεν μπορείτε να τοποθετήσετε αυτό το αντικείμενο εδώ", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Ακύρωση \n", "object_scroll_up": "[%s] Περιστροφή δεξιά \n", "object_scroll_down": "[%s] Περιστροφή αριστερά \n", + "rotate_left": "Περιστροφή αριστερά", + "rotate_right": "Περιστροφή δεξιά", + "rotate_clockwise": "[%s] Περιστροφή δεξιόστροφα \n", + "rotate_counter_clockwise": "[%s] Περιστροφή αριστερόστροφα \n", "depth_modifier": "[%s] Τροποποιητής ελέγχου βάθους \n" + }, + "target": { + "interact": "[E] Αλληλεπίδραση", + "title": "Επιλογές", + "description": "Χωρίς περιγραφή" } } diff --git a/locales/en-pirate.json b/locales/en-pirate.json index 926caf3..ca2da43 100644 --- a/locales/en-pirate.json +++ b/locales/en-pirate.json @@ -4,6 +4,7 @@ "Input": "Amount o' Booty", "PurchaseAmount": "Plunder Quantity", "PurchasedItem": "Ye Have Plundered ", + "PurchaseFailed": "Plunder failed, yer hold be full", "CurrencySymbol": "$ %s", "Confirm": "Aye, Plunder!", "AreYouSure": "Be ye sure ye want to plunder a %s?", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Pirate's Emporium" }, - "UNITTEST": { - "UNITTESTA": "I be a %s %s", - "locale-unit-test": "This be a test string, arrr!" + "Notifications": { + "PlaceholderTitle": "Parley Notice" }, "clipboard": { "copy": "Copied to ye clipboard, matey!" }, + "input": { + "submit_text": "Send forth!" + }, "placeable_object": { "no_prop_defined": "Ye didn't pick any booty to place, ye scallywag!", "cant_place_here": "Ye can't be plunderin' here!", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Abandon Ship! \n", "object_scroll_up": "[%s] Turn starboard \n", "object_scroll_down": "[%s] Turn port \n", + "rotate_left": "Turn Port", + "rotate_right": "Turn Starboard", + "rotate_clockwise": "[%s] Spin Clockwise, arrr! \n", + "rotate_counter_clockwise": "[%s] Spin Counter-Clockwise, matey! \n", "depth_modifier": "[%s] Depth Control, savvy? \n" + }, + "target": { + "interact": "[E] Parley", + "title": "Choices, matey", + "description": "No tale to tell" } } diff --git a/locales/en.json b/locales/en.json index e7d0781..bf4e35f 100644 --- a/locales/en.json +++ b/locales/en.json @@ -4,6 +4,7 @@ "Input": "Amount Input", "PurchaseAmount": "Purchase Quantity", "PurchasedItem": "You Have Purchased ", + "PurchaseFailed": "Purchase failed, inventory full", "CurrencySymbol": "$ %s", "Confirm": "Confirm Purchase", "AreYouSure": "Are you sure you want to purchase a %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Shop Name" }, - "UNITTEST": { - "UNITTESTA": "I'm a %s %s", - "locale-unit-test": "This is a test string" + "Notifications": { + "PlaceholderTitle": "Notification" }, "clipboard": { "copy": "Copied to clipboard" }, + "input": { + "submit_text": "Submit" + }, "placeable_object": { "no_prop_defined": "You didn't define any object to place", "cant_place_here": "You can't place this object here", @@ -30,8 +33,17 @@ "place_object_scroll_down": "[Scroll Down] Turn left \n", "object_place": "[%s] Place \n", "object_cancel": "[%s] Cancel \n", + "object_scroll_up": "[%s] Turn right \n", + "object_scroll_down": "[%s] Turn left \n", + "rotate_left": "Rotate Left", + "rotate_right": "Rotate Right", "rotate_clockwise": "[%s] Rotate Clockwise \n", "rotate_counter_clockwise": "[%s] Rotate Counter-Clockwise \n", "depth_modifier": "[%s] Depth Control Modifier \n" + }, + "target": { + "interact": "[E] Interact", + "title": "Options", + "description": "No Description" } } \ No newline at end of file diff --git a/locales/es.json b/locales/es.json index 56c07d7..5c039a8 100644 --- a/locales/es.json +++ b/locales/es.json @@ -4,6 +4,7 @@ "Input": "Entrada de cantidad", "PurchaseAmount": "Cantidad de compra", "PurchasedItem": "Has comprado ", + "PurchaseFailed": "Compra fallida, inventario lleno", "CurrencySymbol": "$ %s", "Confirm": "Confirmar compra", "AreYouSure": "¿Estás seguro de que quieres comprar un %s?", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Nombre de la tienda" }, - "UNITTEST": { - "UNITTESTA": "Soy un %s %s", - "locale-unit-test": "Esta es una cadena de prueba" + "Notifications": { + "PlaceholderTitle": "Notificación" }, "clipboard": { "copy": "Copiado al portapapeles" }, + "input": { + "submit_text": "Enviar" + }, "placeable_object": { "no_prop_defined": "No has definido ningún objeto para colocar", "cant_place_here": "No puedes colocar este objeto aquí", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Cancelar \n", "object_scroll_up": "[%s] Girar a la derecha \n", "object_scroll_down": "[%s] Girar a la izquierda \n", + "rotate_left": "Girar a la izquierda", + "rotate_right": "Girar a la derecha", + "rotate_clockwise": "[%s] Rotar en sentido horario \n", + "rotate_counter_clockwise": "[%s] Rotar en sentido antihorario \n", "depth_modifier": "[%s] Modificador de control de profundidad \n" + }, + "target": { + "interact": "[E] Interactuar", + "title": "Opciones", + "description": "Sin descripción" } } diff --git a/locales/fi.json b/locales/fi.json index 9d7c9c3..7da2ca9 100644 --- a/locales/fi.json +++ b/locales/fi.json @@ -4,6 +4,7 @@ "Input": "Määrän syöttö", "PurchaseAmount": "Ostomäärä", "PurchasedItem": "Olet ostanut ", + "PurchaseFailed": "Osto epäonnistui, varasto täynnä", "CurrencySymbol": "$ %s", "Confirm": "Vahvista osto", "AreYouSure": "Oletko varma, että haluat ostaa %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Kaupan nimi" }, - "UNITTEST": { - "UNITTESTA": "Olen %s %s", - "locale-unit-test": "Tämä on testimerkki" + "Notifications": { + "PlaceholderTitle": "Ilmoitus" }, "clipboard": { "copy": "Kopioitu leikepöydälle" }, + "input": { + "submit_text": "Lähetä" + }, "placeable_object": { "no_prop_defined": "Et ole määrittänyt mitään objektia sijoitettavaksi", "cant_place_here": "Et voi sijoittaa tätä objektia tähän", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Peruuta \n", "object_scroll_up": "[%s] Käännä oikealle \n", "object_scroll_down": "[%s] Käännä vasemmalle \n", + "rotate_left": "Kierrä vasemmalle", + "rotate_right": "Kierrä oikealle", + "rotate_clockwise": "[%s] Kierrä myötäpäivään \n", + "rotate_counter_clockwise": "[%s] Kierrä vastapäivään \n", "depth_modifier": "[%s] Syvyyshallinnan muokkaaja \n" + }, + "target": { + "interact": "[E] Vuorovaikutus", + "title": "Vaihtoehdot", + "description": "Ei kuvausta" } } diff --git a/locales/fr.json b/locales/fr.json index b68c3fb..ee8f64f 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -4,6 +4,7 @@ "Input": "Saisie de quantité", "PurchaseAmount": "Quantité d'achat", "PurchasedItem": "Vous avez acheté ", + "PurchaseFailed": "Achat échoué, inventaire plein", "CurrencySymbol": "$ %s", "Confirm": "Confirmer l'achat", "AreYouSure": "Êtes-vous sûr de vouloir acheter un %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Nom du magasin" }, - "UNITTEST": { - "UNITTESTA": "Je suis un %s %s", - "locale-unit-test": "Ceci est une chaîne de test" + "Notifications": { + "PlaceholderTitle": "Notification" }, "clipboard": { "copy": "Copié dans le presse-papiers" }, + "input": { + "submit_text": "Soumettre" + }, "placeable_object": { "no_prop_defined": "Vous n'avez défini aucun objet à placer", "cant_place_here": "Vous ne pouvez pas placer cet objet ici", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Annuler \n", "object_scroll_up": "[%s] Tourner à droite \n", "object_scroll_down": "[%s] Tourner à gauche \n", + "rotate_left": "Pivoter à gauche", + "rotate_right": "Pivoter à droite", + "rotate_clockwise": "[%s] Rotation horaire \n", + "rotate_counter_clockwise": "[%s] Rotation antihoraire \n", "depth_modifier": "[%s] Modificateur de contrôle de profondeur \n" + }, + "target": { + "interact": "[E] Interagir", + "title": "Options", + "description": "Aucune description" } } diff --git a/locales/hi.json b/locales/hi.json index ea1ddd6..a4d41e5 100644 --- a/locales/hi.json +++ b/locales/hi.json @@ -4,6 +4,7 @@ "Input": "मात्रा इनपुट", "PurchaseAmount": "खरीदारी की मात्रा", "PurchasedItem": "आपने खरीदा है ", + "PurchaseFailed": "खरीदारी विफल, इन्वेंटरी भरी हुई है", "CurrencySymbol": "$ %s", "Confirm": "खरीदारी की पुष्टि करें", "AreYouSure": "क्या आप वाकई %s खरीदना चाहते हैं", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "दुकान का नाम" }, - "UNITTEST": { - "UNITTESTA": "मैं एक %s %s हूं", - "locale-unit-test": "यह एक परीक्षण स्ट्रिंग है" + "Notifications": { + "PlaceholderTitle": "सूचना" }, "clipboard": { "copy": "क्लिपबोर्ड पर कॉपी किया गया" }, + "input": { + "submit_text": "प्रस्तुत करें" + }, "placeable_object": { "no_prop_defined": "आपने रखने के लिए कोई वस्तु परिभाषित नहीं की है", "cant_place_here": "आप इस वस्तु को यहां नहीं रख सकते", @@ -32,6 +35,15 @@ "object_cancel": "[%s] रद्द करें \n", "object_scroll_up": "[%s] दाएं मुड़ें \n", "object_scroll_down": "[%s] बाएं मुड़ें \n", + "rotate_left": "बाएं मुड़ें", + "rotate_right": "दाएं मुड़ें", + "rotate_clockwise": "[%s] घड़ी की दिशा में घुमाएं \n", + "rotate_counter_clockwise": "[%s] घड़ी की विपरीत दिशा में घुमाएं \n", "depth_modifier": "[%s] गहराई नियंत्रण संशोधक \n" + }, + "target": { + "interact": "[E] बातचीत करें", + "title": "विकल्प", + "description": "कोई विवरण नहीं" } } diff --git a/locales/hr.json b/locales/hr.json index 77fc6d0..bb807c7 100644 --- a/locales/hr.json +++ b/locales/hr.json @@ -4,6 +4,7 @@ "Input": "Unos količine", "PurchaseAmount": "Količina kupnje", "PurchasedItem": "Kupili ste ", + "PurchaseFailed": "Kupnja nije uspjela, inventar pun", "CurrencySymbol": "%s kn", "Confirm": "Potvrdi kupnju", "AreYouSure": "Jeste li sigurni da želite kupiti %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Naziv trgovine" }, - "UNITTEST": { - "UNITTESTA": "Ja sam %s %s", - "locale-unit-test": "Ovo je test string" + "Notifications": { + "PlaceholderTitle": "Obavijest" }, "clipboard": { "copy": "Kopirano u međuspremnik" }, + "input": { + "submit_text": "Pošalji" + }, "placeable_object": { "no_prop_defined": "Niste definirali nijedan objekt za postavljanje", "cant_place_here": "Ne možete postaviti ovaj objekt ovdje", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Otkažи \n", "object_scroll_up": "[%s] Okreni desno \n", "object_scroll_down": "[%s] Okreni lijevo \n", + "rotate_left": "Okreni lijevo", + "rotate_right": "Okreni desno", + "rotate_clockwise": "[%s] Rotiraj u smjeru kazaljke na satu \n", + "rotate_counter_clockwise": "[%s] Rotiraj suprotno od kazaljke na satu \n", "depth_modifier": "[%s] Modifikator kontrole dubine \n" + }, + "target": { + "interact": "[E] Interakcija", + "title": "Opcije", + "description": "Nema opisa" } } diff --git a/locales/hu.json b/locales/hu.json index ced006d..3714c46 100644 --- a/locales/hu.json +++ b/locales/hu.json @@ -4,6 +4,7 @@ "Input": "Mennyiség bevitel", "PurchaseAmount": "Vásárlási mennyiség", "PurchasedItem": "Megvásároltad ", + "PurchaseFailed": "Vásárlás sikertelen, leltár tele", "CurrencySymbol": "$ %s", "Confirm": "Vásárlás megerősítése", "AreYouSure": "Biztosan meg akarsz vásárolni egy %s-t", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Bolt neve" }, - "UNITTEST": { - "UNITTESTA": "Én egy %s %s vagyok", - "locale-unit-test": "Ez egy teszt string" + "Notifications": { + "PlaceholderTitle": "Értesítés" }, "clipboard": { "copy": "Vágólapra másolva" }, + "input": { + "submit_text": "Elküld" + }, "placeable_object": { "no_prop_defined": "Nem definiáltál semmilyen objektumot elhelyezésre", "cant_place_here": "Nem helyezheted el ezt az objektumot itt", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Mégse \n", "object_scroll_up": "[%s] Jobbra fordítás \n", "object_scroll_down": "[%s] Balra fordítás \n", + "rotate_left": "Balra fordítás", + "rotate_right": "Jobbra fordítás", + "rotate_clockwise": "[%s] Forgatás óramutató járásával megegyezően \n", + "rotate_counter_clockwise": "[%s] Forgatás óramutató járásával ellentétesen \n", "depth_modifier": "[%s] Mélység vezérlő módosító \n" + }, + "target": { + "interact": "[E] Interakció", + "title": "Lehetőségek", + "description": "Nincs leírás" } } diff --git a/locales/it.json b/locales/it.json index 44968f7..44d026e 100644 --- a/locales/it.json +++ b/locales/it.json @@ -4,6 +4,7 @@ "Input": "Inserimento quantità", "PurchaseAmount": "Quantità di acquisto", "PurchasedItem": "Hai acquistato ", + "PurchaseFailed": "Acquisto fallito, inventario pieno", "CurrencySymbol": "$ %s", "Confirm": "Conferma acquisto", "AreYouSure": "Sei sicuro di voler acquistare un %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Nome negozio" }, - "UNITTEST": { - "UNITTESTA": "Sono un %s %s", - "locale-unit-test": "Questa è una stringa di test" + "Notifications": { + "PlaceholderTitle": "Notifica" }, "clipboard": { "copy": "Copiato negli appunti" }, + "input": { + "submit_text": "Invia" + }, "placeable_object": { "no_prop_defined": "Non hai definito alcun oggetto da posizionare", "cant_place_here": "Non puoi posizionare questo oggetto qui", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Annulla \n", "object_scroll_up": "[%s] Ruota a destra \n", "object_scroll_down": "[%s] Ruota a sinistra \n", - "depth_modifier": "[%s] Modificatore controllo profondità \n" + "rotate_left": "Ruota a sinistra", + "rotate_right": "Ruota a destra", + "rotate_clockwise": "[%s] Ruota in senso orario \n", + "rotate_counter_clockwise": "[%s] Ruota in senso antiorario \n", + "depth_modifier": "[%s] Modificatore di controllo della profondità \n" + }, + "target": { + "interact": "[E] Interagisci", + "title": "Opzioni", + "description": "Nessuna descrizione" } } diff --git a/locales/ja.json b/locales/ja.json index 0966d26..5d74d85 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -4,6 +4,7 @@ "Input": "数量入力", "PurchaseAmount": "購入数量", "PurchasedItem": "購入しました ", + "PurchaseFailed": "購入に失敗しました、インベントリがいっぱいです", "CurrencySymbol": "$ %s", "Confirm": "購入を確認", "AreYouSure": "%sを購入してもよろしいですか", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "店舗名" }, - "UNITTEST": { - "UNITTESTA": "私は%s %sです", - "locale-unit-test": "これはテスト文字列です" + "Notifications": { + "PlaceholderTitle": "通知" }, "clipboard": { "copy": "クリップボードにコピーされました" }, + "input": { + "submit_text": "送信" + }, "placeable_object": { "no_prop_defined": "配置するオブジェクトが定義されていません", "cant_place_here": "このオブジェクトをここに配置することはできません", @@ -32,6 +35,15 @@ "object_cancel": "[%s] キャンセル \n", "object_scroll_up": "[%s] 右回転 \n", "object_scroll_down": "[%s] 左回転 \n", - "depth_modifier": "[%s] 深度制御修飾子 \n" + "rotate_left": "左回転", + "rotate_right": "右回転", + "rotate_clockwise": "[%s] 時計回りに回転 \n", + "rotate_counter_clockwise": "[%s] 反時計回りに回転 \n", + "depth_modifier": "[%s] 深さコントロール修飾子 \n" + }, + "target": { + "interact": "[E] 対話", + "title": "オプション", + "description": "説明なし" } } diff --git a/locales/ko.json b/locales/ko.json index 5297b43..ca8240b 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -4,6 +4,7 @@ "Input": "수량 입력", "PurchaseAmount": "구매 수량", "PurchasedItem": "구매했습니다 ", + "PurchaseFailed": "구매 실패, 인벤토리가 가득 찼습니다", "CurrencySymbol": "$ %s", "Confirm": "구매 확인", "AreYouSure": "%s를 구매하시겠습니까", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "상점 이름" }, - "UNITTEST": { - "UNITTESTA": "나는 %s %s입니다", - "locale-unit-test": "이것은 테스트 문자열입니다" + "Notifications": { + "PlaceholderTitle": "알림" }, "clipboard": { "copy": "클립보드에 복사됨" }, + "input": { + "submit_text": "제출" + }, "placeable_object": { "no_prop_defined": "배치할 객체를 정의하지 않았습니다", "cant_place_here": "이 객체를 여기에 배치할 수 없습니다", @@ -32,6 +35,15 @@ "object_cancel": "[%s] 취소 \n", "object_scroll_up": "[%s] 오른쪽으로 회전 \n", "object_scroll_down": "[%s] 왼쪽으로 회전 \n", + "rotate_left": "왼쪽으로 회전", + "rotate_right": "오른쪽으로 회전", + "rotate_clockwise": "[%s] 시계 방향으로 회전 \n", + "rotate_counter_clockwise": "[%s] 시계 반대 방향으로 회전 \n", "depth_modifier": "[%s] 깊이 제어 수정자 \n" + }, + "target": { + "interact": "[E] 상호작용", + "title": "옵션", + "description": "설명 없음" } } diff --git a/locales/lt.json b/locales/lt.json index 59ac559..dbd9ee9 100644 --- a/locales/lt.json +++ b/locales/lt.json @@ -4,6 +4,7 @@ "Input": "Kiekio įvestis", "PurchaseAmount": "Pirkimo kiekis", "PurchasedItem": "Jūs nusipirkote ", + "PurchaseFailed": "Pirkimas nepavyko, inventorius pilnas", "CurrencySymbol": "%s €", "Confirm": "Patvirtinti pirkimą", "AreYouSure": "Ar tikrai norite nusipirkti %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Parduotuvės pavadinimas" }, - "UNITTEST": { - "UNITTESTA": "Aš esu %s %s", - "locale-unit-test": "Tai yra testavimo eilutė" + "Notifications": { + "PlaceholderTitle": "Pranešimas" }, "clipboard": { "copy": "Nukopijuota į iškarpinę" }, + "input": { + "submit_text": "Pateikti" + }, "placeable_object": { "no_prop_defined": "Nenurodėte jokio objekto, kurį reikia pastatyti", "cant_place_here": "Čia negalite pastatyti šio objekto", @@ -30,8 +33,17 @@ "place_object_scroll_down": "[Slinkti žemyn] Pasukti kairėn \n", "object_place": "[%s] Pastatyti \n", "object_cancel": "[%s] Atšaukti \n", + "object_scroll_up": "[%s] Pasukti dešinėn \n", + "object_scroll_down": "[%s] Pasukti kairėn \n", + "rotate_left": "Pasukti kairėn", + "rotate_right": "Pasukti dešinėn", "rotate_clockwise": "[%s] Sukti pagal laikrodžio rodyklę \n", "rotate_counter_clockwise": "[%s] Sukti prieš laikrodžio rodyklę \n", "depth_modifier": "[%s] Gylio kontrolės modifikatorius \n" + }, + "target": { + "interact": "[E] Sąveika", + "title": "Parinktys", + "description": "Nėra aprašymo" } } diff --git a/locales/nl.json b/locales/nl.json index 17917ab..fa38717 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -4,6 +4,7 @@ "Input": "Hoeveelheid invoer", "PurchaseAmount": "Aankoop hoeveelheid", "PurchasedItem": "Je hebt gekocht ", + "PurchaseFailed": "Aankoop mislukt, inventaris vol", "CurrencySymbol": "$ %s", "Confirm": "Aankoop bevestigen", "AreYouSure": "Weet je zeker dat je een %s wilt kopen", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Winkelnaam" }, - "UNITTEST": { - "UNITTESTA": "Ik ben een %s %s", - "locale-unit-test": "Dit is een test string" + "Notifications": { + "PlaceholderTitle": "Melding" }, "clipboard": { "copy": "Gekopieerd naar klembord" }, + "input": { + "submit_text": "Indienen" + }, "placeable_object": { "no_prop_defined": "Je hebt geen object gedefinieerd om te plaatsen", "cant_place_here": "Je kunt dit object hier niet plaatsen", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Annuleren \n", "object_scroll_up": "[%s] Rechtsom draaien \n", "object_scroll_down": "[%s] Linksom draaien \n", + "rotate_left": "Linksom draaien", + "rotate_right": "Rechtsom draaien", + "rotate_clockwise": "[%s] Draai met de klok mee \n", + "rotate_counter_clockwise": "[%s] Draai tegen de klok in \n", "depth_modifier": "[%s] Diepte controle modifier \n" + }, + "target": { + "interact": "[E] Interactie", + "title": "Opties", + "description": "Geen beschrijving" } } diff --git a/locales/no.json b/locales/no.json index 58fa8c7..6b7e2af 100644 --- a/locales/no.json +++ b/locales/no.json @@ -4,6 +4,7 @@ "Input": "Mengde inndata", "PurchaseAmount": "Kjøpsmengde", "PurchasedItem": "Du har kjøpt ", + "PurchaseFailed": "Kjøp mislyktes, inventar fullt", "CurrencySymbol": "$ %s", "Confirm": "Bekreft kjøp", "AreYouSure": "Er du sikker på at du vil kjøpe en %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Butikknavn" }, - "UNITTEST": { - "UNITTESTA": "Jeg er en %s %s", - "locale-unit-test": "Dette er en teststreng" + "Notifications": { + "PlaceholderTitle": "Varsling" }, "clipboard": { "copy": "Kopiert til utklippstavle" }, + "input": { + "submit_text": "Send inn" + }, "placeable_object": { "no_prop_defined": "Du har ikke definert noe objekt å plassere", "cant_place_here": "Du kan ikke plassere dette objektet her", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Avbryt \n", "object_scroll_up": "[%s] Snu til høyre \n", "object_scroll_down": "[%s] Snu til venstre \n", - "depth_modifier": "[%s] Dybdekontroll modifikator \n" + "rotate_left": "Roter til venstre", + "rotate_right": "Roter til høyre", + "rotate_clockwise": "[%s] Roter med klokken \n", + "rotate_counter_clockwise": "[%s] Roter mot klokken \n", + "depth_modifier": "[%s] Dybdekontroll Modifikator \n" + }, + "target": { + "interact": "[E] Samhandle", + "title": "Alternativer", + "description": "Ingen beskrivelse" } } diff --git a/locales/pl.json b/locales/pl.json index fa3732c..24f63eb 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -4,6 +4,7 @@ "Input": "Wprowadzanie ilości", "PurchaseAmount": "Ilość zakupu", "PurchasedItem": "Kupiłeś ", + "PurchaseFailed": "Zakup nieudany, ekwipunek pełny", "CurrencySymbol": "$ %s", "Confirm": "Potwierdź zakup", "AreYouSure": "Czy na pewno chcesz kupić %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Nazwa sklepu" }, - "UNITTEST": { - "UNITTESTA": "Jestem %s %s", - "locale-unit-test": "To jest ciąg testowy" + "Notifications": { + "PlaceholderTitle": "Powiadomienie" }, "clipboard": { "copy": "Skopiowano do schowka" }, + "input": { + "submit_text": "Wyślij" + }, "placeable_object": { "no_prop_defined": "Nie zdefiniowałeś żadnego obiektu do umieszczenia", "cant_place_here": "Nie możesz umieścić tego obiektu tutaj", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Anuluj \n", "object_scroll_up": "[%s] Obróć w prawo \n", "object_scroll_down": "[%s] Obróć w lewo \n", + "rotate_left": "Obróć w lewo", + "rotate_right": "Obróć w prawo", + "rotate_clockwise": "[%s] Obróć zgodnie z ruchem wskazówek zegara \n", + "rotate_counter_clockwise": "[%s] Obróć przeciwnie do ruchu wskazówek zegara \n", "depth_modifier": "[%s] Modyfikator kontroli głębokości \n" + }, + "target": { + "interact": "[E] Interakcja", + "title": "Opcje", + "description": "Brak opisu" } } diff --git a/locales/pt.json b/locales/pt.json index 7ca66e4..2c39cef 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -4,6 +4,7 @@ "Input": "Entrada de quantidade", "PurchaseAmount": "Quantidade de compra", "PurchasedItem": "Você comprou ", + "PurchaseFailed": "Compra falhou, inventário cheio", "CurrencySymbol": "$ %s", "Confirm": "Confirmar compra", "AreYouSure": "Você tem certeza que quer comprar um %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Nome da loja" }, - "UNITTEST": { - "UNITTESTA": "Eu sou um %s %s", - "locale-unit-test": "Esta é uma string de teste" + "Notifications": { + "PlaceholderTitle": "Notificação" }, "clipboard": { "copy": "Copiado para a área de transferência" }, + "input": { + "submit_text": "Enviar" + }, "placeable_object": { "no_prop_defined": "Você não definiu nenhum objeto para colocar", "cant_place_here": "Você não pode colocar este objeto aqui", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Cancelar \n", "object_scroll_up": "[%s] Girar para a direita \n", "object_scroll_down": "[%s] Girar para a esquerda \n", + "rotate_left": "Girar para a esquerda", + "rotate_right": "Girar para a direita", + "rotate_clockwise": "[%s] Girar no sentido horário \n", + "rotate_counter_clockwise": "[%s] Girar no sentido anti-horário \n", "depth_modifier": "[%s] Modificador de controle de profundidade \n" + }, + "target": { + "interact": "[E] Interagir", + "title": "Opções", + "description": "Sem descrição" } } diff --git a/locales/ro.json b/locales/ro.json index 32db7bd..097a78d 100644 --- a/locales/ro.json +++ b/locales/ro.json @@ -4,6 +4,7 @@ "Input": "Introducere cantitate", "PurchaseAmount": "Cantitate de cumpărare", "PurchasedItem": "Ai cumpărat ", + "PurchaseFailed": "Achiziție eșuată, inventar plin", "CurrencySymbol": "$ %s", "Confirm": "Confirmă cumpărarea", "AreYouSure": "Ești sigur că vrei să cumperi un %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Numele magazinului" }, - "UNITTEST": { - "UNITTESTA": "Sunt un %s %s", - "locale-unit-test": "Acesta este un șir de test" + "Notifications": { + "PlaceholderTitle": "Notificare" }, "clipboard": { "copy": "Copiat în clipboard" }, + "input": { + "submit_text": "Trimit" + }, "placeable_object": { "no_prop_defined": "Nu ai definit niciun obiect de plasat", "cant_place_here": "Nu poți plasa acest obiect aici", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Anulează \n", "object_scroll_up": "[%s] Rotește la dreapta \n", "object_scroll_down": "[%s] Rotește la stânga \n", - "depth_modifier": "[%s] Modificator control adâncime \n" + "rotate_left": "Rotește la stânga", + "rotate_right": "Rotește la dreapta", + "rotate_clockwise": "[%s] Rotește în sensul acelor de ceasornic \n", + "rotate_counter_clockwise": "[%s] Rotește în sens invers acelor de ceasornic \n", + "depth_modifier": "[%s] Modificator de control al adâncimii \n" + }, + "target": { + "interact": "[E] Interacționează", + "title": "Opțiuni", + "description": "Fără descriere" } } diff --git a/locales/ru.json b/locales/ru.json index e58033c..5cf6f65 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -4,6 +4,7 @@ "Input": "Ввод количества", "PurchaseAmount": "Количество покупки", "PurchasedItem": "Вы купили ", + "PurchaseFailed": "Покупка не удалась, инвентарь полон", "CurrencySymbol": "$ %s", "Confirm": "Подтвердить покупку", "AreYouSure": "Вы уверены, что хотите купить %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Название магазина" }, - "UNITTEST": { - "UNITTESTA": "Я %s %s", - "locale-unit-test": "Это тестовая строка" + "Notifications": { + "PlaceholderTitle": "Уведомление" }, "clipboard": { "copy": "Скопировано в буфер обмена" }, + "input": { + "submit_text": "Отправить" + }, "placeable_object": { "no_prop_defined": "Вы не определили никакого объекта для размещения", "cant_place_here": "Вы не можете разместить этот объект здесь", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Отменить \n", "object_scroll_up": "[%s] Повернуть вправо \n", "object_scroll_down": "[%s] Повернуть влево \n", + "rotate_left": "Повернуть влево", + "rotate_right": "Повернуть вправо", + "rotate_clockwise": "[%s] Вращать по часовой стрелке \n", + "rotate_counter_clockwise": "[%s] Вращать против часовой стрелки \n", "depth_modifier": "[%s] Модификатор контроля глубины \n" + }, + "target": { + "interact": "[E] Взаимодействовать", + "title": "Опции", + "description": "Нет описания" } } diff --git a/locales/sv.json b/locales/sv.json index 4dd55b3..843d567 100644 --- a/locales/sv.json +++ b/locales/sv.json @@ -4,6 +4,7 @@ "Input": "Mängd inmatning", "PurchaseAmount": "Inköpsmängd", "PurchasedItem": "Du har köpt ", + "PurchaseFailed": "Köp misslyckades, inventarium fullt", "CurrencySymbol": "$ %s", "Confirm": "Bekräfta köp", "AreYouSure": "Är du säker på att du vill köpa en %s", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Butiksnamn" }, - "UNITTEST": { - "UNITTESTA": "Jag är en %s %s", - "locale-unit-test": "Detta är en teststräng" + "Notifications": { + "PlaceholderTitle": "Avisering" }, "clipboard": { "copy": "Kopierat till urklipp" }, + "input": { + "submit_text": "Skicka" + }, "placeable_object": { "no_prop_defined": "Du har inte definierat något objekt att placera", "cant_place_here": "Du kan inte placera detta objekt här", @@ -32,6 +35,15 @@ "object_cancel": "[%s] Avbryt \n", "object_scroll_up": "[%s] Vrid höger \n", "object_scroll_down": "[%s] Vrid vänster \n", - "depth_modifier": "[%s] Djupkontroll modifierare \n" + "rotate_left": "Rotera vänster", + "rotate_right": "Rotera höger", + "rotate_clockwise": "[%s] Rotera medurs \n", + "rotate_counter_clockwise": "[%s] Rotera moturs \n", + "depth_modifier": "[%s] Djupkontroll Modifierare \n" + }, + "target": { + "interact": "[E] Interagera", + "title": "Alternativ", + "description": "Ingen beskrivning" } } diff --git a/locales/th.json b/locales/th.json index 7d72a4d..d58e3dc 100644 --- a/locales/th.json +++ b/locales/th.json @@ -4,6 +4,7 @@ "Input": "ป้อนจำนวน", "PurchaseAmount": "จำนวนที่ซื้อ", "PurchasedItem": "คุณได้ซื้อ ", + "PurchaseFailed": "การซื้อล้มเหลว คลังเต็ม", "CurrencySymbol": "$ %s", "Confirm": "ยืนยันการซื้อ", "AreYouSure": "คุณแน่ใจหรือว่าต้องการซื้อ %s", @@ -13,14 +14,14 @@ "CashIcon": "fa-solid fa-money-bill-wave", "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "ชื่อร้าน" - }, - "UNITTEST": { - "UNITTESTA": "ฉันเป็น %s %s", - "locale-unit-test": "นี่คือสตริงทดสอบ" - }, - "clipboard": { + }, "Notifications": { + "PlaceholderTitle": "การแจ้งเตือน" + }, "clipboard": { "copy": "คัดลอกไปยังคลิปบอร์ด" }, + "input": { + "submit_text": "ส่ง" + }, "placeable_object": { "no_prop_defined": "คุณไม่ได้กำหนดวัตถุใดๆ เพื่อวาง", "cant_place_here": "คุณไม่สามารถวางวัตถุนี้ที่นี่", @@ -32,6 +33,15 @@ "object_cancel": "[%s] ยกเลิก \n", "object_scroll_up": "[%s] หมุนไปทางขวา \n", "object_scroll_down": "[%s] หมุนไปทางซ้าย \n", - "depth_modifier": "[%s] ตัวปรับเปลี่ยนการควบคุมความลึก \n" + "rotate_left": "หมุนไปทางซ้าย", + "rotate_right": "หมุนไปทางขวา", + "rotate_clockwise": "[%s] หมุนตามเข็มนาฬิกา \n", + "rotate_counter_clockwise": "[%s] หมุนทวนเข็มนาฬิกา \n", + "depth_modifier": "[%s] ตัวปรับควบคุมความลึก \n" + }, + "target": { + "interact": "[E] โต้ตอบ", + "title": "ตัวเลือก", + "description": "ไม่มีคำอธิบาย" } } diff --git a/locales/tr.json b/locales/tr.json index 00d59a4..dc639d0 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -4,6 +4,7 @@ "Input": "Miktar girişi", "PurchaseAmount": "Satın alma miktarı", "PurchasedItem": "Satın aldınız ", + "PurchaseFailed": "Satın alma başarısız, envanter dolu", "CurrencySymbol": "$ %s", "Confirm": "Satın almayı onayla", "AreYouSure": "Bir %s satın almak istediğinizden emin misiniz", @@ -13,14 +14,14 @@ "CashIcon": "fa-solid fa-money-bill-wave", "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "Mağaza adı" - }, - "UNITTEST": { - "UNITTESTA": "Ben bir %s %s'yim", - "locale-unit-test": "Bu bir test dizesidir" - }, - "clipboard": { + }, "Notifications": { + "PlaceholderTitle": "Bildirim" + }, "clipboard": { "copy": "Panoya kopyalandı" }, + "input": { + "submit_text": "Gönder" + }, "placeable_object": { "no_prop_defined": "Yerleştirmek için herhangi bir nesne tanımlamadınız", "cant_place_here": "Bu nesneyi buraya yerleştiremezsiniz", @@ -32,6 +33,15 @@ "object_cancel": "[%s] İptal \n", "object_scroll_up": "[%s] Sağa döndür \n", "object_scroll_down": "[%s] Sola döndür \n", - "depth_modifier": "[%s] Derinlik kontrol düzenleyicisi \n" + "rotate_left": "Sola döndür", + "rotate_right": "Sağa döndür", + "rotate_clockwise": "[%s] Saat yönünde döndür \n", + "rotate_counter_clockwise": "[%s] Saat yönünün tersine döndür \n", + "depth_modifier": "[%s] Derinlik Kontrol Değiştirici \n" + }, + "target": { + "interact": "[E] Etkileşim", + "title": "Seçenekler", + "description": "Açıklama yok" } } diff --git a/locales/zh-cn.json b/locales/zh-cn.json index fd7f36c..6bd96c5 100644 --- a/locales/zh-cn.json +++ b/locales/zh-cn.json @@ -4,6 +4,7 @@ "Input": "数量输入", "PurchaseAmount": "购买数量", "PurchasedItem": "您已购买 ", + "PurchaseFailed": "购买失败,库存已满", "CurrencySymbol": "$ %s", "Confirm": "确认购买", "AreYouSure": "您确定要购买 %s 吗", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "商店名称" }, - "UNITTEST": { - "UNITTESTA": "我是一个 %s %s", - "locale-unit-test": "这是一个测试字符串" + "Notifications": { + "PlaceholderTitle": "通知" }, "clipboard": { "copy": "已复制到剪贴板" }, + "input": { + "submit_text": "提交" + }, "placeable_object": { "no_prop_defined": "您没有定义任何要放置的对象", "cant_place_here": "您不能在此处放置此对象", @@ -32,6 +35,15 @@ "object_cancel": "[%s] 取消 \n", "object_scroll_up": "[%s] 向右转 \n", "object_scroll_down": "[%s] 向左转 \n", + "rotate_left": "向左旋转", + "rotate_right": "向右旋转", + "rotate_clockwise": "[%s] 顺时针旋转 \n", + "rotate_counter_clockwise": "[%s] 逆时针旋转 \n", "depth_modifier": "[%s] 深度控制修改器 \n" + }, + "target": { + "interact": "[E] 互动", + "title": "选项", + "description": "无描述" } } diff --git a/locales/zh-hk.json b/locales/zh-hk.json index bcef63c..21873c1 100644 --- a/locales/zh-hk.json +++ b/locales/zh-hk.json @@ -4,6 +4,7 @@ "Input": "數量輸入", "PurchaseAmount": "購買數量", "PurchasedItem": "您已購買 ", + "PurchaseFailed": "購買失敗,庫存已滿", "CurrencySymbol": "$ %s", "Confirm": "確認購買", "AreYouSure": "您確定要購買 %s 嗎", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "商店名稱" }, - "UNITTEST": { - "UNITTESTA": "我是一個 %s %s", - "locale-unit-test": "這是一個測試字符串" + "Notifications": { + "PlaceholderTitle": "通知" }, "clipboard": { "copy": "已復制到剪貼板" }, + "input": { + "submit_text": "提交" + }, "placeable_object": { "no_prop_defined": "您沒有定義任何要放置的對象", "cant_place_here": "您不能在此處放置此對象", @@ -32,6 +35,15 @@ "object_cancel": "[%s] 取消 \n", "object_scroll_up": "[%s] 向右轉 \n", "object_scroll_down": "[%s] 向左轉 \n", + "rotate_left": "向左旋轉", + "rotate_right": "向右旋轉", + "rotate_clockwise": "[%s] 順時針旋轉 \n", + "rotate_counter_clockwise": "[%s] 逆時針旋轉 \n", "depth_modifier": "[%s] 深度控制修改器 \n" + }, + "target": { + "interact": "[E] 互動", + "title": "選項", + "description": "無描述" } } diff --git a/locales/zh-tw.json b/locales/zh-tw.json index 198dc18..83646c7 100644 --- a/locales/zh-tw.json +++ b/locales/zh-tw.json @@ -4,6 +4,7 @@ "Input": "數量輸入", "PurchaseAmount": "購買數量", "PurchasedItem": "您已購買 ", + "PurchaseFailed": "購買失敗,庫存已滿", "CurrencySymbol": "$ %s", "Confirm": "確認購買", "AreYouSure": "您確定要購買 %s 嗎", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "商店名稱" }, - "UNITTEST": { - "UNITTESTA": "我是一個 %s %s", - "locale-unit-test": "這是一個測試字符串" + "Notifications": { + "PlaceholderTitle": "通知" }, "clipboard": { "copy": "已複製到剪貼簿" }, + "input": { + "submit_text": "提交" + }, "placeable_object": { "no_prop_defined": "您沒有定義任何要放置的物件", "cant_place_here": "您不能在此處放置此物件", @@ -32,6 +35,15 @@ "object_cancel": "[%s] 取消 \n", "object_scroll_up": "[%s] 向右轉 \n", "object_scroll_down": "[%s] 向左轉 \n", + "rotate_left": "向左旋轉", + "rotate_right": "向右旋轉", + "rotate_clockwise": "[%s] 順時針旋轉 \n", + "rotate_counter_clockwise": "[%s] 逆時針旋轉 \n", "depth_modifier": "[%s] 深度控制修改器 \n" + }, + "target": { + "interact": "[E] 互動", + "title": "選項", + "description": "無描述" } } diff --git a/locales/zh.json b/locales/zh.json index fd7f36c..6bd96c5 100644 --- a/locales/zh.json +++ b/locales/zh.json @@ -4,6 +4,7 @@ "Input": "数量输入", "PurchaseAmount": "购买数量", "PurchasedItem": "您已购买 ", + "PurchaseFailed": "购买失败,库存已满", "CurrencySymbol": "$ %s", "Confirm": "确认购买", "AreYouSure": "您确定要购买 %s 吗", @@ -14,13 +15,15 @@ "ShopIcon": "fa-solid fa-basket-shopping", "ShopName": "商店名称" }, - "UNITTEST": { - "UNITTESTA": "我是一个 %s %s", - "locale-unit-test": "这是一个测试字符串" + "Notifications": { + "PlaceholderTitle": "通知" }, "clipboard": { "copy": "已复制到剪贴板" }, + "input": { + "submit_text": "提交" + }, "placeable_object": { "no_prop_defined": "您没有定义任何要放置的对象", "cant_place_here": "您不能在此处放置此对象", @@ -32,6 +35,15 @@ "object_cancel": "[%s] 取消 \n", "object_scroll_up": "[%s] 向右转 \n", "object_scroll_down": "[%s] 向左转 \n", + "rotate_left": "向左旋转", + "rotate_right": "向右旋转", + "rotate_clockwise": "[%s] 顺时针旋转 \n", + "rotate_counter_clockwise": "[%s] 逆时针旋转 \n", "depth_modifier": "[%s] 深度控制修改器 \n" + }, + "target": { + "interact": "[E] 互动", + "title": "选项", + "description": "无描述" } } diff --git a/modules/clothing/esx_skin/client.lua b/modules/clothing/esx_skin/client.lua index d5e4592..0ece696 100644 --- a/modules/clothing/esx_skin/client.lua +++ b/modules/clothing/esx_skin/client.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('esx_skin') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} function Clothing.OpenMenu() diff --git a/modules/clothing/esx_skin/server.lua b/modules/clothing/esx_skin/server.lua index a96ef52..cd223dd 100644 --- a/modules/clothing/esx_skin/server.lua +++ b/modules/clothing/esx_skin/server.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('esx_skin') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} Clothing.Players = {} diff --git a/modules/clothing/esx_skin/shared.lua b/modules/clothing/esx_skin/shared.lua index 53d5845..73c9054 100644 --- a/modules/clothing/esx_skin/shared.lua +++ b/modules/clothing/esx_skin/shared.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('esx_skin') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} diff --git a/modules/clothing/fivem-appearance/client.lua b/modules/clothing/fivem-appearance/client.lua index add4d6c..77d1bdf 100644 --- a/modules/clothing/fivem-appearance/client.lua +++ b/modules/clothing/fivem-appearance/client.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('fivem-appearance') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} function Clothing.OpenMenu() diff --git a/modules/clothing/fivem-appearance/server.lua b/modules/clothing/fivem-appearance/server.lua index c57ef48..a176e91 100644 --- a/modules/clothing/fivem-appearance/server.lua +++ b/modules/clothing/fivem-appearance/server.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('fivem-appearance') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} Clothing.Players = {} diff --git a/modules/clothing/illenium-appearance/client.lua b/modules/clothing/illenium-appearance/client.lua index 5c49c5d..59e515a 100644 --- a/modules/clothing/illenium-appearance/client.lua +++ b/modules/clothing/illenium-appearance/client.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('illenium-appearance') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} function Clothing.OpenMenu() diff --git a/modules/clothing/illenium-appearance/server.lua b/modules/clothing/illenium-appearance/server.lua index 492840e..def4aee 100644 --- a/modules/clothing/illenium-appearance/server.lua +++ b/modules/clothing/illenium-appearance/server.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('illenium-appearance') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} Clothing.Players = {} diff --git a/modules/clothing/qb-clothing/client.lua b/modules/clothing/qb-clothing/client.lua index 3b7cb4d..cfcbaea 100644 --- a/modules/clothing/qb-clothing/client.lua +++ b/modules/clothing/qb-clothing/client.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('qb-clothing') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} function Clothing.OpenMenu() diff --git a/modules/clothing/qb-clothing/server.lua b/modules/clothing/qb-clothing/server.lua index 05fca20..67c0672 100644 --- a/modules/clothing/qb-clothing/server.lua +++ b/modules/clothing/qb-clothing/server.lua @@ -1,6 +1,7 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('qb-clothing') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} Clothing.Players = {} diff --git a/modules/clothing/qb-clothing/shared.lua b/modules/clothing/qb-clothing/shared.lua index 394e0b3..3e338f2 100644 --- a/modules/clothing/qb-clothing/shared.lua +++ b/modules/clothing/qb-clothing/shared.lua @@ -2,6 +2,7 @@ if GetResourceState('qb-clothing') == 'missing' then return end if GetResourceState('rcore_clothing') ~= 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} diff --git a/modules/clothing/rcore_clothing/client.lua b/modules/clothing/rcore_clothing/client.lua index fee5fb9..c88a362 100644 --- a/modules/clothing/rcore_clothing/client.lua +++ b/modules/clothing/rcore_clothing/client.lua @@ -1,5 +1,6 @@ ---@diagnostic disable: duplicate-set-field if GetResourceState('rcore_clothing') == 'missing' then return end +if GetResourceState('17mov_CharacterSystem') ~= 'missing' then return end Clothing = Clothing or {} function Clothing.OpenMenu() diff --git a/modules/dialogue/_default/client/client.lua b/modules/dialogue/_default/client/client.lua index 0e6b130..52807cc 100644 --- a/modules/dialogue/_default/client/client.lua +++ b/modules/dialogue/_default/client/client.lua @@ -22,7 +22,7 @@ function Dialogue.Close(name) -- Wait brief moment to see if new dialogue opens CreateThread(function() - Wait(50) -- Small delay to allow new dialogue to open + Wait(200) -- Small delay to allow new dialogue to open if pendingCameraDestroy and not activeDialogue then -- No new dialogue opened, safe to destroy camera RenderScriptCams(false, 1, 1000, 1, 0) @@ -56,7 +56,7 @@ function Dialogue.Open( name, dialogue, characterOptions, dialogueOptions, onSel -- camera magic! if entity then Wait(500) - local endLocation = GetOffsetFromEntityInWorldCoords(entity, offset.x, offset.y + 2.0, offset.z + 0.5) + local endLocation = GetOffsetFromEntityInWorldCoords(entity, offset.x, offset.y + 2.0, offset.z) local pedHeading = GetEntityHeading(entity) -- Get position in front of ped based on their heading diff --git a/modules/dispatch/emergencydispatch/client/client.lua b/modules/dispatch/emergencydispatch/client/client.lua new file mode 100644 index 0000000..599e104 --- /dev/null +++ b/modules/dispatch/emergencydispatch/client/client.lua @@ -0,0 +1,25 @@ +---@diagnostic disable: duplicate-set-field +if GetResourceState('emergencydispatch') == 'missing' then return end +Dispatch = Dispatch or {} + +---This will send an alert to currently supported dispatch systems. +---@param data table The data to send to the dispatch system. +---@return nil +Dispatch.SendAlert = function(data) + local ped = PlayerPedId() + + local job = data.job or data.jobs[1] or 'police' + local message = data.message or "An Alert Has Been Made" + local coords = data.coords or GetEntityCoords(ped) + + -- The last boolean argument is unknown. The developer always uses true. + TriggerServerEvent('emergencydispatch:emergencycall:new', job, message, coords, true) +end + +---This will get the name of the in use resource. +---@return string +Dispatch.GetResourceName = function() + return 'emergencydispatch' +end + +return Dispatch \ No newline at end of file diff --git a/modules/dispatch/emergencydispatch/server/server.lua b/modules/dispatch/emergencydispatch/server/server.lua new file mode 100644 index 0000000..4ad62ef --- /dev/null +++ b/modules/dispatch/emergencydispatch/server/server.lua @@ -0,0 +1,18 @@ +if GetResourceState('emergencydispatch') == 'missing' then return end +Dispatch = Dispatch or {} + +RegisterNetEvent("community_bridge:server:dispatch:sendAlert", function(data) + local job = data.job or data.jobs[1] or 'police' + local message = data.message or "An Alert Has Been Made" + local coords = data.coords or vector3(0, 0, 0) + + TriggerEvent('emergencydispatch:emergencycall:new', job, message, coords, true) +end) + +---This will get the name of the in use resource. +---@return string +Dispatch.GetResourceName = function() + return 'emergencydispatch' +end + +return Dispatch \ No newline at end of file diff --git a/modules/dispatch/fd_dispatch/client/client.lua b/modules/dispatch/fd_dispatch/client/client.lua new file mode 100644 index 0000000..a725dfc --- /dev/null +++ b/modules/dispatch/fd_dispatch/client/client.lua @@ -0,0 +1,42 @@ +---@diagnostic disable: duplicate-set-field +if GetResourceState('fd_dispatch') == 'missing' then return end +if GetResourceState('lb-tablet') == 'started' then return end +Dispatch = Dispatch or {} + +Dispatch.SendAlert = function(data) + local metadata = {} + if data.vehicle then + table.insert(metadata, { + type = 'vehicle', + model = data.vehicle or locale('unknown_vehicle_model'), + plate = data.plate or nil, + color = data.colorHex or nil + }) + end + local coords = data.coords or GetEntityCoords(PlayerPedId()) + local alertData = { + title = data.message or "No message provided", + description = data.message or "", + groups = data.jobs or data.job or "police", + location = {coords = coords, street = GetStreetNameFromHashKey(GetStreetNameAtCoord(coords.x, coords.y, coords.z))}, + code = data.code or '10-80', + priority = data.priority or 2, + metadata = metadata, + blip = { + radius = data.blipData and data.blipData.radius or 0, + sprite = data.blipData and data.blipData.sprite or 161, + color = data.blipData and data.blipData.color or 84, + scale = data.blipData and data.blipData.scale or 1.0, + time = data.time and (data.time / 1000) or nil, + }, + } + exports["fd_dispatch"]:CustomAlert(alertData) +end + +---This will get the name of the in use resource. +---@return string +Dispatch.GetResourceName = function() + return 'fd_dispatch' +end + +return Dispatch \ No newline at end of file diff --git a/modules/dispatch/fd_dispatch/server/server.lua b/modules/dispatch/fd_dispatch/server/server.lua new file mode 100644 index 0000000..ef9fa8f --- /dev/null +++ b/modules/dispatch/fd_dispatch/server/server.lua @@ -0,0 +1,11 @@ +if GetResourceState('fd_dispatch') == 'missing' then return end +if GetResourceState('lb-tablet') == 'started' then return end +Dispatch = Dispatch or {} + +---This will get the name of the in use resource. +---@return string +Dispatch.GetResourceName = function() + return 'fd_dispatch' +end + +return Dispatch \ No newline at end of file diff --git a/modules/dispatch/tk_dispatch/client/client.lua b/modules/dispatch/tk_dispatch/client/client.lua index f7c0740..6c96e05 100644 --- a/modules/dispatch/tk_dispatch/client/client.lua +++ b/modules/dispatch/tk_dispatch/client/client.lua @@ -3,7 +3,7 @@ if GetResourceState('tk_dispatch') == 'missing' then return end Dispatch = Dispatch or {} Dispatch.SendAlert = function(data) - exports.tk_dispatch:addCall({ + local alertData = { title = data.message, code = data.code or '10-80', priority = 'Priority 3', @@ -17,7 +17,8 @@ Dispatch.SendAlert = function(data) scale = data.blipData.scale or 0.8, }, jobs = data.jobs or {'police'}, - }) + } + exports.tk_dispatch:addCall(alertData) end ---This will get the name of the in use resource. diff --git a/modules/dispatch/wasabi_mdt/client/client.lua b/modules/dispatch/wasabi_mdt/client/client.lua new file mode 100644 index 0000000..29aed8d --- /dev/null +++ b/modules/dispatch/wasabi_mdt/client/client.lua @@ -0,0 +1,23 @@ +---@diagnostic disable: duplicate-set-field +if GetResourceState('wasabi_mdt') == 'missing' then return end +Dispatch = Dispatch or {} + +Dispatch.SendAlert = function(data) + local fallbackCoords = GetEntityCoords(PlayerPedId()) + local alertData = { + type = data.code or '10-80', + title = data.code or '10-80', + description = data.message or "No message provided", + location = {data.coords.x, data.coords.y, data.coords.z} or {fallbackCoords.x, fallbackCoords.y, fallbackCoords.z}, + coords = {data.coords.x, data.coords.y, data.coords.z} or {fallbackCoords.x, fallbackCoords.y, fallbackCoords.z}, + } + exports.wasabi_mdt:CreateDispatch(alertData) +end + +---This will get the name of the in use resource. +---@return string +Dispatch.GetResourceName = function() + return 'wasabi_mdt' +end + +return Dispatch \ No newline at end of file diff --git a/modules/dispatch/wasabi_mdt/server/server.lua b/modules/dispatch/wasabi_mdt/server/server.lua new file mode 100644 index 0000000..d5aad7c --- /dev/null +++ b/modules/dispatch/wasabi_mdt/server/server.lua @@ -0,0 +1,10 @@ +if GetResourceState('wasabi_mdt') == 'missing' then return end +Dispatch = Dispatch or {} + +---This will get the name of the in use resource. +---@return string +Dispatch.GetResourceName = function() + return 'wasabi_mdt' +end + +return Dispatch \ No newline at end of file diff --git a/modules/framework/_default/client.lua b/modules/framework/_default/client.lua index 77042d7..d04d2b0 100644 --- a/modules/framework/_default/client.lua +++ b/modules/framework/_default/client.lua @@ -3,18 +3,22 @@ Framework = Framework or {} local currentJobCounts = GlobalState.jobcounts or {} +---@description State bag change handler to update job counts when global state changes +---@param bagName string +---@param key string +---@param value table|nil AddStateBagChangeHandler('jobcounts', 'global', function(bagName, key, value) if not value then currentJobCounts = {} return end currentJobCounts = value end) ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Framework.GetResourceName = function() return 'default' end ----This is an internal function that will be used to retrieve job counts later. +---@description This is an internal function that will be used to retrieve job counts later. ---@param jobName string ---@return number Framework.GetJobCount = function(jobName) @@ -22,7 +26,7 @@ Framework.GetJobCount = function(jobName) return currentJobCounts[jobName] end ----This will allow passing a table of job names and returning a sum of the total count. +---@description This will allow passing a table of job names and returning a sum of the total count. ---@param tbl table ---@return number Framework.GetJobCountTotal = function(tbl) diff --git a/modules/framework/_default/server.lua b/modules/framework/_default/server.lua index 6e675f2..c4c4826 100644 --- a/modules/framework/_default/server.lua +++ b/modules/framework/_default/server.lua @@ -7,13 +7,13 @@ local globalState = GlobalState globalState.jobcounts = {} ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Framework.GetResourceName = function() return 'default' end ----This is an internal function that will be used to retrieve job counts later. +---@description This is an internal function that will be used to retrieve job counts later. ---@param jobName string ---@return number Framework.GetJobCount = function(jobName) @@ -25,7 +25,7 @@ Framework.GetJobCount = function(jobName) return count end ----This will allow passing a table of job names and returning a sum of the total count. +---@description This will allow passing a table of job names and returning a sum of the total count. ---@param tbl any ---@return number Framework.GetJobCountTotal = function(tbl) @@ -36,7 +36,7 @@ Framework.GetJobCountTotal = function(tbl) return total end ----This will return a list of player sources for a given job. +---@description This will return a list of player sources for a given job. ---@param jobName string ---@return table Framework.GetPlayerSourcesByJob = function(jobName) @@ -48,7 +48,7 @@ Framework.GetPlayerSourcesByJob = function(jobName) return sources end ----This will update the cached tables for job counts. +---@description This will update the cached tables for job counts. ---This is used to track how many players are in a job. ---@param src number ---@param jobName string @@ -69,13 +69,13 @@ Framework.AddJobCount = function(src, jobName) return true end ----This will return the job name for a given source. +---@description This will return the job name for a given source. ---@param src number Framework.SearchJobCountBySource = function(src) return invertedJobsRegisteredTable[src] end ----This will remove the job count for a given source. +---@description This will remove the job count for a given source. ---@param src number ---@param jobName string | nil Framework.RemoveJobCount = function(src, jobName) @@ -101,12 +101,17 @@ Framework.RemoveJobCount = function(src, jobName) return true end +---@description Event handler for when a player's job changes, updates job counts accordingly +---@param src number +---@param newJobName string AddEventHandler('community_bridge:Server:OnPlayerJobChange', function(src, newJobName) local previousJob = invertedJobsRegisteredTable[src] if previousJob then Framework.RemoveJobCount(src, previousJob) end if newJobName then Framework.AddJobCount(src, newJobName) end end) +---@description Event handler for when a player unloads, removes them from job counts +---@param src number AddEventHandler('community_bridge:Server:OnPlayerUnload', function(src) Framework.RemoveJobCount(src) end) diff --git a/modules/framework/es_extended/client.lua b/modules/framework/es_extended/client.lua index c363a45..cf79c99 100644 --- a/modules/framework/es_extended/client.lua +++ b/modules/framework/es_extended/client.lua @@ -8,7 +8,7 @@ Framework = Framework or {} local cachedItemList = nil ---- @description This is an internal function, its here to attempt to emulate qbs shared items mainly +---@description This is an internal function, its here to attempt to emulate qbs shared items mainly. This should not be used outside of bridge. Framework.ItemList = function() if cachedItemList then return cachedItemList end local items = Callback.Trigger('community_bridge:Callback:GetFrameworkItems', false) @@ -16,100 +16,101 @@ Framework.ItemList = function() return cachedItemList end ---- @description This will get the name of the framework being used (if a supported framework). ---- @return string +---@description This will get the name of the framework being used (if a supported framework). +---@return string Framework.GetFrameworkName = function() - return 'es_extended' + print("This is depricated, please use Framework.GetResourceName() instead.") + return Framework.GetResourceName() end ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Framework.GetResourceName = function() return 'es_extended' end ---- @description This will return true if the player is loaded, false otherwise. ---- This could be useful in scripts that rely on player loaded events and offer a debug mode to hit this function ---- @return boolean +---@description This will return true if the player is loaded, false otherwise. +---This could be useful in scripts that rely on player loaded events and offer a debug mode to hit this function. +---@return boolean Framework.GetIsPlayerLoaded = function() return ESX.IsPlayerLoaded() end ---- @description This will return a table of the player data, this will be in the framework format ---- This is mainly for internal bridge use and should be avoided. +---@description This is an internal function, do not use this outside of bridge as there is no standard format between the frameworks. --- @return table Framework.GetPlayerData = function() return ESX.GetPlayerData() end ---- @description This will return a table of all the jobs in the framework. ---- @return table +---@description This will return a table of all the jobs in the framework. +---@return table Framework.GetFrameworkJobs = function() local jobs = Callback.Trigger('community_bridge:Callback:GetFrameworkJobs', false) return jobs end ---- @description This will return the players birth date ---- @return string +---@description This will get the players birth date +---@return string Framework.GetPlayerDob = function() local playerData = Framework.GetPlayerData() local dob = playerData.dateofbirth return dob end ---- @description This will return the players metadata for the specified metadata key. ---- @param metadata table | string +---@description This will return the players metadata for the specified metadata key. +---@param metadata table | string ---@return table | string | number | boolean Framework.GetPlayerMetaData = function(metadata) return Framework.GetPlayerData().metadata[metadata] end ---- @description This will send a notification to the player. ---- @param message string ---- @param type string ---- @param time number ---- @return nil +---@description This will send a notification to the player. +---@param message string +---@param type string +---@param time number +---@return nil Framework.Notify = function(message, type, time) return ESX.ShowNotification(message, type, time) end ---- @description This will display the help text message on the screen ---- @param message string ---- @param _ unknown ---- @return nil -Framework.ShowHelpText = function(message, _) +---@description Will Display the help text message on the screen +---@param message string +---@param _position unknown +---@return nil +Framework.ShowHelpText = function(message, _position) return exports.esx_textui:TextUI(message, "info") end ---- @description This will hide the help text message on the screen ---- @return nil +---@description This will hide the help text message on the screen +---@return nil Framework.HideHelpText = function() return exports.esx_textui:HideUI() end ---- @description This will get the players identifier (citizenid) etc. +---@description This will get the players identifier (citizenid) etc. ---@return string Framework.GetPlayerIdentifier = function() local playerData = Framework.GetPlayerData() return playerData.identifier end ---- @description This will get the players name (first and last). ---- @return string ---- @return string +---@description This will get the players name (first and last). +---@return string +---@return string Framework.GetPlayerName = function() local playerData = Framework.GetPlayerData() return playerData.firstName, playerData.lastName end ---- @deprecated This will return the players job name, job label, job grade label and job grade level ---- @return string returns job name ---- @return string returns job label ---- @return string returns job grade label ---- @return string returns job grade level +---@description Depricated : This will return the players job name, job label, job grade label and job grade level +---@return string +---@return string +---@return string +---@return string Framework.GetPlayerJob = function() - local playerData = Framework.GetPlayerData() - return playerData.job.name, playerData.job.label, playerData.job.grade_label, playerData.job.grade + print("This is depricated, please use Framework.GetPlayerJobData() instead.") + local jobData = Framework.GetPlayerJobData() + return jobData.jobName, jobData.jobLabel, jobData.gradeName, jobData.gradeRank end --- @description This will return the players job name, job label, job grade label job grade level, @@ -130,7 +131,7 @@ Framework.GetPlayerJobData = function() } end ---This is an internal function to get status data +---@description This is an internal function to get status data --- @param search string Framework.GetStatusData = function(search) local playerData = Framework.GetPlayerData() @@ -144,29 +145,30 @@ Framework.GetStatusData = function(search) return 0 end ----This will get the hunger of a player +---@description This will get the hunger of a player ---@return number Framework.GetHunger = function() local status = Framework.GetStatusData("hunger") return math.floor((status) + 0.5) or 0 end ----This will get the thirst of a player +---@description This will get the thirst of a player ---@return number Framework.GetThirst = function() local status = Framework.GetStatusData("thirst") return math.floor((status) + 0.5) or 0 end ---- @description This will return if the player has the specified item in their inventory ---- @param item string ---- @return boolean -Framework.HasItem = function(item) +---@description Will return boolean if the player has the item. +---@param item string +---@param requiredCount number (optional) +---@return boolean +Framework.HasItem = function(item, requiredCount) local hasItem = ESX.SearchInventory(item, true) - return hasItem > 0 and true or false + return hasItem >= (requiredCount or 1) end ---- @description This will return the item count for the specified item in the players inventory +---@description This is an internal function used as a fallback, please use the Inventory.GetItemCount instead. --- @param item string --- @return number Framework.GetItemCount = function(item) @@ -175,16 +177,38 @@ Framework.GetItemCount = function(item) return inventory[item].count or 0 end ---- @description This will return a table of the players inventory ---- @return table -Framework.GetPlayerInventory = function() - local playerData = Framework.GetPlayerData() - return playerData.inventory +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} +---@param item string +---@return table +Framework.GetItemInfo = function(item) + return {}, print("ESX has not implemented GetItemInfo for this framework. Please ensure the inventory you are using is supported and start order is correct.") end ---- @description This will return the players money by type, I recommend not using this as its the client and not secure or to be trusted ---- @param _type string ---- @return number +---@description This is an internal function used as a fallback, please use the Inventory.GetPlayerInventory instead. +--- @return table {name, label, count, slot, metadata, stack, close, weight} +Framework.GetPlayerInventory = function() + local playerData = Framework.GetPlayerData() + if not playerData then return {} end + local repack = {} + for k, v in pairs(playerData.inventory) do + repack[k] = { + name = v.name, + label = v.label, + count = v.count, + slot = 0, + metadata = {}, + stack = false, + close = v.usable or false, + weight = v.weight or 0, + } + end + return repack +end + +---@description This will return the players money by type, I recommend not useing this as its the client and not secure or to be trusted. +---Use case is for a ui or a menu I guess. +---@param _type string +---@return number Framework.GetAccountBalance = function(_type) local player = Framework.GetPlayerData() if not player then return 0 end @@ -192,52 +216,13 @@ Framework.GetAccountBalance = function(_type) if _type == 'cash' then _type = 'money' end for _, account in ipairs(accounts) do if account.name == _type then + if not account.money or account.money <= 0 then return 0 end return account.money or 0 end end return 0 end ---- @description This will return the vehicle properties for the specified vehicle ---- @param vehicle number ---- @return table -Framework.GetVehicleProperties = function(vehicle) - if not vehicle or not DoesEntityExist(vehicle) then return {} end - local vehicleProps = ESX.Game.GetVehicleProperties(vehicle) - return vehicleProps or {} -end - ---- @description This will set the vehicle properties for the specified vehicle ---- @param vehicle number ---- @param properties table ---- @return boolean -Framework.SetVehicleProperties = function(vehicle, properties) - if not vehicle or not DoesEntityExist(vehicle) then return false end - if not properties then return false end - if NetworkGetEntityIsNetworked(vehicle) then - local vehNetID = NetworkGetNetworkIdFromEntity(vehicle) - local entOwner = GetPlayerServerId(NetworkGetEntityOwner(vehNetID)) - if entOwner ~= GetPlayerServerId(PlayerId()) then - NetworkRequestControlOfEntity(vehicle) - local count = 0 - while not NetworkHasControlOfEntity(vehicle) and count < 3000 do - Wait(1) - count = count + 1 - end - end - end - -- Every framework version does this just a diffrent key I guess? - if properties.color1 and type(properties.color1) == 'table' then - properties.customPrimaryColor = {properties.color1[1], properties.color1[2], properties.color1[3]} - properties.color1 = nil - end - if properties.color2 and type(properties.color2) == 'table' then - properties.customSecondaryColor = {properties.color2[1], properties.color2[2], properties.color2[3]} - properties.color2 = nil - end - return true, ESX.Game.SetVehicleProperties(vehicle, properties) -end - --- @description This will get a players dead status --- @return boolean Framework.GetIsPlayerDead = function() @@ -245,15 +230,20 @@ Framework.GetIsPlayerDead = function() return playerData.dead end +---@description Event handler for when player is loaded in ESX framework +---@param xPlayer table RegisterNetEvent('esx:playerLoaded', function(xPlayer) Wait(1500) TriggerEvent('community_bridge:Client:OnPlayerLoaded') end) +---@description Event handler for when player logs out in ESX framework RegisterNetEvent('esx:onPlayerLogout', function() TriggerEvent('community_bridge:Client:OnPlayerUnload') end) +---@description Event handler for when player job is updated in ESX framework +---@param data table Job data containing name, label, grade_label, and grade RegisterNetEvent('esx:setJob', function(data) TriggerEvent('community_bridge:Client:OnPlayerJobUpdate', data.name, data.label, data.grade_label, data.grade) end) diff --git a/modules/framework/es_extended/server.lua b/modules/framework/es_extended/server.lua index 80243a0..077aa0f 100644 --- a/modules/framework/es_extended/server.lua +++ b/modules/framework/es_extended/server.lua @@ -13,16 +13,17 @@ local cachedItemList = nil --- @description This will return the name of the framework in use --- @return string Framework.GetFrameworkName = function() - return 'es_extended' + print("This is deprecated, please use Framework.GetResourceName() instead.") + return Framework.GetResourceName() end ----This will get the name of the in use resource. ----@return string +---@description This will get the name of the in use resource. +--- @return string Framework.GetResourceName = function() return 'es_extended' end ---- @description This is an internal function, its here to attempt to emulate qbs shared items mainly +---@description This is an internal function, its here to attempt to emulate qbs shared items mainly, do not use this outside of bridge. Framework.ItemList = function() if cachedItemList then return cachedItemList end local items = ESX.Items @@ -46,9 +47,9 @@ Framework.ItemList = function() return cachedItemList end ---- @description This will return if the player is an admin in the framework ---- @param src any ---- @return boolean +---@description This will return if the player is an admin in the framework. +---@param src number +---@return boolean Framework.GetIsFrameworkAdmin = function(src) if not src then return false end local xPlayer = Framework.GetPlayer(src) @@ -58,7 +59,8 @@ Framework.GetIsFrameworkAdmin = function(src) return false end ---- @description This will get the players birth date +---@description Returns the player date of birth. +--- @param src number --- @return string|nil Framework.GetPlayerDob = function(src) local xPlayer = Framework.GetPlayer(src) @@ -99,7 +101,7 @@ Framework.GetPlayerName = function(src) return xPlayer.variables.firstName, xPlayer.variables.lastName end ---- @description This will return a table of all logged in players +---@description This will return a table of all logged in players --- @return table Framework.GetPlayers = function() local players = ESX.GetExtendedPlayers() @@ -110,14 +112,16 @@ Framework.GetPlayers = function() return playerList end ---- @description This will return a table of items matching the specified name and if passed metadata from the player's inventory +---@description Returns a table of items matching the specified name and if passed metadata from the player's inventory. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. --- @param src number --- @param item string ---- @param _ table ---- @return table|nil returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} -Framework.GetItem = function(src, item, _) +--- @param metadata table +--- @return table {name, count, metadata, slot} +Framework.GetItem = function(src, item, metadata) + print("ESX does not support item metadata searches, please ensure you are using a supported inventory system or that you have the correct start order.") local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return {} end local playerItems = xPlayer.getInventory() local repackedTable = {} for _, v in pairs(playerItems) do @@ -125,40 +129,57 @@ Framework.GetItem = function(src, item, _) table.insert(repackedTable, { name = v.name, count = v.count, - --metadata = v.metadata, - --slot = v.slot, + metadata = {}, -- ESX does not support item metadata + slot = 0, -- ESX does not support item slots }) end end return repackedTable end ---- @param src number +---@description This will return a table with the item info, {name, label, stack, weight, description, image} +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. --- @param item string ---- @param _ table ---- @return number returns the count of the item in the players inventory, if not found will return 0. ---- If metadata is passed it will find the matching items count (esx_core does not feature metadata items) -Framework.GetItemCount = function(src, item, _) +--- @return table {name, label, stack, weight, description, image} +Framework.GetItemInfo = function(item) + local items = Framework.ItemList() + if not items[item] then return {} end + return {name = item, label = items[item].label, stack = false, weight = items[item].weight, description = items[item].description, image = items[item].image} +end + +---@description This will return the count of the item in the players inventory, if not found will return 0. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +---@param src number +---@param item string +---@param metadata table (optional) +---@return number +Framework.GetItemCount = function(src, item, metadata) + if metadata then + print("ESX does not support item metadata searches, please ensure you are using a supported inventory system or that you have the correct start order.") + end local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return 0 end return xPlayer.getInventoryItem(item).count end ---- @description This will return true if the player has the item, false otherwise +---@description This will return a boolean if the player has the item. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. --- @param src number --- @param item string ---- @return boolean returns true if the player has the item, false otherwise. +--- @return boolean Framework.HasItem = function(src, item) local getCount = Framework.GetItemCount(src, item, nil) return getCount > 0 end ---- @description This will return the player's inventory as a table ---- @param src number ---- @return table | nil returns the player's inventory as a table in format: {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} +---@description Returns the entire inventory of the player as a table. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +---@param src number +---@return table {name, count, metadata, slot} Framework.GetPlayerInventory = function(src) + print("ESX does not support item metadata or slots, please ensure you are using a supported inventory system or that you have the correct start order.") local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return {} end local playerItems = xPlayer.getInventory() local repackedTable = {} for _, v in pairs(playerItems) do @@ -166,15 +187,25 @@ Framework.GetPlayerInventory = function(src) table.insert(repackedTable, { name = v.name, count = v.count, - --metadata = v.metadata, - --slot = v.slot, + metadata = {}, -- ESX does not support item metadata + slot = 0, -- ESX does not support item slots }) end end return repackedTable end ---- @description Adds the specified metadata key and number value to the player's data. +---@description This will return the item data for the specified slot. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +--- @param src number +--- @param slot number +--- @return table {name, label, weight, count, metadata, slot, stack, description} +Framework.GetItemBySlot = function(src, slot) + print("ESX does not support item slots, please ensure you are using a supported inventory system or that you have the correct start order.") + return {} -- ESX does not support item slots +end + +---@description Adds the specified metadata key and number value to the player's data. --- @param src number --- @param metadata string --- @param value any @@ -186,8 +217,7 @@ Framework.SetPlayerMetadata = function(src, metadata, value) return true end --- Framework.GetMetadata(src, metadata) ---- @description Gets the specified metadata key to the player's data. +---@description Gets the specified metadata key to the player's data. --- @param src number --- @param metadata string --- @return any|nil @@ -197,7 +227,7 @@ Framework.GetPlayerMetadata = function(src, metadata) return xPlayer.getMeta(metadata) or false end ---- @description This will return the specified status column of the player. +---@description This is an internal function and should not be used outside of bridge, this is only present in the esx portion. --- @param src number --- @param column string --- @return string|nil @@ -213,16 +243,16 @@ Framework.GetStatus = function(src, column) return xPlayer.get(column) or nil end ---- @description This will return a boolean if the player is dead or in last stand +---@description This will return a boolean if the player is dead or in last stand. --- @param src number ---- @return boolean|nil +--- @return boolean Framework.GetIsPlayerDead = function(src) local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return false end return xPlayer.get("is_dead") or false end ---- @description This will revive a player, if the player is dead or in last stand +---@description This will revive a player, if the player is dead or in last stand. --- @param src number --- @return boolean Framework.RevivePlayer = function(src) @@ -254,13 +284,13 @@ Framework.AddHunger = function(src, value) return levelForEsx end ---- @description This will get the hunger of a player (ESX we get the percent of the status) +---@description This will get the hunger of a player --- @param src number ---- @return number | nil +--- @return number Framework.GetHunger = function(src) local status = Framework.GetStatus(src, "status") - if not status then return end - if type(status) ~= "table" then return end + if not status then return 0 end + if type(status) ~= "table" then return 0 end for _, entry in ipairs(status) do if entry.name == "hunger" then return math.floor((entry.percent) + 0.5) or 0 @@ -268,13 +298,13 @@ Framework.GetHunger = function(src) end end ---- @description This will get the thirst of a player (ESX we get the percent of the status) +---@description This will get the thirst of a player --- @param src any ---- @return number | nil +--- @return number Framework.GetThirst = function(src) local status = Framework.GetStatus(src, "status") - if not status then return nil end - if type(status) ~= "table" then return end + if not status then return 0 end + if type(status) ~= "table" then return 0 end for _, entry in ipairs(status) do if entry.name == "thirst" then return math.floor((entry.percent) + 0.5) or 0 @@ -282,16 +312,17 @@ Framework.GetThirst = function(src) end end ---- @description This will get the phone number of a player +---@description Returns the phone number of the player. --- @param src number ---- @return string | nil return the phone number of the player +--- @return string | nil Framework.GetPlayerPhone = function(src) local xPlayer = Framework.GetPlayer(src) if not xPlayer then return end return xPlayer.get("phone_number") end ----@deprecated This will return the job name, label, grade name, and grade level of the player. +---@description This will return the job name, label, grade name, and grade level of the player. +---@deprecated ---@param src number ---@return string | nil ---@return string | nil @@ -304,13 +335,12 @@ Framework.GetPlayerJob = function(src) return job.name, job.label, job.grade_label, job.grade end ---- @description This will return the players job name, job label, job grade label job grade level, ---- boss status, and duty status in a table +---@description This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table --- @param src number ---- @return table | nil +--- @return table {jobName, jobLabel, gradeName, gradeLabel, gradeRank, boss, onDuty} Framework.GetPlayerJobData = function(src) local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return {} end local job = xPlayer.getJob() local isBoss = (job.grade_name == "boss") return { @@ -324,9 +354,9 @@ Framework.GetPlayerJobData = function(src) } end ---- @description This will return the players duty status, true if on duty false otherwise +---@description Returns the players duty status. --- @param src number ---- @return boolean return the players duty status +--- @return boolean Framework.GetPlayerDuty = function(src) local xPlayer = Framework.GetPlayer(src) if not xPlayer then return false end @@ -335,7 +365,7 @@ Framework.GetPlayerDuty = function(src) return true end ---- @description This will toggle a players duty status +---@description This will toggle a players duty status --- @param src number --- @param status boolean --- @return boolean @@ -348,95 +378,131 @@ Framework.SetPlayerDuty = function(src, status) return true end ---- @description This will get a table of player sources that have the specified job name +---@description Returns the gang name of the player. +---@param src number +---@return string | nil +Framework.GetPlayerGang = function(src) + print("ESX does not support gangs, please ensure you are using a supported gang system or that you have the correct start order.") + return +end + +---@description This will get a table of player sources that have the specified job name. --- @param job string --- @return table Framework.GetPlayersByJob = function(job) return Framework.GetPlayerSourcesByJob(job) or {} end ---- @description This will set the player's job to the specified name and grade +---@description Sets the player's job to the specified name and grade. --- @param src number --- @param name string --- @param grade string ---- @return nil Framework.SetPlayerJob = function(src, name, grade) local xPlayer = Framework.GetPlayer(src) if not xPlayer then return end if not ESX.DoesJobExist(name, grade) then - Prints.Error("Job Does Not Exsist In Framework :NAME " .. name .. " Grade:" .. grade) + print("^6 Job Does Not Exsist In Framework :NAME " .. name .. " Grade:" .. grade .. " ^0 ") return end xPlayer.setJob(name, grade, true) return true end ---- @description This will add money based on the type of account (money/bank) +---@description This will add money based on the type of account (money/bank) --- @param src number --- @param _type string --- @param amount number ---- @return boolean | nil +--- @return boolean Framework.AddAccountBalance = function(src, _type, amount) local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return false end if _type == 'cash' then _type = 'money' end + if amount <= 0 then return false end xPlayer.addAccountMoney(_type, amount) return true end ---- @description This will remove money based on the type of account (money/bank) +---@description This will remove money based on the type of account (money/bank) --- @param src number --- @param _type string --- @param amount number ---- @return boolean | nil +--- @return boolean Framework.RemoveAccountBalance = function(src, _type, amount) local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return false end if _type == 'cash' then _type = 'money' end + if amount <= 0 then return false end + local accountVal = Framework.GetAccountBalance(src, _type) + if accountVal < amount then return false end xPlayer.removeAccountMoney(_type, amount) return true end ---- @description This will get the account balance based on the type of account (money/bank) +---@description This will get money based on the type of account (money/bank) --- @param src number --- @param _type string ---- @return string | nil +--- @return number Framework.GetAccountBalance = function(src, _type) local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return 0 end if _type == 'cash' then _type = 'money' end - return xPlayer.getAccount(_type).money + local balance = xPlayer.getAccount(_type).money or 0 + if balance <= 0 then return 0 end + return balance end ---- @description Adds the specified item to the player's inventory ---- @param src number ---- @param item string ---- @param amount number ---- @param slot number ---- @param metadata table ---- @return boolean | nil -Framework.AddItem = function(src, item, amount, slot, metadata) +---@description This will add an item, and return true or false based on success +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Framework.AddItem = function(src, item, count, slot, metadata) + if slot then print("ESX does not support item slots, please ensure you are using a supported inventory system or that you have the correct start order.") end + if metadata then print("ESX does not support item metadata, please ensure you are using a supported inventory system or that you have the correct start order.") end local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end - xPlayer.addInventoryItem(item, amount) + if not xPlayer then return false end + xPlayer.addInventoryItem(item, count) + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "add", item = item, count = count, slot = slot, metadata = metadata }) return true end ---- @description Removes the specified item from the player's inventory +---@description Removes the specified item from the player's inventory. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. --- @param src number --- @param item string --- @param amount number ---- @param slot number ---- @param metadata table ----@return boolean | nil +--- @param slot number (optional) +--- @param metadata table (optional) +--- @return boolean Framework.RemoveItem = function(src, item, amount, slot, metadata) + if slot then + print("ESX does not support item slots, please ensure you are using a supported inventory system or that you have the correct start order.") + end + if metadata then + print("ESX does not support item metadata, please ensure you are using a supported inventory system or that you have the correct start order.") + end local xPlayer = Framework.GetPlayer(src) - if not xPlayer then return end + if not xPlayer then return false end xPlayer.removeInventoryItem(item, amount) return true end ---- @description This will get all owned vehicles for the player +---@description Sets the metadata for the specified item in the player's inventory. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +--- @param src number +--- @param item string +--- @param slot number +--- @param metadata table +--- @return boolean +Framework.SetMetadata = function(src, item, slot, metadata) + print("ESX does not support item metadata, please ensure you are using a supported inventory system or that you have the correct start order.") + return false +end + +---@description This will get all owned vehicles for the player --- @param src number --- @return table Framework.GetOwnedVehicles = function(src) @@ -452,7 +518,7 @@ Framework.GetOwnedVehicles = function(src) return vehicles end ---- @description Registers a usable item with a callback function +---@description Registers a usable item with a callback function. --- @param itemName string --- @param cb function Framework.RegisterUsableItem = function(itemName, cb) @@ -465,6 +531,8 @@ Framework.RegisterUsableItem = function(itemName, cb) ESX.RegisterUsableItem(itemName, func) end +---@description Event handler for when a player is loaded in ESX framework +---@param src number RegisterNetEvent("esx:playerLoaded", function(src) src = src or source TriggerEvent("community_bridge:Server:OnPlayerLoaded", src) @@ -473,32 +541,50 @@ RegisterNetEvent("esx:playerLoaded", function(src) Framework.AddJobCount(src, jobData.jobName) end) +---@description Event handler for when a player logs out in ESX framework +---@param src number RegisterNetEvent("esx:playerLogout", function(src) src = src or source TriggerEvent("community_bridge:Server:OnPlayerUnload", src) end) +---@description Event handler for when a player's job is updated in ESX framework +---@param src number +---@param job table +---@param lastJob table RegisterNetEvent("esx:setJob", function(src, job, lastJob) src = src or source if not job or not lastJob then return end TriggerEvent("community_bridge:Server:OnPlayerJobChange", src, job.name) end) +---@description Event handler for when a player disconnects from the server AddEventHandler("playerDropped", function() local src = source TriggerEvent("community_bridge:Server:OnPlayerUnload", src) end) +---@description Callback to get framework jobs list +---@param source number Callback.Register('community_bridge:Callback:GetFrameworkJobs', function(source) return Framework.GetFrameworkJobs() or {} end) --- This is linked to an internal function, its an attempt to standardize the item list across frameworks. +---@description This is linked to an internal function, its an attempt to standardize the item list across frameworks. +---@param source number Callback.Register('community_bridge:Callback:GetFrameworkItems', function(source) return Framework.ItemList() or {} end) Framework.Commands = {} +---@description Adds a command to the ESX framework +---@param name string +---@param help string +---@param arguments table +---@param argsrequired boolean +---@param callback function +---@param permission string +---@param ... any Framework.Commands.Add = function(name, help, arguments, argsrequired, callback, permission, ...) ESX.RegisterCommand(name, permission, function(xPlayer, args, showError) callback(xPlayer, args) diff --git a/modules/framework/qb-core/client.lua b/modules/framework/qb-core/client.lua index 21b5dac..d4ac0a3 100644 --- a/modules/framework/qb-core/client.lua +++ b/modules/framework/qb-core/client.lua @@ -8,33 +8,34 @@ QBCore = exports['qb-core']:GetCoreObject() Framework.Shared = QBCore.Shared ----This will get the name of the framework being used (if a supported framework). +---@description This will get the name of the framework being used (if a supported framework). ---@return string Framework.GetFrameworkName = function() - return 'qb-core' + print("This is depricated, please use Framework.GetResourceName() instead.") + return Framework.GetResourceName() end ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Framework.GetResourceName = function() return 'qb-core' end ----This will return true if the player is loaded, false otherwise. +---@description This will return true if the player is loaded, false otherwise. ---This could be useful in scripts that rely on player loaded events and offer a debug mode to hit this function. ---@return boolean Framework.GetIsPlayerLoaded = function() return LocalPlayer.state.isLoggedIn or false end ----This will return a table of the player data, this will be in the framework format. +---@description This will return a table of the player data, this will be in the framework format. ---This is mainly for internal bridge use and should be avoided. ---@return table Framework.GetPlayerData = function() return QBCore.Functions.GetPlayerData() end ----This will return a table of all the jobs in the framework. +---@description This will return a table of all the jobs in the framework. ---@return table Framework.GetFrameworkJobs = function() local jobs = {} @@ -48,7 +49,7 @@ Framework.GetFrameworkJobs = function() return jobs end ----This will get the players birth date +---@description This will get the players birth date ---@return string Framework.GetPlayerDob = function() local player = Framework.GetPlayerData() @@ -56,14 +57,14 @@ Framework.GetPlayerDob = function() return playerData.charinfo.birthdate end ----This will return the players metadata for the specified metadata key. +---@description This will return the players metadata for the specified metadata key. ---@param metadata table | string ---@return table | string | number | boolean Framework.GetPlayerMetaData = function(metadata) return Framework.GetPlayerData().metadata[metadata] end ----This will send a notification to the player. +---@description This will send a notification to the player. ---@param message string ---@param type string ---@param time number @@ -72,7 +73,7 @@ Framework.Notify = function(message, type, time) TriggerEvent('QBCore:Notify', message, 'primary', time) end ----Will Display the help text message on the screen +---@description This will display the help text message on the screen ---@param message string ---@param _position unknown ---@return nil @@ -80,14 +81,14 @@ Framework.ShowHelpText = function(message, _position) return exports['qb-core']:DrawText(message, _position) end ----This will hide the help text message on the screen +---@description This will hide the help text message on the screen ---@return nil Framework.HideHelpText = function() return exports['qb-core']:HideText() end ----This will return the players money by type, I recommend not useing this as its the client and not secure or to be trusted. ----Use case is for a ui or a menu I guess. +---@description This will return the players money by type, I recommend not using this +---as its the client and not secure or to be trusted. Use case is for a ui or a menu I guess. ---@param _type string ---@return number Framework.GetAccountBalance = function(_type) @@ -98,7 +99,7 @@ Framework.GetAccountBalance = function(_type) return account[_type] or 0 end ----This will return the item data for the specified item. +---@description This will return the item data for the specified item. ---@param item string ---@return table Framework.GetItemInfo = function(item) @@ -115,27 +116,27 @@ Framework.GetItemInfo = function(item) return repackedTable end ----This will get the hunger of a player +---@description This will get the hunger of a player ---@return number Framework.GetHunger = function() local hunger = Framework.GetPlayerMetaData("hunger") or 0 return math.floor((hunger) + 0.5) or 0 end ----This will get the thirst of a player +---@description This will get the thirst of a player ---@return number Framework.GetThirst = function() local thirst = Framework.GetPlayerMetaData("thirst") or 0 return math.floor((thirst) + 0.5) or 0 end ----This will get the players identifier (citizenid) etc. +---@description This will get the players identifier (citizenid) etc. ---@return string Framework.GetPlayerIdentifier = function() return Framework.GetPlayerData().citizenid end ----This will get the players name (first and last). +---@description This will get the players name (first and last). ---@return string ---@return string Framework.GetPlayerName = function() @@ -143,17 +144,18 @@ Framework.GetPlayerName = function() return playerData.charinfo.firstname, playerData.charinfo.lastname end ----Depricated : This will return the players job name, job label, job grade label and job grade level +---@deprecated Deprecated: This will return the players job name, job label, job grade label and job grade level ---@return string ---@return string ---@return string ---@return string Framework.GetPlayerJob = function() - local playerData = Framework.GetPlayerData() - return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level + print("This is depricated, please use Framework.GetPlayerJobData() instead.") + local jobData = Framework.GetPlayerJobData() + return jobData.jobName, jobData.jobLabel, jobData.gradeName, jobData.gradeRank end ----This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table +---@description This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table ---@return table Framework.GetPlayerJobData = function() local playerData = Framework.GetPlayerData() @@ -169,14 +171,15 @@ Framework.GetPlayerJobData = function() } end ----This will return if the player has the specified item in their inventory. +---@description Will return boolean if the player has the item. ---@param item string +---@param requiredCount number (optional) ---@return boolean -Framework.HasItem = function(item) - return QBCore.Functions.HasItem(item) +Framework.HasItem = function(item, requiredCount) + return QBCore.Functions.HasItem(item, requiredCount or 1) end ----This will return the item count for the specified item in the players inventory. +---@description This will return the item count for the specified item in the players inventory ---@param item string ---@return number Framework.GetItemCount = function(item) @@ -184,13 +187,13 @@ Framework.GetItemCount = function(item) local count = 0 for _, v in pairs(frameworkInv) do if v.name == item then - count = count + v.amount + count = count + (v.amount or v.count) end end return count end ----This will return the players inventory as a table in the ox_inventory style flormat. +---@description This will return the players inventory as a table in the ox_inventory style format ---@return table Framework.GetPlayerInventory = function() local items = {} @@ -199,9 +202,9 @@ Framework.GetPlayerInventory = function() table.insert(items, { name = v.name, label = v.label, - count = v.amount, + count = v.amount or v.count, slot = v.slot, - metadata = v.info, + metadata = v.info or v.metadata or {}, stack = v.unique, close = v.useable, weight = v.weight @@ -210,7 +213,7 @@ Framework.GetPlayerInventory = function() return items end ----This will return the vehicle properties for the specified vehicle. +---@description This will return the vehicle properties for the specified vehicle ---@param vehicle number ---@return table Framework.GetVehicleProperties = function(vehicle) @@ -219,7 +222,7 @@ Framework.GetVehicleProperties = function(vehicle) return vehicleProps or {} end ----This will set the vehicle properties for the specified vehicle. +---@description This will set the vehicle properties for the specified vehicle ---@param vehicle number ---@param properties table ---@return boolean @@ -241,35 +244,28 @@ Framework.SetVehicleProperties = function(vehicle, properties) return true, QBCore.Functions.SetVehicleProperties(vehicle, properties) end ----This will get a players dead status. +---@description This will get a players dead status ---@return boolean Framework.GetIsPlayerDead = function() local playerData = Framework.GetPlayerData() return playerData.metadata["isdead"] or playerData.metadata["inlaststand"] end +---@description Event handler for when player is loaded in QB-Core framework RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() Wait(1500) TriggerEvent('community_bridge:Client:OnPlayerLoaded') end) +---@description Event handler for when player is unloaded in QB-Core framework RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() TriggerEvent('community_bridge:Client:OnPlayerUnload') end) +---@description Event handler for when player job is updated in QB-Core framework +---@param data table Job data containing name, label, grade_label, and grade RegisterNetEvent('QBCore:Client:OnJobUpdate', function(data) TriggerEvent('community_bridge:Client:OnPlayerJobUpdate', data.name, data.label, data.grade_label, data.grade) end) -RegisterNetEvent('QBCore:Client:OnGangUpdate', function(data) - -- Unsure what data is passed in this, but considering the gang data isnt updating I doubt this was tested. - --[[ - PlayerJobName = data.name - PlayerJobLabel = data.label - PlayerJobGradeName = data.grade.name - PlayerJobGradeLevel = data.grade.level - TriggerEvent('community_bridge:Client:OnPlayerGangUpdate', PlayerGangName, PlayerGangLabel, PlayerGangGradeName, PlayerGangGradeLevel) - --]] -end) - return Framework \ No newline at end of file diff --git a/modules/framework/qb-core/server.lua b/modules/framework/qb-core/server.lua index 765855d..52196f8 100644 --- a/modules/framework/qb-core/server.lua +++ b/modules/framework/qb-core/server.lua @@ -8,19 +8,20 @@ QBCore = exports['qb-core']:GetCoreObject() Framework.Shared = QBCore.Shared ----This will return the name of the framework in use. +---@description This will return the name of the framework in use. ---@return string Framework.GetFrameworkName = function() - return 'qb-core' + print("[Community Bridge] Warning: Framework.GetFrameworkName is deprecated, use Framework.GetResourceName instead.") + return Framework.GetResourceName() end ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Framework.GetResourceName = function() return 'qb-core' end ----This will return if the player is an admin in the framework. +---@description This will return if the player is an admin in the framework. ---@param src any ---@return boolean Framework.GetIsFrameworkAdmin = function(src) @@ -28,8 +29,7 @@ Framework.GetIsFrameworkAdmin = function(src) return QBCore.Functions.HasPermission(src, 'admin') end --- Framework.GetPlayerIdentifier(src) --- Returns the citizen ID of the player. +---@description This will return the citizen ID of the player. ---@param src number ---@return string | nil Framework.GetPlayerIdentifier = function(src) @@ -39,7 +39,7 @@ Framework.GetPlayerIdentifier = function(src) return playerData.citizenid end ---- Returns the player data of the specified source in the framework defualt format. +---@description Returns the player data of the specified source in the framework defualt format. ---@param src any ---@return table | nil Framework.GetPlayer = function(src) @@ -48,10 +48,8 @@ Framework.GetPlayer = function(src) return player end ----This will return the jobs registered in the framework in a table. ----Format of the table is: ----{name = jobName, label = jobLabel, grade = {name = gradeName, level = gradeLevel}} ----@return table +---@description This will return the jobs registered in the framework in a table. +---@return table {name = jobName, label = jobLabel, grade = {name = gradeName, level = gradeLevel}} Framework.GetFrameworkJobs = function() local jobs = {} for k, v in pairs(QBCore.Shared.Jobs) do @@ -64,8 +62,7 @@ Framework.GetFrameworkJobs = function() return jobs end --- Framework.GetPlayerName(src) --- Returns the first and last name of the player. +---@description Returns the first and last name of the player. ---@return string|nil, string|nil Framework.GetPlayerName = function(src) local player = Framework.GetPlayer(src) @@ -74,7 +71,7 @@ Framework.GetPlayerName = function(src) return playerData.charinfo.firstname, playerData.charinfo.lastname end ----Returns the player date of birth. +---@description Returns the player date of birth. ---@param src number ---@return string|nil Framework.GetPlayerDob = function(src) @@ -84,12 +81,11 @@ Framework.GetPlayerDob = function(src) return playerData.charinfo.birthdate end ----Returns a table of items matching the specified name and if passed metadata from the player's inventory. ----returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} +---@description Returns a table of items matching the specified name and if passed metadata from the player's inventory. ---@param src number ---@param item string ---@param metadata table ----@return table|nil +---@return table|nil {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} Framework.GetItem = function(src, item, metadata) local player = Framework.GetPlayer(src) if not player then return end @@ -100,7 +96,7 @@ Framework.GetItem = function(src, item, metadata) if v.name == item and (not metadata or v.info == metadata) then table.insert(repackedTable, { name = v.name, - count = v.amount, + count = v.amount or v.count, metadata = v.info, slot = v.slot, }) @@ -109,9 +105,9 @@ Framework.GetItem = function(src, item, metadata) return repackedTable end ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will return a table with the item info ---@param item string ----@return table +---@return table {name, label, stack, weight, description, image} Framework.GetItemInfo = function(item) local itemData = QBCore.Shared.Items[item] if not itemData then return {} end @@ -126,8 +122,7 @@ Framework.GetItemInfo = function(item) return repackedTable end ----This will return the count of the item in the players inventory, if not found will return 0. ---- +---@description This will return the count of the item in the players inventory, if not found will return 0 ---if metadata is passed it will find the matching items count. ---@param src number ---@param item string @@ -141,13 +136,13 @@ Framework.GetItemCount = function(src, item, metadata) local count = 0 for _, v in pairs(playerInventory) do if v.name == item and (not metadata or v.info == metadata) then - count = count + v.amount + count = count + (v.amount or v.count) end end return count end ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string ---@return boolean @@ -156,11 +151,9 @@ Framework.HasItem = function(src, item) return getCount > 0 end --- Framework.GetPlayerInventory(src) --- Returns the entire inventory of the player as a table. --- returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} +---@description Returns the entire inventory of the player as a table. ---@param src number ----@return table | nil +---@return table | nil {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} Framework.GetPlayerInventory = function(src) local player = Framework.GetPlayer(src) if not player then return end @@ -170,7 +163,7 @@ Framework.GetPlayerInventory = function(src) for _, v in pairs(playerInventory) do table.insert(repackedTable, { name = v.name, - count = v.amount, + count = v.amount or v.count, metadata = v.info, slot = v.slot, }) @@ -178,7 +171,7 @@ Framework.GetPlayerInventory = function(src) return repackedTable end ----This will return a table of all logged in players +---@description This will return a table of all logged in players ---@return table Framework.GetPlayers = function() local players = QBCore.Functions.GetPlayers() @@ -189,11 +182,10 @@ Framework.GetPlayers = function() return playerList end ----This will return the item data for the specified slot. ----Format {name, label, weight, count, metadata, slot, stack, description} +---@description This will return the item data for the specified slot. ---@param src number ---@param slot number ----@return table|nil +---@return table|nil {name, label, weight, count, metadata, slot, stack, description} Framework.GetItemBySlot = function(src, slot) local player = Framework.GetPlayer(src) if not player then return end @@ -206,7 +198,7 @@ Framework.GetItemBySlot = function(src, slot) name = v.name, label = v.label, weight = v.weight, - count = v.amount, + count = v.amount or v.count, metadata = v.info, slot = v.slot, stack = v.unique or false, @@ -217,8 +209,7 @@ Framework.GetItemBySlot = function(src, slot) return repack end --- Framework.SetMetadata(src, metadata, value) --- Adds the specified metadata key and number value to the player's data. +---@description Adds the specified metadata key and number value to the player's data. ---@return boolean|nil Framework.SetPlayerMetadata = function(src, metadata, value) local player = Framework.GetPlayer(src) @@ -227,8 +218,7 @@ Framework.SetPlayerMetadata = function(src, metadata, value) return true end --- Framework.GetMetadata(src, metadata) --- Gets the specified metadata key to the player's data. +---@description Gets the specified metadata key to the player's data. ---@param src number ---@param metadata string ---@return any|nil @@ -239,8 +229,7 @@ Framework.GetPlayerMetadata = function(src, metadata) return playerData.metadata[metadata] or false end --- Framework.AddStress(src, value) --- Adds the specified value to the player's stress level and updates the client HUD. +---@description Adds the specified value to the player's stress level and updates the client HUD. ---@param src number ---@param value number ---@return number | nil @@ -254,8 +243,7 @@ Framework.AddStress = function(src, value) return newStress end --- Framework.RemoveStress(src, value) --- Removes the specified value from the player's stress level and updates the client HUD. +---@description Removes the specified value from the player's stress level and updates the client HUD. ---@param src number ---@param value number ---@return number | nil @@ -269,8 +257,7 @@ Framework.RemoveStress = function(src, value) return newStress end --- Framework.AddHunger(src, value) --- Adds the specified value from the player's hunger level. +---@description Adds the specified value from the player's hunger level. ---@param src number ---@param value number ---@return number | nil @@ -281,12 +268,10 @@ Framework.AddHunger = function(src, value) local newHunger = (playerData.metadata.hunger or 0) + value player.Functions.SetMetaData('hunger', Math.Clamp(newHunger, 0, 100)) TriggerClientEvent('hud:client:UpdateNeeds', src, newHunger, playerData.metadata.thirst) - --TriggerClientEvent('hud:client:UpdateStress', src, newStress) return newHunger end --- Framework.AddThirst(src, value) --- Adds the specified value from the player's thirst level. +---@description Adds the specified value from the player's thirst level. ---@param src number ---@param value number ---@return number | nil @@ -297,11 +282,10 @@ Framework.AddThirst = function(src, value) local newThirst = (playerData.metadata.thirst or 0) + value player.Functions.SetMetaData('thirst', Math.Clamp(newThirst, 0, 100)) TriggerClientEvent('hud:client:UpdateNeeds', src, playerData.metadata.hunger, newThirst) - --TriggerClientEvent('hud:client:UpdateStress', src, newStress) return newThirst end ----This will get the hunger of a player +---@description This will get the hunger of a player ---@param src number ---@return number | nil Framework.GetHunger = function(src) @@ -312,17 +296,17 @@ Framework.GetHunger = function(src) return math.floor((newHunger) + 0.5) or 0 end ----This will return a boolean if the player is dead or in last stand. +---@description This will return a boolean if the player is dead or in last stand. ---@param src number ---@return boolean|nil Framework.GetIsPlayerDead = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return false end local playerData = player.PlayerData return playerData.metadata.isdead or playerData.metadata.inlaststand or false end ----This will revive a player, if the player is dead or in last stand. +---@description This will revive a player, if the player is dead or in last stand. ---@param src number ---@return boolean Framework.RevivePlayer = function(src) @@ -332,20 +316,29 @@ Framework.RevivePlayer = function(src) return true end +--- @description This will get the hunger of a player +--- @param src number +--- @return number +Framework.GetHunger = function(src) + local player = Framework.GetPlayer(src) + if not player then return 0 end + local playerData = player.PlayerData + local newHunger = (playerData.metadata.hunger or 0) + return math.floor((newHunger) + 0.5) or 0 +end ----This will get the thirst of a player +---@description This will get the thirst of a player ---@param src any ---@return number | nil Framework.GetThirst = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return 0 end local playerData = player.PlayerData local newThirst = (playerData.metadata.thirst or 0) return math.floor((newThirst) + 0.5) or 0 end --- Framework.GetPlayerPhone(src) --- Returns the phone number of the player. +---@description Returns the phone number of the player. ---@param src number ---@return string | nil Framework.GetPlayerPhone = function(src) @@ -355,8 +348,7 @@ Framework.GetPlayerPhone = function(src) return playerData.charinfo.phone end --- Framework.GetPlayerGang(src) --- Returns the gang name of the player. +---@description Returns the gang name of the player. ---@param src number ---@return string | nil Framework.GetPlayerGang = function(src) @@ -366,32 +358,33 @@ Framework.GetPlayerGang = function(src) return playerData.gang.name end ----This will get a table of player sources that have the specified job name. +---@description This will get a table of player sources that have the specified job name. ---@param job string ---@return table Framework.GetPlayersByJob = function(job) return Framework.GetPlayerSourcesByJob(job) or {} end ----Depricated: Returns the job name, label, grade name, and grade level of the player. +---@deprecated Deprecated: Returns the job name, label, grade name, and grade level of the player. ---@param src number ---@return string | string | string | number | nil ---@return string | string | string | number | nil ---@return string | string | string | number | nil ---@return string | string | string | number | nil Framework.GetPlayerJob = function(src) - local player = Framework.GetPlayer(src) - if not player then return end - local playerData = player.PlayerData - return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level + print("[Community Bridge] Warning: Framework.GetPlayerJob is deprecated, use Framework.GetPlayerJobData instead.") + local jobData = Framework.GetPlayerJobData(src) + if not jobData then return end + return jobData.jobName, jobData.jobLabel, jobData.gradeName, jobData.gradeLevel end ----This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table +---@description This will return the players job name, job label, job grade label job grade level, boss status, +---and duty status in a table ---@param src number ---@return table | nil Framework.GetPlayerJobData = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return { } end local playerData = player.PlayerData local jobData = playerData.job return { @@ -405,21 +398,21 @@ Framework.GetPlayerJobData = function(src) } end ----Returns the players duty status. +---@description Returns the players duty status. ---@param src number ---@return boolean | nil Framework.GetPlayerDuty = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return false end local playerData = player.PlayerData if not playerData.job.onduty then return false end return true end ----This will toggle a players duty status ----@param src number ----@param status boolean ----@return boolean +--- @description This will toggle a players duty status +--- @param src number +--- @param status boolean +--- @return boolean Framework.SetPlayerDuty = function(src, status) local player = Framework.GetPlayer(src) if not player then return false end @@ -428,86 +421,108 @@ Framework.SetPlayerDuty = function(src, status) return true end --- Sets the player's job to the specified name and grade. +---@description Sets the player's job to the specified name and grade. ---@param src number ---@param name string ---@param grade string ---@return nil Framework.SetPlayerJob = function(src, name, grade) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return false end return player.Functions.SetJob(name, grade) end ----This will add money based on the type of account (money/bank) +---@description This will add money based on the type of account (money/bank) ---@param src number ---@param _type string ---@param amount number ---@return boolean | nil Framework.AddAccountBalance = function(src, _type, amount) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return false end if _type == 'money' then _type = 'cash' end + if amount <= 0 then return false end return player.Functions.AddMoney(_type, amount) end ----This will remove money based on the type of account (money/bank) +---@description This will remove money based on the type of account (money/bank) ---@param src number ---@param _type string ---@param amount number ---@return boolean | nil Framework.RemoveAccountBalance = function(src, _type, amount) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return false end if _type == 'money' then _type = 'cash' end return player.Functions.RemoveMoney(_type, amount) end ----This will remove money based on the type of account (money/bank) +---@description This will remove money based on the type of account (money/bank) ---@param src number ---@param _type string ---@return string | nil Framework.GetAccountBalance = function(src, _type) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return 0 end local playerData = player.PlayerData if _type == 'money' then _type = 'cash' end return playerData.money[_type] end --- Framework.AddItem(src, item, amount, slot, metadata) --- Adds the specified item to the player's inventory. +---@description This will add an item, and return true or false based on success +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. ---@param src number ---@param item string ----@param amount number ----@param slot number ----@param metadata table ----@return boolean | nil -Framework.AddItem = function(src, item, amount, slot, metadata) +---@param count number +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Framework.AddItem = function(src, item, count, slot, metadata) local player = Framework.GetPlayer(src) - if not player then return end - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "add", item = item, count = amount, slot = slot, metadata = metadata }) - return player.Functions.AddItem(item, amount, slot, metadata) + if not player then return false end + local success = player.Functions.AddItem(item, count, slot, metadata) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "add", item = item, count = count, slot = slot, metadata = metadata }) + return success end --- Framework.RemoveItem(src, item, amount, slot, metadata) --- Removes the specified item from the player's inventory. +---@description Internal function to search for items with specific metadata in player inventory +---@param src number +---@param metadata table +---@return boolean, number|nil +local function runMetadataSearch(src, metadata) + local inv = Framework.GetPlayerInventory(src) or {} + for k, v in pairs(inv) do + if v.metadata and v.metadata == metadata then + return true, v.slot + end + end + return false +end + +---@description This will remove an item, and return true or false based on success ---@param src number ---@param item string ----@param amount number ----@param slot number ----@param metadata table ----@return boolean | nil -Framework.RemoveItem = function(src, item, amount, slot, metadata) +---@param count number +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Framework.RemoveItem = function(src, item, count, slot, metadata) local player = Framework.GetPlayer(src) - if not player then return end - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "remove", item = item, count = amount, slot = slot, metadata = metadata }) - return player.Functions.RemoveItem(item, amount, slot or nil) + if not player then return false end + if metadata then + local found, itemSlot = runMetadataSearch(src, metadata) + if found then + slot = itemSlot + end + end + local success = player.Functions.RemoveItem(item, count, slot) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "remove", item = item, count = count, slot = slot, metadata = metadata }) + return success end --- Framework.SetMetadata(src, item, slot, metadata) --- Sets the metadata for the specified item in the player's inventory. --- Notes, this is kinda a jank workaround. with the framework aside from updating the entire table theres not really a better way +---@description This will set the metadata of an item in the inventory. ---@param src number ---@param item string ---@param slot number @@ -515,23 +530,95 @@ end ---@return boolean | nil Framework.SetMetadata = function(src, item, slot, metadata) local player = Framework.GetPlayer(src) - if not player then return end - local slotFinder = Framework.GetPlayerInventory(src) - local freeSlot = Table.FindFirstUnoccupiedSlot(slotFinder) - local itemSlot = slot or nil - if itemSlot == nil then - for _, v in pairs(slotFinder) do - if v.name == item then - slot = v.slot - break - end - end - end - if not player.Functions.RemoveItem(item, 1, itemSlot) then return false end - return player.Functions.AddItem(item, 1, slot, metadata) + if not player then return false end + local success = Framework.RemoveItem(src, item, 1, slot, nil) + if not success then return false end + Framework.AddItem(src, item, 1, slot, metadata) end ----This will get all owned vehicles for the player +---@description This will return a table with the item info, {name, label, stack, weight, description, image} +---@param item string +---@return table +Framework.GetItemInfo = function(item) + local itemData = QBCore.Shared.Items[item] + if not itemData then return {} end + return { + name = itemData.name, + label = itemData.label or itemData.name, + stack = itemData.unique, + weight = itemData.weight, + description = itemData.description, + image = itemData.image + } +end + +---@description This will return the count of the item in the players inventory, if not found will return 0. +--- This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +---@param src number +---@param item string +---@param metadata table (optional) +---@return number +Framework.GetItemCount = function(src, item, metadata) + local player = Framework.GetPlayer(src) + if not player then return 0 end + local playerData = player.PlayerData + local playerInventory = playerData.items + local count = 0 + for _, v in pairs(playerInventory) do + if v.name == item and (not metadata or v.info == metadata) then + count = count + (v.amount or v.count) + end + end + return count +end + +---@description This will return a boolean if the player has the item. +---@param src number +---@param item string +---@param requiredCount number (optional) +---@return boolean +Framework.HasItem = function(src, item, requiredCount) + local getCount = Framework.GetItemCount(src, item, nil) + return getCount >= (requiredCount or 1) +end + +---@description This wil return the players inventory. +---@param src number +---@return table +Framework.GetPlayerInventory = function(src) + local player = Framework.GetPlayer(src) + if not player then return {} end + local playerData = player.PlayerData + local playerInventory = playerData.items + local repackedTable = {} + for _, v in pairs(playerInventory) do + table.insert(repackedTable, { + name = v.name, + count = v.amount or v.count, + metadata = v.info, + slot = v.slot, + }) + end + return repackedTable +end + +---@description Returns the specified slot data as a table. +---@param src number +---@param slot number +---@return table {name, label, weight, count, metadata, slot, stack, description, image} +Framework.GetItemBySlot = function(src, slot) + local inventory = Framework.GetPlayerInventory(src) + if not inventory or #inventory == 0 then return {} end + for _, v in pairs(inventory) do + if v.slot == slot then + local itemInfo = Framework.GetItemInfo(v.name) + return {v.name, itemInfo.label or v.name, itemInfo.weight or 0, v.count or 0, v.metadata or {}, v.slot, itemInfo.stack or false, itemInfo.description or "No description available", itemInfo.image or nil} + end + end + return {} +end + +---@description This will get all owned vehicles for the player ---@param src number ---@return table Framework.GetOwnedVehicles = function(src) @@ -546,8 +633,7 @@ Framework.GetOwnedVehicles = function(src) return vehicles end --- Framework.RegisterUsableItem(item, cb) --- Registers a usable item with a callback function. +---@description Registers a usable item with a callback function. ---@param itemName string ---@param cb function Framework.RegisterUsableItem = function(itemName, cb) @@ -560,6 +646,8 @@ Framework.RegisterUsableItem = function(itemName, cb) QBCore.Functions.CreateUseableItem(itemName, func) end +---@description Event handler for when a player is loaded in QB-Core framework +---@param src number RegisterNetEvent("QBCore:Server:OnPlayerLoaded", function(src) src = src or source TriggerEvent("community_bridge:Server:OnPlayerLoaded", src) @@ -568,23 +656,37 @@ RegisterNetEvent("QBCore:Server:OnPlayerLoaded", function(src) Framework.AddJobCount(src, jobData.jobName) end) +---@description Event handler for when a player is unloaded in QB-Core framework +---@param src number RegisterNetEvent("QBCore:Server:OnPlayerUnload", function(src) src = src or source TriggerEvent("community_bridge:Server:OnPlayerUnload", src) end) +---@description Event handler for when a player's job is updated in QB-Core framework +---@param src number +---@param job table RegisterNetEvent("QBCore:Server:OnJobUpdate", function(src, job) src = src or source if not job then return end TriggerEvent("community_bridge:Server:OnPlayerJobChange", src, job.name) end) +---@description Event handler for when a player disconnects from the server AddEventHandler("playerDropped", function() local src = source TriggerEvent("community_bridge:Server:OnPlayerUnload", src) end) Framework.Commands = {} +---@description Adds a command to the QB-Core framework +---@param name string +---@param help string +---@param arguments table +---@param argsrequired boolean +---@param callback function +---@param permission string +---@param ... any Framework.Commands.Add = function(name, help, arguments, argsrequired, callback, permission, ...) QBCore.Commands.Add(name, help, arguments, argsrequired, callback, permission, ...) end diff --git a/modules/framework/qbx_core/client.lua b/modules/framework/qbx_core/client.lua index 59c4dbd..05bc161 100644 --- a/modules/framework/qbx_core/client.lua +++ b/modules/framework/qbx_core/client.lua @@ -5,46 +5,45 @@ QBox = exports.qbx_core Framework = Framework or {} ----This will get the name of the framework being used (if a supported framework). +---@description This will get the name of the framework being used (if a supported framework). ---@return string Framework.GetFrameworkName = function() - return 'qbx_core' + print("This is depricated, please use Framework.GetResourceName() instead.") + return Framework.GetResourceName() end ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Framework.GetResourceName = function() return 'qbx_core' end ----This will return true if the player is loaded, false otherwise. ----This could be useful in scripts that rely on player loaded events and offer a debug mode to hit this function. +---@description This will return true if the player is loaded, false otherwise. ---@return boolean Framework.GetIsPlayerLoaded = function() return LocalPlayer.state.isLoggedIn or false end ----This will return a table of the player data, this will be in the framework format. ----This is mainly for internal bridge use and should be avoided. +---@description This is an internal function, do not use this outside of bridge as there is no standard format between the frameworks. ---@return table Framework.GetPlayerData = function() return QBox.GetPlayerData() end ----This will return a table of all the jobs in the framework. +---@description This will return a table of all the jobs in the framework. ---@return table Framework.GetFrameworkJobs = function() return QBox.GetJobs() end ----This will get the players birth date +---@description This will get the players birth date ---@return string Framework.GetPlayerDob = function() local playerData = Framework.GetPlayerData() return playerData.charinfo.birthdate end ----Will Display the help text message on the screen +---@description Will Display the help text message on the screen ---@param message string ---@param position string ---@return nil @@ -52,20 +51,20 @@ Framework.ShowHelpText = function(message, position) return exports.ox_lib:showTextUI(message, { position = position or 'top-center' }) end ----This will hide the help text message on the screen +---@description This will hide the help text message on the screen ---@return nil Framework.HideHelpText = function() return exports.ox_lib:hideTextUI() end ----This will return the players metadata for the specified metadata key. +---@description This will return the players metadata for the specified metadata key. ---@param metadata table | string ---@return table | string | number | boolean Framework.GetPlayerMetaData = function(metadata) return Framework.GetPlayerData().metadata[metadata] end ----This will send a notification to the player. +---@description This will send a notification to the player. ---@param message string ---@param type string ---@param time number @@ -74,27 +73,27 @@ Framework.Notify = function(message, type, time) return QBox:Notify("Notification", type, time, message) end ----This will get the hunger of a player +---@description This will get the hunger of a player ---@return number Framework.GetHunger = function() local hunger = Framework.GetPlayerMetaData("hunger") or 0 return math.floor((hunger) + 0.5) or 0 end ----This will get the thirst of a player +---@description This will get the thirst of a player ---@return number Framework.GetThirst = function() local thirst = Framework.GetPlayerMetaData("thirst") or 0 return math.floor((thirst) + 0.5) or 0 end ----This will get the players identifier (citizenid) etc. +---@description This will get the players identifier (citizenid) etc. ---@return string Framework.GetPlayerIdentifier = function() return Framework.GetPlayerData().citizenid end ----This will get the players name (first and last). +---@description This will get the players name (first and last). ---@return string ---@return string Framework.GetPlayerName = function() @@ -102,17 +101,18 @@ Framework.GetPlayerName = function() return playerData.charinfo.firstname, playerData.charinfo.lastname end ----Depricated : This will return the players job name, job label, job grade label and job grade level +---@description Depricated : This will return the players job name, job label, job grade label and job grade level ---@return string ---@return string ---@return string ---@return string Framework.GetPlayerJob = function() - local playerData = Framework.GetPlayerData() - return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level + print("This is depricated, please use Framework.GetPlayerJobData() instead.") + local jobData = Framework.GetPlayerJobData() + return jobData.jobName, jobData.jobLabel, jobData.gradeName, jobData.gradeRank end ----This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table +---@description This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table ---@return table Framework.GetPlayerJobData = function() local playerData = Framework.GetPlayerData() @@ -128,13 +128,13 @@ Framework.GetPlayerJobData = function() } end ----This will return the players inventory as a table in the ox_inventory style flormat. ----@return table +---@description This is an internal function used as a fallback, please use the Inventory.GetPlayerInventory instead. +---@return table {name, label, count, slot, metadata, stack, close, weight} Framework.GetPlayerInventory = function() return Framework.GetPlayerData().items end ----This will return the players money by type, I recommend not useing this as its the client and not secure or to be trusted. +---@description This will return the players money by type, I recommend not useing this as its the client and not secure or to be trusted. ---Use case is for a ui or a menu I guess. ---@param _type string ---@return number @@ -143,64 +143,53 @@ Framework.GetAccountBalance = function(_type) if not player then return 0 end local account = player.money if _type == 'money' then _type = 'cash' end - return account[_type] or 0 + local balance = account[_type] or 0 + if balance <= 0 then return 0 end + return balance end ----This will return the vehicle properties for the specified vehicle. ----@param vehicle number ----@return table -Framework.GetVehicleProperties = function(vehicle) - if not vehicle or not DoesEntityExist(vehicle) then return {} end - local vehicleProps = lib.getVehicleProperties(vehicle) - return vehicleProps or {} -end - ----This will set the vehicle properties for the specified vehicle. ----@param vehicle number ----@param properties table ----@return boolean -Framework.SetVehicleProperties = function(vehicle, properties) - if not vehicle or not DoesEntityExist(vehicle) then return false end - if not properties then return false end - if NetworkGetEntityIsNetworked(vehicle) then - local vehNetID = NetworkGetNetworkIdFromEntity(vehicle) - local entOwner = GetPlayerServerId(NetworkGetEntityOwner(vehNetID)) - if entOwner ~= GetPlayerServerId(PlayerId()) then - NetworkRequestControlOfEntity(vehicle) - local count = 0 - while not NetworkHasControlOfEntity(vehicle) and count < 3000 do - Wait(1) - count = count + 1 - end - end - end - return true, lib.setVehicleProperties(vehicle, properties) -end - ----This will return the item count for the specified item in the players inventory. ----@param item string ----@return number +---@description This is an internal function used as a fallback, please use the Inventory.GetItemCount instead. +--- @param item string +--- @return number Framework.GetItemCount = function(item) - -- This seems to be exclusively for ox_inventory, if other inventories are used, they need to be bridged in the inventory module. Until then we will return 0 and a print. - return 0, print("Community_bridge:WARN: GetItemCount is not implemented for this framework, please use the inventory module to get the item count. If you are using a diffrent inventory please let us know so we can bridge it and have less nonsense.") + return 0, print("Qbox has not implemented GetItemCount for this framework. Please ensure the inventory you are using is supported and start order is correct.") end ----This will get a players dead status. +---@description This will return the item data for the specified item. +--- @param item string +--- @return table {name, label, stack, weight, description, image} +Framework.GetItemInfo = function(item) + return {}, print("Qbox has not implemented GetItemInfo for this framework. Please ensure the inventory you are using is supported and start order is correct.") +end + +---@description Will return boolean if the player has the item. +---@param item string +---@param requiredCount number (optional) +---@return boolean +Framework.HasItem = function(item, requiredCount) + return false, print("Qbox has not implemented HasItem for this framework, Please ensure the inventory you are using is supported and start order is correct.") +end + +---@description This will get a players dead status. ---@return boolean Framework.GetIsPlayerDead = function() local playerData = Framework.GetPlayerData() return playerData.metadata["isdead"] or playerData.metadata["inlaststand"] end +---@description Event handler for when player is loaded in QBX Core framework RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() Wait(1500) TriggerEvent('community_bridge:Client:OnPlayerLoaded') end) +---@description Event handler for when player is unloaded in QBX Core framework RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() TriggerEvent('community_bridge:Client:OnPlayerUnload') end) +---@description Event handler for when player job is updated in QBX Core framework +---@param data table Job data containing name, label, and grade information RegisterNetEvent('QBCore:Client:OnJobUpdate', function(data) TriggerEvent('community_bridge:Client:OnPlayerJobUpdate', data.name, data.label, data.grade.name, data.grade.level) end) diff --git a/modules/framework/qbx_core/server.lua b/modules/framework/qbx_core/server.lua index bf29bfe..a887481 100644 --- a/modules/framework/qbx_core/server.lua +++ b/modules/framework/qbx_core/server.lua @@ -5,27 +5,27 @@ Framework = Framework or {} local QBox = exports.qbx_core ----Returns the name of the framework being used (if a supported framework). +---@description Returns the name of the framework being used (if a supported framework). ---@return string Framework.GetFrameworkName = function() return 'qbx_core' end ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Framework.GetResourceName = function() return 'qbx_core' end ----This will return if the player is an admin in the framework. ----@param src any +---@description This will return if the player is an admin in the framework. +---@param src number ---@return boolean Framework.GetIsFrameworkAdmin = function(src) if not src then return false end return IsPlayerAceAllowed(src, 'admin') end ----Returns the player date of birth. +---@description Returns the player date of birth. ---@param src number ---@return string|nil Framework.GetPlayerDob = function(src) @@ -35,7 +35,7 @@ Framework.GetPlayerDob = function(src) return playerData.charinfo.birthdate end ---- Returns the player data of the specified source. +---@description Returns the player data of the specified source. ---@param src any ---@return table | nil Framework.GetPlayer = function(src) @@ -44,13 +44,13 @@ Framework.GetPlayer = function(src) return player end ----Returns a table of the jobs in the framework. +---@description Returns a table of the jobs in the framework. ---@return table Framework.GetFrameworkJobs = function() return QBox.GetJobs() end ----Returns the citizen ID of the player. +---@description Returns the citizen ID of the player. ---@param src number ---@return string | boolean | nil Framework.GetPlayerIdentifier = function(src) @@ -61,7 +61,7 @@ Framework.GetPlayerIdentifier = function(src) return playerData.citizenid end ----This will return a table of all logged in players +---@description This will return a table of all logged in players ---@return table Framework.GetPlayers = function() local players = QBox:GetQBPlayers() @@ -72,7 +72,7 @@ Framework.GetPlayers = function() return playerList end ----Returns the first and last name of the player. +---@description Returns the first and last name of the player. ---@param src number ---@return string | nil ---@return string | nil @@ -83,63 +83,110 @@ Framework.GetPlayerName = function(src) return playerData.charinfo.firstname, playerData.charinfo.lastname end ----Returns a table of items matching the specified name and if passed metadata from the player's inventory. +---@description Adds the specified item to the player's inventory. +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +---@param src number +---@param item string +---@param amount number +---@param slot number +---@param metadata table +---@return boolean | nil +Framework.AddItem = function(src, item, amount, slot, metadata) + local player = Framework.GetPlayer(src) + if not player then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "add", item = item, count = amount, slot = slot, metadata = metadata }) + return player.Functions.AddItem(item, amount, slot, metadata) +end + +---@description Removes the specified item from the player's inventory. +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +---@param src number +---@param item string +---@param amount number +---@param slot number +---@param metadata table +---@return boolean | nil +Framework.RemoveItem = function(src, item, amount, slot, metadata) + local player = Framework.GetPlayer(src) + if not player then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "remove", item = item, count = amount, slot = slot, metadata = metadata }) + return player.Functions.RemoveItem(item, amount, slot) +end + +---@description Sets the metadata for the specified item in the player's inventory. +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. +---@param src number +---@param item string +---@param slot number +---@param metadata table +---@return boolean | nil +Framework.SetMetadata = function(src, item, slot, metadata) + local player = Framework.GetPlayer(src) + if not player then return false end + player.Functions.RemoveItem(item, 1, slot) + return player.Functions.AddItem(item, 1, slot, metadata) +end + +---@description Returns a table of items matching the specified name and if passed metadata from the player's inventory. +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. ---returns {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} ---@param src number ---@param item string ---@param metadata table ----@return table|nil +---@return table|nil {name = v.name, count = v.amount, metadata = v.info, slot = v.slot} Framework.GetItem = function(src, item, metadata) local player = Framework.GetPlayer(src) - if not player then return end - local playerInventory = player.PlayerData.items + if not player then return { } end local repackedTable = {} - for _, v in pairs(playerInventory) do + for _, v in pairs(player.PlayerData.items) do if v.name == item and (not metadata or v.info == metadata) then - table.insert(repackedTable, { + repackedTable[#repackedTable + 1] = { name = v.name, - count = v.amount, - metadata = v.info, + count = v.amount or v.count, + metadata = v.info or v.metadata, slot = v.slot, - }) + } end end return repackedTable end ----Returns the count of items matching the specified name and if passed metadata from the player's inventory. +---@description Returns the count of items matching the specified name and if passed metadata from the player's inventory. +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. ---@param src number ---@param item string ---@param metadata table ---@return number | nil Framework.GetItemCount = function(src, item, metadata) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return 0 end local playerInventory = player.PlayerData.items local count = 0 for _, v in pairs(playerInventory) do if v.name == item and (not metadata or v.info == metadata) then - count = count + v.amount + count = count + (v.amount or v.count) end end return count end ----Returns boolean if the player has the specified item in their inventory. +---@description Returns boolean if the player has the specified item in their inventory. +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. ---@param src number ---@param item string ---@return boolean Framework.HasItem = function(src, item) - local getCount = Framework.GetItemCount(src, item, nil) + local getCount = Framework.GetItemCount(src, item) return getCount > 0 end ----Returns the entire inventory of the player as a table. +---@description Returns the entire inventory of the player as a table. +---This is an internal function and should not be used outside of bridge, use the Inventory module instead when dealing with items. ---@param src number ---@return table | nil Framework.GetPlayerInventory = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return { } end local playerItems = player.PlayerData.items local repackedTable = {} for _, v in pairs(playerItems) do @@ -153,7 +200,7 @@ Framework.GetPlayerInventory = function(src) return repackedTable end ----Adds the specified metadata key and number value to the player's data. +---@description Adds the specified metadata key and number value to the player's data. ---@param src number ---@param metadata string ---@param value string @@ -165,7 +212,7 @@ Framework.SetPlayerMetadata = function(src, metadata, value) return true end ----Gets the specified metadata key to the player's data. +---@description Gets the specified metadata key to the player's data. ---@param src number ---@param metadata string ---@return string | boolean | nil @@ -176,7 +223,7 @@ Framework.GetPlayerMetadata = function(src, metadata) return playerData.metadata[metadata] or false end ----Adds the specified value to the player's stress level and updates the client HUD. +---@description Adds the specified value to the player's stress level and updates the client HUD. ---@param src number ---@param value number ---@return number | nil @@ -190,7 +237,7 @@ Framework.AddStress = function(src, value) return newStress end ----Removes the specified value from the player's stress level and updates the client HUD. +---@description Removes the specified value from the player's stress level and updates the client HUD. ---@param src number ---@param value number ---@return number | nil @@ -204,7 +251,7 @@ Framework.RemoveStress = function(src, value) return newStress end ----Adds the specified value from the player's hunger level. +---@description Adds the specified value from the player's hunger level. ---@param src number ---@param value number ---@return number | nil @@ -218,7 +265,7 @@ Framework.AddHunger = function(src, value) return newHunger end ----Adds the specified value from the player's thirst level. +---@description Adds the specified value from the player's thirst level. ---@param src number ---@param value number ---@return number | nil @@ -232,28 +279,28 @@ Framework.AddThirst = function(src, value) return newThirst end ----This will return the players hunger level. +---@description This will return the players hunger level. ---@param src number ---@return number | nil Framework.GetHunger = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return 0 end local playerData = player.PlayerData local newHunger = (playerData.metadata.hunger or 0) return math.floor((newHunger) + 0.5) or 0 end ----This will return a boolean if the player is dead or in last stand. +---@description This will return a boolean if the player is dead or in last stand. ---@param src number ---@return boolean|nil Framework.GetIsPlayerDead = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return false end local playerData = player.PlayerData return playerData.metadata.isdead or false end ----This will revive a player, if the player is dead or in last stand. +---@description This will revive a player, if the player is dead or in last stand. ---@param src number ---@return boolean Framework.RevivePlayer = function(src) @@ -263,18 +310,18 @@ Framework.RevivePlayer = function(src) return true end ----This will return the players thirst level. +---@description This will return the players thirst level. ---@param src number ---@return number| nil Framework.GetThirst = function(src) local player = Framework.GetPlayer(src) - if not player then return end + if not player then return 0 end local playerData = player.PlayerData local newThirst = (playerData.metadata.thirst or 0) return math.floor((newThirst) + 0.5) or 0 end ----Returns the phone number of the player. +---@description Returns the phone number of the player. ---@param src number ---@return string | nil Framework.GetPlayerPhone = function(src) @@ -284,7 +331,7 @@ Framework.GetPlayerPhone = function(src) return playerData.charinfo.phone end ----Returns the gang name of the player. +---@description Returns the gang name of the player. ---@param src number ---@return string | nil Framework.GetPlayerGang = function(src) @@ -292,14 +339,15 @@ Framework.GetPlayerGang = function(src) return player.gang.name end ----This will get a table of player sources that have the specified job name. +---@description This will get a table of player sources that have the specified job name. ---@param job string ---@return table Framework.GetPlayersByJob = function(job) return Framework.GetPlayerSourcesByJob(job) or {} end ----Depricated: Returns the job name, label, grade name, and grade level of the player. +---@description Depricated: Returns the job name, label, grade name, and grade level of the player. +---Please use GetPlayerJobData instead. ---@param src number ---@return string | string | string | number | nil ---@return string | string | string | number | nil @@ -309,10 +357,11 @@ Framework.GetPlayerJob = function(src) local player = Framework.GetPlayer(src) if not player then return end local playerData = player.PlayerData + print("This function is depricated, please use GetPlayerJobData instead.") return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level end ----This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table +---@description This will return the players job name, job label, job grade label job grade level, boss status, and duty status in a table ---@param src number ---@return table | nil Framework.GetPlayerJobData = function(src) @@ -331,7 +380,7 @@ Framework.GetPlayerJobData = function(src) } end ----Sets the player's job to the specified name and grade. +---@description Sets the player's job to the specified name and grade. ---@param src number ---@param name string ---@param grade string @@ -342,7 +391,7 @@ Framework.SetPlayerJob = function(src, name, grade) return player.Functions.SetJob(name, grade) end ----This will toggle the duty status of the player. +---@description This will toggle the duty status of the player. ---@param src number ---@param status boolean Framework.SetPlayerDuty = function(src, status) @@ -353,7 +402,7 @@ Framework.SetPlayerDuty = function(src, status) TriggerEvent('QBCore:Server:SetDuty', src, player.PlayerData.job.onduty) end ----Returns the players duty status. +---@description Returns the players duty status. ---@param src number ---@return boolean | nil Framework.GetPlayerDuty = function(src) @@ -364,7 +413,7 @@ Framework.GetPlayerDuty = function(src) return true end ----Adds the specified amount to the player's account balance of the specified type. +---@description Adds the specified amount to the player's account balance of the specified type. ---@param src number ---@param _type string ---@param amount number @@ -373,10 +422,11 @@ Framework.AddAccountBalance = function(src, _type, amount) local player = Framework.GetPlayer(src) if not player then return end if _type == 'money' then _type = 'cash' end + if amount <= 0 then return false end return player.Functions.AddMoney(_type, amount) end ----Removes the specified amount from the player's account balance of the specified type. +---@description Removes the specified amount from the player's account balance of the specified type. ---@param src number ---@param _type string ---@param amount number @@ -385,10 +435,11 @@ Framework.RemoveAccountBalance = function(src, _type, amount) local player = Framework.GetPlayer(src) if not player then return end if _type == 'money' then _type = 'cash' end + if amount <= 0 then return false end return player.Functions.RemoveMoney(_type, amount) end ----Returns the player's account balance of the specified type. +---@description Returns the player's account balance of the specified type. ---@param src number ---@param _type string ---@return number | nil @@ -397,51 +448,12 @@ Framework.GetAccountBalance = function(src, _type) if not player then return end local playerData = player.PlayerData if _type == 'money' then _type = 'cash' end - return playerData.money[_type] + local balance = playerData.money[_type] or 0 + if balance <= 0 then return 0 end + return balance end ----Adds the specified item to the player's inventory. ----@param src number ----@param item string ----@param amount number ----@param slot number ----@param metadata table ----@return boolean | nil -Framework.AddItem = function(src, item, amount, slot, metadata) - local player = Framework.GetPlayer(src) - if not player then return end - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "add", item = item, count = amount, slot = slot, metadata = metadata }) - return player.Functions.AddItem(item, amount, slot, metadata) -end - ----Removes the specified item from the player's inventory. ----@param src number ----@param item string ----@param amount number ----@param slot number ----@param metadata table ----@return boolean | nil -Framework.RemoveItem = function(src, item, amount, slot, metadata) - local player = Framework.GetPlayer(src) - if not player then return end - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, { action = "remove", item = item, count = amount, slot = slot, metadata = metadata }) - return player.Functions.RemoveItem(item, amount, slot) -end - ----Sets the metadata for the specified item in the player's inventory. ----@param src number ----@param item string ----@param slot number ----@param metadata table ----@return boolean | nil -Framework.SetMetadata = function(src, item, slot, metadata) - local player = Framework.GetPlayer(src) - if not player then return end - player.Functions.RemoveItem(item, 1, slot) - return player.Functions.AddItem(item, 1, slot, metadata) -end - ----Returns a table of owned vehicles for the player. format is {vehicle = vehicle, plate = plate} +---@description Returns a table of owned vehicles for the player. format is {vehicle = vehicle, plate = plate} ---@param src number ---@return table Framework.GetOwnedVehicles = function(src) @@ -456,7 +468,7 @@ Framework.GetOwnedVehicles = function(src) return vehicles end ----Registers a usable item with a callback function. +---@description Registers a usable item with a callback function. ---@param itemName string ---@param cb function ---@return function @@ -470,6 +482,8 @@ Framework.RegisterUsableItem = function(itemName, cb) return QBox:CreateUseableItem(itemName, func) end +---@description Event handler for when a player is loaded in QBX Core framework +---@param src number RegisterNetEvent("QBCore:Server:OnPlayerLoaded", function(src) src = src or source TriggerEvent("community_bridge:Server:OnPlayerLoaded", src) @@ -478,17 +492,23 @@ RegisterNetEvent("QBCore:Server:OnPlayerLoaded", function(src) Framework.AddJobCount(src, jobData.jobName) end) +---@description Event handler for when a player is unloaded in QBX Core framework +---@param src number RegisterNetEvent("QBCore:Server:OnPlayerUnload", function(src) src = src or source TriggerEvent("community_bridge:Server:OnPlayerUnload", src) end) +---@description Event handler for when a player's job is updated in QBX Core framework +---@param src number +---@param job table RegisterNetEvent("QBCore:Server:OnJobUpdate", function(src, job) src = src or source if not job then return end TriggerEvent("community_bridge:Server:OnPlayerJobChange", src, job.name) end) +---@description Event handler for when a player disconnects from the server AddEventHandler("playerDropped", function() local src = source TriggerEvent("community_bridge:Server:OnPlayerUnload", src) diff --git a/modules/fuel/_default/client.lua b/modules/fuel/_default/client.lua index 53748be..28c6ae5 100644 --- a/modules/fuel/_default/client.lua +++ b/modules/fuel/_default/client.lua @@ -2,14 +2,13 @@ Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return 'default' end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -17,7 +16,7 @@ Fuel.GetFuel = function(vehicle) return GetVehicleFuelLevel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/bigDaddy-Fuel/client.lua b/modules/fuel/bigDaddy-Fuel/client.lua index 56b1721..c3569d2 100644 --- a/modules/fuel/bigDaddy-Fuel/client.lua +++ b/modules/fuel/bigDaddy-Fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "BigDaddy-Fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports['BigDaddy-Fuel']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/cdn-fuel/client.lua b/modules/fuel/cdn-fuel/client.lua index c4fd02f..f83bb4b 100644 --- a/modules/fuel/cdn-fuel/client.lua +++ b/modules/fuel/cdn-fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "cdn-fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports['cdn-fuel']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/esx-sna-fuel/client.lua b/modules/fuel/esx-sna-fuel/client.lua index 87eefe7..7ba9f75 100644 --- a/modules/fuel/esx-sna-fuel/client.lua +++ b/modules/fuel/esx-sna-fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "esx-sna-fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports['esx-sna-fuel']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/lc_fuel/client.lua b/modules/fuel/lc_fuel/client.lua index 7471143..aae2689 100644 --- a/modules/fuel/lc_fuel/client.lua +++ b/modules/fuel/lc_fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "lc_fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports["lc_fuel"]:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/legacyfuel/client.lua b/modules/fuel/legacyfuel/client.lua index 49a875c..dd17acc 100644 --- a/modules/fuel/legacyfuel/client.lua +++ b/modules/fuel/legacyfuel/client.lua @@ -4,14 +4,13 @@ if GetResourceState(resourceName) == 'missing' then return end if GetResourceState("qb-fuel") == 'started' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -19,7 +18,7 @@ Fuel.GetFuel = function(vehicle) return exports['LegacyFuel']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/okokGasStation/client.lua b/modules/fuel/okokGasStation/client.lua index f71a6c5..b2fc8c9 100644 --- a/modules/fuel/okokGasStation/client.lua +++ b/modules/fuel/okokGasStation/client.lua @@ -3,14 +3,13 @@ local resourceName = "okokGasStation" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports['okokGasStation']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/ox_fuel/client.lua b/modules/fuel/ox_fuel/client.lua index c643b95..5b7cb92 100644 --- a/modules/fuel/ox_fuel/client.lua +++ b/modules/fuel/ox_fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "ox_fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return Entity(vehicle).state.fuel end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/ps-fuel/client.lua b/modules/fuel/ps-fuel/client.lua index 520a6b6..e5c9d7b 100644 --- a/modules/fuel/ps-fuel/client.lua +++ b/modules/fuel/ps-fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "ps-fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports["ps-fuel"]:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/qb-fuel/client.lua b/modules/fuel/qb-fuel/client.lua index 8c57932..cb741cd 100644 --- a/modules/fuel/qb-fuel/client.lua +++ b/modules/fuel/qb-fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "qb-fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports['qb-fuel']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/qs-fuelstations/client.lua b/modules/fuel/qs-fuelstations/client.lua index 84e9e93..e6a2364 100644 --- a/modules/fuel/qs-fuelstations/client.lua +++ b/modules/fuel/qs-fuelstations/client.lua @@ -3,14 +3,13 @@ local resourceName = "qs-fuelstations" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports['qs-fuelstations']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/renewed-Fuel/client.lua b/modules/fuel/renewed-Fuel/client.lua index c5c0b90..0197cbc 100644 --- a/modules/fuel/renewed-Fuel/client.lua +++ b/modules/fuel/renewed-Fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "Renewed-Fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -18,7 +17,7 @@ Fuel.GetFuel = function(vehicle) return exports['Renewed-Fuel']:GetFuel(vehicle) end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/ti_fuel/client.lua b/modules/fuel/ti_fuel/client.lua index 005a078..fee140d 100644 --- a/modules/fuel/ti_fuel/client.lua +++ b/modules/fuel/ti_fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "ti_fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -19,7 +18,7 @@ Fuel.GetFuel = function(vehicle) return level end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/fuel/x-fuel/client.lua b/modules/fuel/x-fuel/client.lua index 712c5de..0468f47 100644 --- a/modules/fuel/x-fuel/client.lua +++ b/modules/fuel/x-fuel/client.lua @@ -3,14 +3,13 @@ local resourceName = "x-fuel" if GetResourceState(resourceName) == 'missing' then return end Fuel = Fuel or {} ----Returns the name of the active fuel resource. ----If no supported resource is found, "default" will be returned. +---@description Returns the name of the active fuel resource. ---@return string Fuel.GetResourceName = function() return resourceName end ----Returns the current fuel level of a vehicle. +---@description Returns the current fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@return number The vehicle fuel level. Fuel.GetFuel = function(vehicle) @@ -19,7 +18,7 @@ Fuel.GetFuel = function(vehicle) return level end ----Sets the fuel level of a vehicle. +---@description Sets the fuel level of a vehicle. ---@param vehicle number The vehicle entity handle. ---@param fuel number The fuel level to assign. ---@param type? string The fuel type, used only in ti_fuel. (default: RON91) diff --git a/modules/inventory/_default/client.lua b/modules/inventory/_default/client.lua index 4ff2b77..a0353cd 100644 --- a/modules/inventory/_default/client.lua +++ b/modules/inventory/_default/client.lua @@ -1,40 +1,41 @@ ---@diagnostic disable: duplicate-set-field Inventory = Inventory or {} ----Return the item info in oxs format, {name, label, stack, weight, description, image} +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "default" +end + +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) return Framework.GetItemInfo(item) end ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "default" -end - ----Will return boolean if the player has the item. +---@description Will return boolean if the player has the item. ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(item) - return Framework.HasItem(item) +Inventory.HasItem = function(item, requiredCount) + return Framework.HasItem(item, requiredCount) end ----This will return th count of the item in the players inventory, if not found will return 0. +---@description This will return their count of the item in the players inventory, if not found will return 0. ---@param item string ---@return number Inventory.GetItemCount = function(item) return Framework.GetItemCount(item) end ----This will return the players inventory in the format of {name, label, count, slot, metadata} +---@description This will return the players inventory in the format of {name, label, count, slot, metadata} ---@return table Inventory.GetPlayerInventory = function() return Framework:GetPlayerInventory() end ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -42,8 +43,7 @@ Inventory.GetImagePath = function(item) return "https://avatars.githubusercontent.com/u/47620135" end ----This will remove the file extension from the item name if present. ----example: "item.png" will become "item" +---@description This will remove the file extension from the item name if present. ---@param item string ---@return string Inventory.StripPNG = function(item) @@ -53,8 +53,7 @@ Inventory.StripPNG = function(item) return item end ----This will remove the file extension from the item name if present. ----example: "item.webp" will become "item" +---@description This will remove the file extension from the item name if present. ---@param item string ---@return string Inventory.StripWebp = function(item) @@ -64,8 +63,8 @@ Inventory.StripWebp = function(item) return item end ----This will return the entire items table from the inventory. ----@return table +---@description This will return the entire items table from the inventory. +---@return table Inventory.Items = function() if not Framework.Shared or not Framework.Shared.Items then local itemList = Framework.ItemList() or { Items = {} } @@ -74,6 +73,4 @@ Inventory.Items = function() return Framework.Shared.Items end - - return Inventory \ No newline at end of file diff --git a/modules/inventory/_default/server.lua b/modules/inventory/_default/server.lua index 7075b84..c80ae9b 100644 --- a/modules/inventory/_default/server.lua +++ b/modules/inventory/_default/server.lua @@ -1,7 +1,14 @@ ---@diagnostic disable: duplicate-set-field Inventory = Inventory or {} +Inventory.Stashes = Inventory.Stashes or {} ----This will add an item, and return true or false based on success +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "default" +end + +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number @@ -9,18 +16,13 @@ Inventory = Inventory or {} ---@param metadata table ---@return boolean Inventory.AddItem = function(src, item, count, slot, metadata) + local success = Framework.AddItem(src, item, count, slot, metadata) + if not success then return false end TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return Framework.AddItem(src, item, count, slot, metadata) + return success end ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "default" -end - - ----This will remove an item, and return true or false based on success +---@description This will remove an item, and return true or false based on success ---@param src number ---@param item string ---@param count number @@ -29,36 +31,36 @@ end ---@return boolean Inventory.RemoveItem = function(src, item, count, slot, metadata) item = type(item) == "table" and item.name or item + local success = Framework.RemoveItem(src, item, count, slot, metadata) + if not success then return false end TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return Framework.RemoveItem(src, item, count, slot, metadata) + return success end ----This will add items to a trunk, and return true or false based on success +---@description This will add items to a trunk, and return true or false based on success ---@param identifier string ---@param items table ---@return boolean Inventory.AddTrunkItems = function(identifier, items) - return false, Prints.Error("This Inventory Has Not Been Bridged For A Trunk Feature.") + return false, print("This Inventory Has Not Been Bridged For A Trunk Feature.") end ----This will clear the specified inventory, will return success or failure. +---@description This will clear the specified inventory, will always return true unless a value isnt passed correctly. ---@param id string ---@return boolean Inventory.ClearStash = function(id, _type) - if type(id) ~= "string" then return false end if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return false, Prints.Error("This Inventory Has Not Been Bridged For A ClearStash Feature.") + return false, print("This Inventory Has Not Been Bridged For A ClearStash Feature.") end ----This will return a table with the item info, ----example: {name = "coolitem", label = "a cool item name", stack = false, weight = 1000, description = "some item description", image = "coolitem.png"} +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) return Framework.GetItemInfo(item) end ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() if not Framework.Shared or not Framework.Shared.Items then @@ -68,35 +70,31 @@ Inventory.Items = function() return Framework.Shared.Items end ----This will return the count of the item in the players inventory, if not found will return 0. ----if metadata is passed it will find the matching items count. ----example: 0 +---@description This will return the count of the item in the players inventory, if not found will return 0. ---@param src number ---@param item string ----@param metadata table +---@param metadata table (optional) ---@return number Inventory.GetItemCount = function(src, item, metadata) return Framework.GetItemCount(src, item, metadata) end ----This wil return the players inventory. ----example: {{weight = 10, name = "farts", metadata = {description = "this is a description"}, slot = 1, label = "stinky", count = 1}, {weight = 10, name = "farts", metadata = {description = "this is a description"}, slot = 2, label = "stinky", count = 1}} +---@description This wil return the players inventory. ---@param src number ---@return table Inventory.GetPlayerInventory = function(src) return Framework.GetPlayerInventory(src) end ----Returns the specified slot data as a table. ----example {weight = 10, name = "farts", metadata = {description = "this is a description"}, slot = 1, label = "stinky", count = 1} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) return Framework.GetItemBySlot(src, slot) end ----This will set the metadata of an item in the inventory. +---@description This will set the metadata of an item in the inventory. ---@param src number ---@param item string ---@param slot number @@ -106,74 +104,65 @@ Inventory.SetMetadata = function(src, item, slot, metadata) return Framework.SetMetadata(src, item, slot, metadata) end ----This will open the specified stash for the src passed. +---@description This will open the specified stash for the src passed. ---@param src number ----@param _type string ----@param id number|string +---@param _type string "stash", "trunk", "glovebox" +---@param id string ---@return nil Inventory.OpenStash = function(src, _type, id) - _type = _type or "stash" - local tbl = Inventory.Stashes[id] - return false, Prints.Error("This Inventory Has Not Been Bridged For A Stash Feature.") + return false, print("This Inventory Has Not Been Bridged For A Stash Feature.") end ----This will register a stash +---@description This will register a stash ---@param id number|string ---@param label string ---@param slots number ---@param weight number ----@param owner string ----@param groups table ----@param coords table +---@param owner string (optional) +---@param groups table (optional) +---@param coords table (optional) ---@return boolean ---@return string|number Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } + Inventory.Stashes[id] = {id = id, label = label, slots = slots, weight = weight, owner = owner, groups = groups, coords = coords} return true, id end ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) - return Framework.HasItem(src, item) +Inventory.HasItem = function(src, item, requiredCount) + return Framework.HasItem(src, item, requiredCount) end ----This is to get if there is available space in the inventory, will return boolean. +---@description This is to get if there is available space in the inventory, will return boolean. ---@param src number ---@param item string ---@param count number ---@return boolean Inventory.CanCarryItem = function(src, item, count) - return false, Prints.Error("This Inventory Has Not Been Bridged For A CanCarryItem Feature.") + return true, print("This Inventory Has Not Been Bridged For A CanCarryItem Feature.") end ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean Inventory.UpdatePlate = function(oldplate, newplate) - return false, Prints.Error("This Inventory Has Not Been Bridged For A UpdatePlate Feature.") + return false, print("This Inventory Has Not Been Bridged For A UpdatePlate Feature.") end --- This will open the specified shop for the src passed. +---@description This will open the specified shop for the src passed. ---@param src number ---@param shopTitle string Inventory.OpenShop = function(src, shopTitle) return Bridge.Shops.OpenShop(src, shopTitle) end --- This will register a shop, if it already exists it will return true. +---@description This will register a shop, if it already exists it will return true. ---@param shopTitle string ---@param shopInventory table ---@param shopCoords table @@ -182,14 +171,14 @@ Inventory.RegisterShop = function(shopTitle, shopInventory, shopCoords, shopGrou return Bridge.Shops.CreateShop(shopTitle, shopInventory, shopCoords, shopGroups) end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) return "https://avatars.githubusercontent.com/u/47620135" end ----This will remove the file extension from the item name if present. +---@description This will remove the file extension from the item name if present. ---example: "item.png" will become "item" ---@param item string ---@return string @@ -200,7 +189,7 @@ Inventory.StripPNG = function(item) return item end ----This will remove the file extension from the item name if present. +---@description This will remove the file extension from the item name if present. ---example: "item.webp" will become "item" ---@param item string ---@return string @@ -211,8 +200,12 @@ Inventory.StripWebp = function(item) return item end +---@description Opens another player's inventory for inspection/interaction +---@param src number The source player who is opening the inventory +---@param targetSrc number The target player whose inventory is being opened +---@return boolean Inventory.OpenPlayerInventory = function(src, targetSrc) - return false, Prints.Error("OpenPlayerInventory is not implemented in this inventory, because of this we dont have a way to open a players inventory.") + return false, print("OpenPlayerInventory is not implemented in this inventory, because of this we dont have a way to open a players inventory.") end return Inventory \ No newline at end of file diff --git a/modules/inventory/codem-inventory/client.lua b/modules/inventory/codem-inventory/client.lua index 2fe7e66..048e24f 100644 --- a/modules/inventory/codem-inventory/client.lua +++ b/modules/inventory/codem-inventory/client.lua @@ -1,61 +1,60 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('codem-inventory') ~= 'started' then return end +if GetResourceState('codem-inventory') == 'missing' then return end Inventory = Inventory or {} local codem = exports['codem-inventory'] ----Return the item info in oxs format, {name, label, stack, weight, description, image} ----@param item string ----@return table -Inventory.GetItemInfo = function(item) - local itemData = codem:GetItemList(item) - if not itemData then return {} end - local image = itemData.image and Inventory.GetImagePath(itemData.image) or Inventory.GetImagePath(item) - return { - name = itemData.name or "Missing Name", - label = itemData.label or "Missing Label", - stack = itemData.unique or "false", - weight = itemData.weight or "0", - description = itemData.description or "none", - image = image, - } -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "codem-inventory" end - ----This will return the entire items table from the inventory. ----@return table -Inventory.Items = function() - return codem:GetItemList() +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} +---@param item string +---@return table +Inventory.GetItemInfo = function(item) + local itemData = Inventory.Items() + if not itemData or not itemData[item] then return {} end + local image = Inventory.GetImagePath(itemData[item].image) or Inventory.GetImagePath(item) + return { + name = itemData[item].name or "Missing Name", + label = itemData[item].label or "Missing Label", + stack = itemData[item].unique or "false", + weight = itemData[item].weight or "0", + description = itemData[item].description or "none", + image = image, + } end ----This will get the image path for this item, if not found will return placeholder. +---@description This will return the entire items table from the inventory. +---@return table +Inventory.Items = function() + return codem:GetItemList() or {} +end + +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) item = Inventory.StripPNG(item) - local file = LoadResourceFile("codem-inventory", string.format("html/images/%s.png", item)) - local imagePath = file and string.format("nui://codem-inventory/html/images/%s.png", item) + local file = LoadResourceFile("codem-inventory", string.format("html/itemimages/%s.png", item)) + local imagePath = file and string.format("nui://codem-inventory/html/itemimages/%s.png", item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----This will return the players inventory in the format of {name, label, count, slot, metadata} +---@description This will return the players inventory in the format of {name, label, count, slot, metadata} ---@return table Inventory.GetPlayerInventory = function() local items = {} - local inventory = codem:getUserInventory() + local inventory = codem:GetClientPlayerInventory() for _, v in pairs(inventory) do table.insert(items, { name = v.name, label = v.label, - count = v.amount, + count = v.amount or v.count, slot = v.slot, - metadata = v.info, + metadata = v.info or v.metadata or {}, stack = v.unique, close = v.useable, weight = v.weight @@ -64,9 +63,4 @@ Inventory.GetPlayerInventory = function() return items end -RegisterNetEvent('community_bridge:client:codem-inventory:openStash', function(id, data) - if source ~= 65535 then return end - TriggerServerEvent('codem-inventory:server:openstash', id, data.slots, data.weight, data.label) -end) - return Inventory \ No newline at end of file diff --git a/modules/inventory/codem-inventory/server.lua b/modules/inventory/codem-inventory/server.lua index a0b3e0a..8e93754 100644 --- a/modules/inventory/codem-inventory/server.lua +++ b/modules/inventory/codem-inventory/server.lua @@ -1,29 +1,44 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('codem-inventory') ~= 'started' then return end +if GetResourceState('codem-inventory') == 'missing' then return end Inventory = Inventory or {} Inventory.Stashes = Inventory.Stashes or {} local codem = exports['codem-inventory'] ----This will add an item, and return true or false based on success ----@param src number ----@param item string ----@param count number ----@param slot number ----@param metadata table ----@return boolean -Inventory.AddItem = function(src, item, count, slot, metadata) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return codem:AddItem(src, item, count, slot, metadata) -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "codem-inventory" end +---@description This will add an item, and return true or false based on success +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Inventory.AddItem = function(src, item, count, slot, metadata) + local success = codem:AddItem(src, item, count, slot, metadata) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) + return success +end + +---@description Internal function to search for items with specific metadata in player inventory +---@param src number +---@param metadata table +---@return boolean, number|nil +local function runMetadataSearch(src, metadata) + local inv = Framework.GetPlayerInventory(src) or {} + for _, v in pairs(inv) do + if v.metadata and v.metadata == metadata then + return true, v.slot + end + end + return false +end ---This will remove an item, and return true or false based on success ---@param src number @@ -33,33 +48,48 @@ end ---@param metadata table ---@return boolean Inventory.RemoveItem = function(src, item, count, slot, metadata) + if metadata then + local found, foundSlot = runMetadataSearch(src, metadata) + if found then slot = foundSlot end + end + local success = codem:RemoveItem(src, item, count, slot) + if not success then return false end TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return codem:RemoveItem(src, item, count, slot) + return success end ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) - local itemData = codem:GetItemList(item) - if not itemData then return {} end + local itemData = Inventory.Items() + if not itemData or not itemData[item] then return {} end return { - name = itemData.name or "Missing Name", - label = itemData.label or "Missing Label", - stack = itemData.unique or "false", - weight = itemData.weight or "0", - description = itemData.description or "none", - image = itemData.image or Inventory.GetImagePath(item), + name = itemData[item].name or "Missing Name", + label = itemData[item].label or "Missing Label", + stack = itemData[item].unique or "false", + weight = itemData[item].weight or "0", + description = itemData[item].description or "none", + image = itemData[item].image or Inventory.GetImagePath(item), } end ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() - return codem:GetItemList() + return codem:GetItemList() or {} end ----This wil return the players inventory. +---@description This will return the count of the item in the players inventory, if not found will return 0. +---@param src number +---@param item string +---@param metadata table (optional) +---@return number +Inventory.GetItemCount = function(src, item, metadata) + return codem:GetItemsTotalAmount(src, item) or 0 +end + +---@description This wil return the players inventory. ---@param src number ---@return table Inventory.GetPlayerInventory = function(src) @@ -69,35 +99,34 @@ Inventory.GetPlayerInventory = function(src) for _, v in pairs(playerItems) do table.insert(repackedTable, { name = v.name, - count = v.amount, - metadata = v.info, + count = v.amount or v.count, + metadata = v.info or v.metadata or {}, slot = v.slot, }) end return repackedTable end ----Returns the specified slot data as a table. ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) local slotData = codem:GetItemBySlot(src, slot) if not slotData then return {} end return { - name = v.name, - label = v.label or v.name, - weight = v.weight, - slot = v.slot, - count = v.amount or v.count, - metadata = v.info or v.metadata, - stack = v.unique, - description = v.description + name = slotData.name, + label = slotData.label or slotData.name, + weight = slotData.weight, + slot = slotData.slot, + count = slotData.amount or slotData.count, + metadata = slotData.info or slotData.metadata or {}, + stack = slotData.unique or false, + description = slotData.description } end ----This will set the metadata of an item in the inventory. +---@description This will set the metadata of an item in the inventory. ---@param src number ---@param item string ---@param slot number @@ -107,103 +136,57 @@ Inventory.SetMetadata = function(src, item, slot, metadata) return codem:SetItemMetadata(src, slot, metadata) end ----This will open the specified stash for the src passed. ----@param src number ----@param _type string ----@param id number||string ----@return nil -Inventory.OpenStash = function(src, _type, id) - _type = _type or "stash" - local tbl = Inventory.Stashes[id] - TriggerClientEvent('community_bridge:client:codem-inventory:openStash', src, id, { label = tbl.label, slots = tbl.slots, weight = tbl.weight }) -end - - ----This will register a stash ----@param id number|string ----@param label string ----@param slots number ----@param weight number ----@param owner string ----@param groups table ----@param coords table ----@return boolean ----@return string|number -Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) - if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } - return true, id -end - ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) - return codem:HasItem(src, item, 1) +Inventory.HasItem = function(src, item, requiredCount) + return codem:HasItem(src, item, requiredCount or 1) end ----This is to get if there is available space in the inventory, will return boolean. ----@param src number ----@param item string ----@param count number ----@return boolean -Inventory.CanCarryItem = function(src, item, count) - return true -end - ----This will add items to a trunk, and return true or false based on success ----If a trunk with the identifier does not exist, it will create one with default values. ----@param identifier string ----@param items table ----@return boolean -Inventory.AddTrunkItems = function(identifier, items) - if type(items) ~= "table" then return false end - return false, print("AddItemsToTrunk is not implemented in codem-inventory, because of this we dont have a way to add items to a trunk.") -end - ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. +---@description This will clear the specified inventory, will always return true unless a value isnt passed correctly. ---@param id string +---@param _type string unused with ox_inventory ---@return boolean Inventory.ClearStash = function(id, _type) if type(id) ~= "string" then return false end if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return false, print("ClearInventory is not implemented in codem-inventory, because of this we dont have a way to clear a stash.") + codem:UpdateStash(id, {}) + return true end ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ----@param oldplate string ----@param newplate string +---@description This will add items to a stash, and return true or false based on success +---@param id string +---@param items table {item, count, metadata} ---@return boolean -Inventory.UpdatePlate = function(oldplate, newplate) - return false, print("Unable to update plate for codem-inventory, I do not have access to a copy of this inventory to bridge the feature.") +Inventory.AddStashItems = function(id, items) + if type(items) ~= "table" then return false end + local repack = {} + for _, v in pairs(items) do + table.insert(repack, { + item = v.item, + amount = v.count or v.amount, + info = v.metadata or v.info or {}, + unique = v.unique or v.stack or false, + description = v.description or "none", + weight = Inventory.GetItemInfo(v.item).weight or 0, + type = 'item', + slot = #repack + 1, + }) + end + codem:UpdateStash(id, repack) + return true end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) item = Inventory.StripPNG(item) - local file = LoadResourceFile("codem-inventory", string.format("html/images/%s.png", item)) - local imagePath = file and string.format("nui://codem-inventory/html/images/%s.png", item) + local file = LoadResourceFile("codem-inventory", string.format("html/itemimages/%s.png", item)) + local imagePath = file and string.format("nui://codem-inventory/html/itemimages/%s.png", item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end -Inventory.OpenPlayerInventory = function(src, target) - assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end - exports['codem-inventory']:OpenInventory(src, target) -end - - return Inventory \ No newline at end of file diff --git a/modules/inventory/core_inventory/client.lua b/modules/inventory/core_inventory/client.lua index 943491b..4ecfea0 100644 --- a/modules/inventory/core_inventory/client.lua +++ b/modules/inventory/core_inventory/client.lua @@ -1,35 +1,26 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('core_inventory') ~= 'started' then return end +if GetResourceState('core_inventory') == 'missing' then return end local core = exports.core_inventory +-- Core inventory docs available at https://docs.c8re.store/core-inventory/api/server#getitemslist Callback = Callback or Require("lib/callback/shared/callback.lua") Inventory = Inventory or {} ----Return the item info in oxs format, {name, label, stack, weight, description, image} ----@param item string ----@return table -Inventory.GetItemInfo = function(item) - local frameworkName = Framework.GetFrameworkName() - if not frameworkName then return {} end - local dataRepack = {} - if frameworkName == 'es_extended' then - local callbackData = Callback.Trigger('community_bridge:Callback:core_inventory', false) - -- really really wish this inventory allowed me to pull the item list client side.... - dataRepack = callbackData[item] - if not dataRepack then return {} end - elseif frameworkName == 'qb-core' then - dataRepack = Framework.Shared.Items[item] - if not dataRepack then return {} end - end - return {name = dataRepack.name, label = dataRepack.label, stack = dataRepack.stack, weight = dataRepack.weight, description = dataRepack.description, image = Inventory.GetImagePath(dataRepack.name) } -end - ---This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "core_inventory" end +local cachedItemList = nil +--- Return the item info in oxs format, {name, label, stack, weight, description, image} +--- https://docs.c8re.store/core-inventory/api/server#getitemslist +--- @param item string +--- @return table +Inventory.GetItemInfo = function(item) + local itemList = Inventory.Items() + return itemList[item] or {} +end ---This will return the entire items table from the inventory. ---@return table @@ -38,13 +29,16 @@ Inventory.Items = function() if not frameworkName then return {} end local dataRepack = {} if frameworkName == 'es_extended' then - local callbackData = Callback.Trigger('community_bridge:Callback:core_inventory', false) - -- really really wish this inventory allowed me to pull the item list client side.... - dataRepack = callbackData - if not dataRepack then return {} end + if not cachedItemList then cachedItemList = Callback.Trigger('community_bridge:Callback:core_inventory', false) end + dataRepack = cachedItemList or {} elseif frameworkName == 'qb-core' then - dataRepack = Framework.Shared.Items - if not dataRepack then return {} end + dataRepack = Framework.Shared.Items or {} + end + for itemName, itemData in pairs(dataRepack) do + if itemData and itemData.name then + dataRepack[itemName].image = Inventory.GetImagePath(itemData.name) + dataRepack[itemName].stack = dataRepack[itemName].unique or false + end end return dataRepack end @@ -56,11 +50,12 @@ Inventory.HasItem = function(item) return core:hasItem(item, 1) end ----This will return th count of the item in the players inventory, if not found will return 0. +---@description Will return boolean if the player has the item. ---@param item string ----@return number -Inventory.GetItemCount = function(item) - return core:getItemCount(item) +---@param requiredCount number (optional) +---@return boolean +Inventory.HasItem = function(item, requiredCount) + return core:getItemCount(item) >= (requiredCount or 1) end ---This will get the image path for this item, if not found will return placeholder. @@ -81,9 +76,9 @@ Inventory.GetPlayerInventory = function() for _, v in pairs(playerItems) do table.insert(repackedTable, { name = v.name, - count = v.count, - metadata = v.metadata, - slot = v.id, + count = v.count or v.amount, + metadata = v.metadata or v.info, + slot = v.id or v.slot, }) end return repackedTable diff --git a/modules/inventory/core_inventory/server.lua b/modules/inventory/core_inventory/server.lua index e2dc3ad..c6407e6 100644 --- a/modules/inventory/core_inventory/server.lua +++ b/modules/inventory/core_inventory/server.lua @@ -1,11 +1,17 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('core_inventory') ~= 'started' then return end +if GetResourceState('core_inventory') == 'missing' then return end Inventory = Inventory or {} Inventory.Stashes = Inventory.Stashes or {} Callback = Callback or Require("lib/callback/shared/callback.lua") local core = exports.core_inventory +---This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "core_inventory" +end + ---This will add an item, and return true or false based on success ---@param src number ---@param item string @@ -14,18 +20,14 @@ local core = exports.core_inventory ---@param metadata table ---@return boolean Inventory.AddItem = function(src, item, count, slot, metadata) + -- docs specify a table returned on success, on failure it returns false. + -- https://docs.c8re.store/core-inventory/api/server#additem + local success = core:addItem(src, item, count, metadata) + if not success then return false end TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return core:addItem(src, item, count, metadata) + return success or false end - ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "core_inventory" -end - - ---This will remove an item, and return true or false based on success ---@param src number ---@param item string @@ -39,7 +41,7 @@ Inventory.RemoveItem = function(src, item, count, slot, metadata) if not inv then return false end for _, v in pairs(inv) do if v.name == item and v.metadata == metadata then - slot = v.slot + slot = v.id or v.slot break end end @@ -53,11 +55,12 @@ Inventory.RemoveItem = function(src, item, count, slot, metadata) identifier = string.gsub(identifier, ":", "") end local weirdInventoryName = 'content-' .. identifier + -- No return value specified in docs, so we assume none. + -- https://docs.c8re.store/core-inventory/api/server#removeitemexact return core:removeItemExact(weirdInventoryName, slot, count) end core:removeItem(src, item, count) return true - -- I hate this inventory so much, I am so sorry for this. end ---This will return the count of the item in the players inventory, if not found will return 0. @@ -93,24 +96,24 @@ Inventory.GetPlayerInventory = function(src) local playerItems = core:getInventory(src) local repackedTable = {} for _, v in pairs(playerItems) do - if v.metadata and v.count > 1 then + if (v.metadata or v.info) and (v.count or v.amount) > 1 then local plaseFixThisExportCuzThisIsPainful = core:getItems(src, v.name) if plaseFixThisExportCuzThisIsPainful then for _, item in pairs(plaseFixThisExportCuzThisIsPainful) do table.insert(repackedTable, { name = v.name, - count = item.count, - metadata = item.metadata, - slot = item.id, + count = item.count or item.amount, + metadata = item.metadata or item.info, + slot = item.id or item.slot, }) end end else table.insert(repackedTable, { name = v.name, - count = v.count, - metadata = v.metadata, - slot = v.id, + count = v.count or v.amount, + metadata = v.metadata or v.info, + slot = v.id or v.slot, }) end end @@ -126,12 +129,12 @@ Inventory.GetItemBySlot = function(src, slot) local inv = Inventory.GetPlayerInventory(src) if not inv then return {} end for _, v in pairs(inv) do - if v.slot == slot then + if (v.slot == slot) or (v.id == slot) then return { name = v.name, count = v.count, metadata = v.metadata, - slot = v.slot, + slot = v.id or v.slot, } end end @@ -156,7 +159,7 @@ end Inventory.OpenStash = function(src, _type, id) _type = _type or "stash" local tbl = Inventory.Stashes[id] - core:openInventory(src, id, _type, tbl.slots, tbl.weight, true, nil, false) + core:openInventory(src, id, _type, tbl.slots or 30, tbl.weight or 50000, true, nil, false) end ---This will register a stash @@ -185,12 +188,14 @@ Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coor return true, id end ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) - return core:getItemCount(src, item) > 0 +Inventory.HasItem = function(src, item, requiredCount) + local count = Inventory.GetItemCount(src, item, nil) + return count >= (requiredCount or 1) end ---This is to get if there is available space in the inventory, will return boolean. @@ -212,15 +217,6 @@ Inventory.AddTrunkItems = function(identifier, items) return false, print("AddItemsToTrunk is not implemented in core_inventory, because of this we dont have a way to add items to a trunk.") end ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. ----@param id string ----@return boolean -Inventory.ClearStash = function(id, _type) - if type(id) ~= "string" then return false end - if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return false, print("ClearInventory is not implemented in core_inventory, because of this we dont have a way to clear a stash.") -end - ---This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string @@ -267,9 +263,7 @@ end Inventory.OpenPlayerInventory = function(src, target) assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end + assert(target, "OpenPlayerInventory: target is required") local identifier = Framework.GetPlayerIdentifier(target) if not identifier then return false end exports.core_inventory:openInventory(src, 'stash-'.. identifier:gsub(':',''), 'stash', nil, nil, true, nil, false) diff --git a/modules/inventory/jpr-inventory/client.lua b/modules/inventory/jpr-inventory/client.lua index 489878c..84e5a9a 100644 --- a/modules/inventory/jpr-inventory/client.lua +++ b/modules/inventory/jpr-inventory/client.lua @@ -1,10 +1,16 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('jpr-inventory') ~= 'started' then return end +if GetResourceState('jpr-inventory') == 'missing' then return end local jpr = exports['jpr-inventory'] Inventory = Inventory or {} ----Return the item info in oxs format, {name, label, stack, weight, description, image} +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "jpr-inventory" +end + +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -20,28 +26,7 @@ Inventory.GetItemInfo = function(item) } end - ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "jpr-inventory" -end - - ----Will return boolean if the player has the item. ----@param item string ----@return boolean -Inventory.HasItem = function(item) - return jpr:HasItem(item) -end - ----This will return the entire items table from the inventory. ----@return table -Inventory.Items = function() - return Framework.Shared.Items -end - ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) diff --git a/modules/inventory/jpr-inventory/server.lua b/modules/inventory/jpr-inventory/server.lua index 6e0eb82..d8ce57d 100644 --- a/modules/inventory/jpr-inventory/server.lua +++ b/modules/inventory/jpr-inventory/server.lua @@ -1,5 +1,5 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('jpr-inventory') ~= 'started' then return end +if GetResourceState('jpr-inventory') == 'missing' then return end local jpr = exports['jpr-inventory'] local registeredShops = {} @@ -7,37 +7,43 @@ local registeredShops = {} Inventory = Inventory or {} Inventory.Stashes = Inventory.Stashes or {} ----This will add an item, and return true or false based on success ----@param src number ----@param item string ----@param count number ----@param slot number ----@param metadata table ----@return boolean -Inventory.AddItem = function(src, item, count, slot, metadata) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return exports['jpr-inventory']:AddItem(src, item, count, slot, metadata, 'community_bridge Item added') -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "jpr-inventory" end ----This will remove an item, and return true or false based on success +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number ----@param slot number ----@param metadata table +---@param slot number (optional) +---@param metadata table (optional) ---@return boolean -Inventory.RemoveItem = function(src, item, count, slot, metadata) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return exports['jpr-inventory']:RemoveItem(src, item, count, slot, 'community_bridge Item removed') +Inventory.AddItem = function(src, item, count, slot, metadata) + local canCarry = Inventory.CanCarryItem(src, item, count) + if not canCarry then return false end + local success = exports['jpr-inventory']:AddItem(src, item, count, slot, metadata, 'community_bridge Item added') + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) + return success or false end ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will remove an item, and return true or false based on success +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Inventory.RemoveItem = function(src, item, count, slot, metadata) + local success = exports['jpr-inventory']:RemoveItem(src, item, count, slot, 'community_bridge Item removed') + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) + return success or false +end + +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -46,17 +52,10 @@ Inventory.GetItemInfo = function(item) return itemTable end ----This will return the entire items table from the inventory. ----@return table -Inventory.Items = function() - return Framework.Shared.Items -end - ----Returns the specified slot data as a table. ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) local slotData = jpr:GetItemBySlot(src, slot) if not slotData then return {} end @@ -72,78 +71,27 @@ Inventory.GetItemBySlot = function(src, slot) } end ----This will open the specified stash for the src passed. +---@description This will open the specified stash for the src passed. ---@param src number ----@param _type string ----@param id number||string +---@param _type string "stash", "trunk", "glovebox" +---@param id string ---@return nil Inventory.OpenStash = function(src, _type, id) _type = _type or "stash" - local tbl = Inventory.Stashes[id] + local tbl = Inventory.Stashes[id] or {weight = 1000000, slots = 50} TriggerClientEvent('community_bridge:client:jpr-inventory:openStash', src, id, { weight = tbl.weight, slots = tbl.slots }) end ----This will register a stash ----@param id number|string ----@param label string ----@param slots number ----@param weight number ----@param owner string ----@param groups table ----@param coords table ----@return boolean ----@return string|number -Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) - if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } - return true, id -end - ----This will add items to a trunk, and return true or false based on success ----If a trunk with the identifier does not exist, it will create one with default values. ----@param identifier string ----@param items table ----@return boolean -Inventory.AddTrunkItems = function(identifier, items) - if type(items) ~= "table" then return false end - return false, print("AddItemsToTrunk is not implemented in jpr-inventory, because of this we dont have a way to add items to a trunk.") -end - ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. ----@param id string ----@return boolean -Inventory.ClearStash = function(id, _type) - if type(id) ~= "string" then return false end - if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return false, print("ClearInventory is not implemented in jpr-inventory, because of this we dont have a way to clear a stash.") -end - ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) - return jpr:HasItem(src, item, 1) +Inventory.HasItem = function(src, item, requiredCount) + return jpr:HasItem(src, item, requiredCount or 1) end ----This is to get if there is available space in the inventory, will return boolean. ----@param src number ----@param item string ----@param count number ----@return boolean -Inventory.CanCarryItem = function(src, item, count) - return true -end - ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean @@ -158,7 +106,7 @@ Inventory.UpdatePlate = function(oldplate, newplate) return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -168,26 +116,26 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----This will open the specified shop for the src passed. +---@description This will open the specified shop for the src passed. ---@param src number ---@param shopTitle string Inventory.OpenShop = function(src, shopTitle) jpr:OpenShop(src, shopTitle) end ----This will register a shop, if it already exists it will return true. +---@description This will register a shop, if it already exists it will return true. ---@param shopTitle string ----@param shopInventory table +---@param inventory table ---@param shopCoords table ---@param shopGroups table -Inventory.RegisterShop = function(shopTitle, shopInventory, shopCoords, shopGroups) - if not shopTitle or not shopInventory or not shopCoords then return end +Inventory.RegisterShop = function(shopTitle, inventory, shopCoords, shopGroups) + if not shopTitle or not inventory or not shopCoords then return end if registeredShops[shopTitle] then return true end local repackItems = {} - local repackedShopItems = {name = shopTitle, label = shopTitle, coords = shopCoords, items = repackItems, slots = #shopInventory, } - for k, v in pairs(shopInventory) do - table.insert(repackItems, { name = v.name, price = v.price or 1000, amount = v.count or 1, slot = k }) + local repackedShopItems = {name = shopTitle, label = shopTitle, coords = shopCoords, items = repackItems, slots = #inventory, } + for k, v in pairs(inventory) do + table.insert(repackItems, { name = v.name, price = v.price or 1000, amount = v.count or v.amount or 1, slot = k }) end jpr:CreateShop(repackedShopItems) @@ -195,11 +143,12 @@ Inventory.RegisterShop = function(shopTitle, shopInventory, shopCoords, shopGrou return true end +---@description This will open a players inventory, used for admin purposes and stuff. +---@param src number +---@param target number Inventory.OpenPlayerInventory = function(src, target) assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end + assert(target, "OpenPlayerInventory: target is required") local identifier = Framework.GetPlayerIdentifier(target) if not identifier then return false end exports['jpr-inventory']:OpenInventory(src, identifier) diff --git a/modules/inventory/origen_inventory/client.lua b/modules/inventory/origen_inventory/client.lua index eccc81b..4411f9e 100644 --- a/modules/inventory/origen_inventory/client.lua +++ b/modules/inventory/origen_inventory/client.lua @@ -1,13 +1,20 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('origen_inventory') ~= 'started' then return end +if GetResourceState('origen_inventory') == 'missing' then return end +if GetResourceState('ox_inventory') ~= 'missing' then return end Inventory = Inventory or {} local origin = exports.origen_inventory ----Return the item info in oxs format, {name, label, stack, weight, description, image} +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "origen_inventory" +end + +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) - local itemData = origin:Items(item) + local itemData = Inventory.Items()[item] if not itemData then return {} end return { name = itemData.name or "Missing Name", @@ -19,26 +26,16 @@ Inventory.GetItemInfo = function(item) } end ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "origen_inventory" -end - ----This will return the entire items table from the inventory. ----@return table -Inventory.Items = function() - return origin:Items() -end - ----Will return boolean if the player has the item. +---@description Will return boolean if the player has the item. ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(item) - return origin:HasItem(item) +Inventory.HasItem = function(item, requiredCount) + local count = Inventory.GetItemCount(item) + return count >= (requiredCount or 1) end ----This will return th count of the item in the players inventory, if not found will return 0. +---@description This will return their count of the item in the players inventory, if not found will return 0. ---@param item string ---@return number Inventory.GetItemCount = function(item) @@ -47,7 +44,7 @@ Inventory.GetItemCount = function(item) return inventory.count end ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -57,7 +54,7 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----This will return the players inventory in the format of {name, label, count, slot, metadata} +---@description This will return the players inventory in the format of {name, label, count, slot, metadata} ---@return table Inventory.GetPlayerInventory = function() local repack = {} @@ -67,10 +64,10 @@ Inventory.GetPlayerInventory = function() table.insert(repack, { name = v.name, label = v.label, - count = v.amount, + count = v.amount or v.count, slot = v.slot, - metadata = v.metadata, - stack = v.unique, + metadata = v.metadata or v.info or {}, + stack = v.unique or v.stack or false, close = v.useable, weight = v.weight }) @@ -78,8 +75,4 @@ Inventory.GetPlayerInventory = function() return repack end -Inventory.OpenStash = function(id) - origin:openInventory('stash', id, { label = id, weight = 400000, slots = 100, }) -end - return Inventory \ No newline at end of file diff --git a/modules/inventory/origen_inventory/server.lua b/modules/inventory/origen_inventory/server.lua index 55e3f2d..9a634cf 100644 --- a/modules/inventory/origen_inventory/server.lua +++ b/modules/inventory/origen_inventory/server.lua @@ -1,42 +1,49 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('origen_inventory') ~= 'started' then return end +if GetResourceState('origen_inventory') == 'missing' then return end +if GetResourceState('ox_inventory') ~= 'missing' then return end Inventory = Inventory or {} Inventory.Stashes = Inventory.Stashes or {} local origin = exports.origen_inventory ----This will add an item, and return true or false based on success ----@param src number ----@param item string ----@param count number ----@param slot number ----@param metadata table ----@return boolean -Inventory.AddItem = function(src, item, count, slot, metadata) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return origin:AddItem(src, item, count, metadata, slot, true) -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "origen_inventory" end ----This will remove an item, and return true or false based on success +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number ----@param slot number ----@param metadata table +---@param slot number (optional) +---@param metadata table (optional) ---@return boolean -Inventory.RemoveItem = function(src, item, count, slot, metadata) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return origin:removeItem(src, item, count, metadata, slot, true) +Inventory.AddItem = function(src, item, count, slot, metadata) + local canCarry = Inventory.CanCarryItem(src, item, count) + if not canCarry then return false end + local success = origin:addItem(src, item, count, metadata, slot, false) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) + return success or false end ----This will add items to a trunk, and return true or false based on success +---@description This will remove an item, and return true or false based on success +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Inventory.RemoveItem = function(src, item, count, slot, metadata) + local success = origin:removeItem(src, item, count, metadata, slot, false) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) + return success or false +end + +---@description This will add items to a trunk, and return true or false based on success ---@param identifier string ---@param items table ---@return boolean @@ -48,8 +55,8 @@ Inventory.AddTrunkItems = function(identifier, items) for _, v in pairs(items) do table.insert(repack_items, { name = v.item, - amount = v.count, - metadata = v.metadata or {} + amount = v.count or v.amount, + metadata = v.metadata or v.info or {} }) end if #repack_items == 0 then return false end @@ -57,13 +64,14 @@ Inventory.AddTrunkItems = function(identifier, items) return true end ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. ----@param identifier string +---@description This will clear the specified inventory, will always return true unless a value isnt passed correctly. +---@param id string +---@param _type string unused with ox_inventory ---@return boolean -Inventory.ClearStash = function(identifier, _type) - if type(identifier) ~= "string" then return false end - if Inventory.Stashes[identifier] then Inventory.Stashes[identifier] = nil end - local id = identifier +Inventory.ClearStash = function(id, _type) + if type(id) ~= "string" then return false end + if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end + local id = id if _type == "trunk" then id = "trunk_"..id elseif _type == "glovebox" then @@ -71,7 +79,7 @@ Inventory.ClearStash = function(identifier, _type) elseif _type == "stash" then id = "stash_"..id end - local inv = origin:getInventory(identifier, _type) + local inv = origin:getInventory(id, _type) if not inv then return false end local indexed = inv.inventory for _, v in pairs(indexed) do @@ -82,7 +90,7 @@ Inventory.ClearStash = function(identifier, _type) return true end ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -98,23 +106,22 @@ Inventory.GetItemInfo = function(item) } end ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return origin:Items() end ----This will return the count of the item in the players inventory, if not found will return 0. ----if metadata is passed it will find the matching items count. +---@description This will return the count of the item in the players inventory, if not found will return 0. ---@param src number ---@param item string ----@param metadata table +---@param metadata table (optional) ---@return number Inventory.GetItemCount = function(src, item, metadata) return origin:getItemCount(src, item, metadata, false) or 0 end ----This wil return the players inventory. +---@description This will return the players inventory. ---@param src number ---@return table Inventory.GetPlayerInventory = function(src) @@ -125,8 +132,8 @@ Inventory.GetPlayerInventory = function(src) if v.slot then table.insert(repack, { name = v.name, - count = v.amount, - metadata = v.metadata or {}, + count = v.amount or v.count, + metadata = v.metadata or v.info or {}, slot = v.slot, label = v.label or "Unknown" }) @@ -135,20 +142,19 @@ Inventory.GetPlayerInventory = function(src) return repack end ----Returns the specified slot data as a table. ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) local playerInv = Inventory.GetPlayerInventory(src) for _, v in pairs(playerInv) do if v.slot == slot then return { name = v.name, - count = v.count, + count = v.count or v.amount, weight = v.weight or 0, - metadata = v.metadata, + metadata = v.metadata or v.info or {}, slot = v.slot, label = v.label } @@ -157,7 +163,7 @@ Inventory.GetItemBySlot = function(src, slot) return {} end ----This will set the metadata of an item in the inventory. +---@description This will set the metadata of an item in the inventory. ---@param src number ---@param item string ---@param slot number @@ -167,51 +173,43 @@ Inventory.SetMetadata = function(src, item, slot, metadata) origin:setMetadata(src, slot, metadata) end ----This will open the specified stash for the src passed. +---@description This will open the specified stash for the src passed. ---@param src number ----@param _type string ----@param id number|string +---@param _type string "stash", "trunk", "glovebox" +---@param id string ---@return nil Inventory.OpenStash = function(src, _type, id) _type = _type or "stash" - local tbl = Inventory.Stashes[id] return origin:OpenInventory(src, _type, id) end ----This will register a stash +---@description This will register a stash ---@param id number|string ---@param label string ---@param slots number ---@param weight number ----@param owner string ----@param groups table ----@param coords table +---@param owner string (optional) +---@param groups table (optional) +---@param coords table (optional) ---@return boolean ---@return string|number Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } + Inventory.Stashes[id] = {id = id, label = label or id, slots = slots, weight = weight, owner = owner, groups = groups, coords = coords} origin:registerStash(id, label, slots, weight, owner, groups, coords) return true, id end ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) - return origin:getItemCount(src , item) > 0 +Inventory.HasItem = function(src, item, requiredCount) + return origin:getItemCount(src , item) > (requiredCount or 0) end ----This is to get if there is available space in the inventory, will return boolean. +---@description This is to get if there is available space in the inventory, will return boolean. ---@param src number ---@param item string ---@param count number @@ -220,7 +218,7 @@ Inventory.CanCarryItem = function(src, item, count) return origin:canCarryItem(src, item, count) end ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean @@ -235,7 +233,7 @@ Inventory.UpdatePlate = function(oldplate, newplate) return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -245,11 +243,12 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end +---@description This will open a players inventory, used for admin purposes and stuff. +---@param src number +---@param target number Inventory.OpenPlayerInventory = function(src, target) assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end + assert(target, "OpenPlayerInventory: target is required") exports.origen_inventory:OpenInventory(src, "otherplayer", target) end diff --git a/modules/inventory/ox_inventory/client.lua b/modules/inventory/ox_inventory/client.lua index f8623ba..cb3b58d 100644 --- a/modules/inventory/ox_inventory/client.lua +++ b/modules/inventory/ox_inventory/client.lua @@ -1,13 +1,21 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('ox_inventory') ~= 'started' then return end -if GetResourceState('qs-inventory') == 'started' then return end -if GetResourceState('origen_inventory') == 'started' then return end +if GetResourceState('ox_inventory') == 'missing' then return end +if GetResourceState('tgiann-inventory') ~= 'missing' then return end +if GetResourceState('qs-inventory') ~= 'missing' then return end +if GetResourceState('origen_inventory') ~= 'missing' then return end +--check for providers =/ local ox_inventory = exports.ox_inventory Inventory = Inventory or {} ----Return the item info in oxs format, {name, label, stack, weight, description, image} +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "ox_inventory" +end + +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -23,33 +31,28 @@ Inventory.GetItemInfo = function(item) } end ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "ox_inventory" -end - ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return ox_inventory:Items() end ----Will return boolean if the player has the item. +---@description Will return boolean if the player has the item. ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(item) - return ox_inventory:Search('count', item) > 0 +Inventory.HasItem = function(item, requiredCount) + return ox_inventory:Search('count', item, nil) >= (requiredCount or 1) end ----This will return th count of the item in the players inventory, if not found will return 0. +---@description This will return their count of the item in the players inventory, if not found will return 0. ---@param item string ---@return number Inventory.GetItemCount = function(item) return ox_inventory:GetItemCount(item, nil, false) end ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -59,7 +62,7 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----This will return the players inventory in the format of {name, label, count, slot, metadata} +---@description This will return the players inventory in the format of {name, label, count, slot, metadata} ---@return table Inventory.GetPlayerInventory = function() return ox_inventory:GetPlayerItems() diff --git a/modules/inventory/ox_inventory/server.lua b/modules/inventory/ox_inventory/server.lua index ff5e4a4..7e022ac 100644 --- a/modules/inventory/ox_inventory/server.lua +++ b/modules/inventory/ox_inventory/server.lua @@ -1,71 +1,50 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('ox_inventory') ~= 'started' then return end -if GetResourceState('qs-inventory') == 'started' then return end -if GetResourceState('origen_inventory') == 'started' then return end +if GetResourceState('ox_inventory') == 'missing' then return end +if GetResourceState('tgiann-inventory') ~= 'missing' then return end +if GetResourceState('qs-inventory') ~= 'missing' then return end +if GetResourceState('origen_inventory') ~= 'missing' then return end +--check for providers =/ local ox_inventory = exports.ox_inventory -local registeredShops = {} - Inventory = Inventory or {} Inventory.Stashes = Inventory.Stashes or {} ----This will add an item, and return true or false based on success ----@param src number ----@param item string ----@param count number ----@param slot number ----@param metadata table ----@return boolean -Inventory.AddItem = function(src, item, count, slot, metadata) - if not ox_inventory:CanCarryItem(src, item, count, metadata) then return false end - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return ox_inventory:AddItem(src, item, count, metadata) -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "ox_inventory" end ----This will remove an item, and return true or false based on success +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number ----@param slot number ----@param metadata table +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Inventory.AddItem = function(src, item, count, slot, metadata) + if not ox_inventory:CanCarryItem(src, item, count, metadata) then return false end + local success = ox_inventory:AddItem(src, item, count, metadata) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) + return success +end + +---@description This will remove an item, and return true or false based on success +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) ---@return boolean Inventory.RemoveItem = function(src, item, count, slot, metadata) + local success = ox_inventory:RemoveItem(src, item, count, metadata, slot) + if not success then return false end TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return ox_inventory:RemoveItem(src, item, count, metadata, slot) + return success end ----This will add items to a trunk, and return true or false based on success ----@param identifier string ----@param items table ----@return boolean -Inventory.AddTrunkItems = function(identifier, items) - local id = "trunk"..identifier - if type(items) ~= "table" then return false end - Inventory.RegisterStash(id, identifier, 20, 10000, nil, nil, nil) - Wait(100) -- Wait for the stash to be registered just in case - for _, v in pairs(items) do - ox_inventory:AddItem(id, v.item, v.count, v.metadata) - end - return true -end - ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. ----@param id string ----@return boolean -Inventory.ClearStash = function(id, _type) - if type(id) ~= "string" then return false end - ox_inventory:ClearInventory(_type..id, nil) - if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return true -end - ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -81,41 +60,37 @@ Inventory.GetItemInfo = function(item) } end ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return ox_inventory:Items() end ----This will return the count of the item in the players inventory, if not found will return 0. ---- ----if metadata is passed it will find the matching items count. +---@description This will return the count of the item in the players inventory, if not found will return 0. ---@param src number ---@param item string ----@param metadata table +---@param metadata table (optional) ---@return number Inventory.GetItemCount = function(src, item, metadata) return ox_inventory:GetItemCount(src, item, metadata, false) end ----This wil return the players inventory. +---@description This wil return the players inventory. ---@param src number ---@return table Inventory.GetPlayerInventory = function(src) return ox_inventory:GetInventoryItems(src, false) end ----Returns the specified slot data as a table. ---- ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) return ox_inventory:GetSlot(src, slot) end ----This will set the metadata of an item in the inventory. +---@description This will set the metadata of an item in the inventory. ---@param src number ---@param item string ---@param slot number @@ -125,52 +100,70 @@ Inventory.SetMetadata = function(src, item, slot, metadata) ox_inventory:SetMetadata(src, slot, metadata) end ----This will open the specified stash for the src passed. ----@param src number ----@param _type string ----@param id number||string ----@return nil -Inventory.OpenStash = function(src, _type, id) - _type = _type or "stash" - --local tbl = Inventory.Stashes[id] - ox_inventory:forceOpenInventory(src, _type, id) -end - --- restores stashes to before commit #e06e04a (no depreication path followed, breaking change and not present on all inventories so undoing it. (also breaking multiple resources)) ----This will register a stash +---@description This will register a stash ---@param id number|string ---@param label string ---@param slots number ---@param weight number ----@param owner string ----@param groups table ----@param coords table +---@param owner string (optional) +---@param groups table (optional) +---@param coords table (optional) ---@return boolean ---@return string|number Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) + id = tostring(id) + -- ox standard doesnt return anything so probably shouldnt return so everything else has the same standard. Id is pointless if its a param already. Yeaaaa probably should change this. if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } + Inventory.Stashes[id] = {id = id, label = label, slots = slots, weight = weight, owner = owner, groups = groups, coords = coords} ox_inventory:RegisterStash(id, label, slots, weight, owner, groups, coords) return true, id end ----This will return a boolean if the player has the item. +---@description This will open the specified stash for the src passed. ---@param src number ----@param item string ----@return boolean -Inventory.HasItem = function(src, item) - return ox_inventory:GetItemCount(src, item, nil, false) > 0 +---@param _type string "stash", "trunk", "glovebox" +---@param id string +---@return nil +Inventory.OpenStash = function(src, _type, id) + _type = _type or "stash" + ox_inventory:forceOpenInventory(src, _type, id) end ----This is to get if there is available space in the inventory, will return boolean. +---@description This will add items to a stash, and return true or false based on success +---@param id string +---@param items table {item, count, metadata} +---@return boolean +Inventory.AddStashItems = function(id, items) + if type(items) ~= "table" then return false end + local success = false + for _, v in pairs(items) do + success = ox_inventory:AddItem(id, v.item, v.count or v.amount, v.metadata or v.info or {}) + end + return success +end + +---@description This will clear the specified inventory, will always return true unless a value isnt passed correctly. +---@param id string +---@param _type string unused with ox_inventory +---@return boolean +Inventory.ClearStash = function(id, _type) + id = tostring(id) + ox_inventory:ClearInventory(id) + if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end + -- ox standard doesnt return anything so probably shouldnt return so everything else has the same standard. Yeaaaa probably should change this. + return true +end + +---@description This will return a boolean if the player has the item. +---@param src number +---@param item string +---@param requiredCount number (optional) +---@return boolean +Inventory.HasItem = function(src, item, requiredCount) + return ox_inventory:GetItemCount(src, item, nil, false) >= (requiredCount or 1) +end + +---@description This is to get if there is available space in the inventory, will return boolean. ---@param src number ---@param item string ---@param count number @@ -179,17 +172,34 @@ Inventory.CanCarryItem = function(src, item, count) return ox_inventory:CanCarryItem(src, item, count) end ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean Inventory.UpdatePlate = function(oldplate, newplate) ox_inventory:UpdateVehicle(oldplate, newplate) - if GetResourceState('jg-mechanic') ~= 'started' then return true end + -- ox standard doesnt return anything so probably shouldnt return so everything else has the same standard. Yeaaaa probably should change this. + if GetResourceState('jg-mechanic') ~= 'missing' then return true end return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will add items to a trunk, and return true or false based on success +---@param identifier string +---@param items table +---@return boolean +Inventory.AddTrunkItems = function(identifier, items) + local id = "trunk"..identifier + if type(items) ~= "table" then return false end + Inventory.RegisterStash(id, identifier, 20, 10000, nil, nil, nil) + Wait(100) + local success = false + for _, v in pairs(items) do + success = ox_inventory:AddItem(id, v.item, v.count or v.amount, v.metadata or v.info or {}) + end + return success +end + +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -199,46 +209,31 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end --- restores shops to before commit #e06e04a (no depreication path followed, breaking change and not present on all inventories so undoing it. (also breaking multiple resources)) --- This will open the specified shop for the src passed. +---@description This will open the specified shop for the src passed. ---@param src number ---@param shopTitle string Inventory.OpenShop = function(src, shopTitle) TriggerClientEvent('ox_inventory:openInventory', src, 'shop', {type = shopTitle}) end --- restores shops to before commit #e06e04a (no depreication path followed, breaking change and not present on all inventories so undoing it. (also breaking multiple resources)) --- This will register a shop, if it already exists it will return true. +---@description This will register a shop, if it already exists it will return true. ---@param shopTitle string ----@param shopInventory table +---@param inventory table ---@param shopCoords table ---@param shopGroups table -Inventory.RegisterShop = function(shopTitle, shopInventory, shopCoords, shopGroups) - if registeredShops[shopTitle] then return true end - registeredShops[shopTitle] = true - ox_inventory:RegisterShop(shopTitle, { name = shopTitle, inventory = shopInventory, groups = shopGroups, }) - --return Inventory.OpenShop(src, shopTitle) +Inventory.RegisterShop = function(shopTitle, inventory, shopCoords, shopGroups) + ox_inventory:RegisterShop(shopTitle, { name = shopTitle, inventory = inventory, groups = shopGroups, }) + -- ox standard doesnt return anything so probably shouldnt return so everything else has the same standard. Yeaaaa probably should change this. return true end ----UNUSED: ----This will return generic item data from the specified inventory, with the items total count. ----format without metadata { count, stack, name, weight, label } ----fortmat with metadata { count, stack, name, weight, label, metadata } +---@description This will open a players inventory, used for admin purposes and stuff. ---@param src number ----@param item string ----@param metadata table ----@return table -Inventory.GetItem = function(src, item, metadata) - return ox_inventory:GetItem(src, item, metadata, false) -end - +---@param target number Inventory.OpenPlayerInventory = function(src, target) assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end - exports.ox_inventory:openInventory('player', target) + assert(target, "OpenPlayerInventory: target is required") + ox_inventory:forceOpenInventory(src, 'player', target) end return Inventory \ No newline at end of file diff --git a/modules/inventory/ps-inventory/client.lua b/modules/inventory/ps-inventory/client.lua index 69ced4f..40a68db 100644 --- a/modules/inventory/ps-inventory/client.lua +++ b/modules/inventory/ps-inventory/client.lua @@ -1,5 +1,5 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('ps-inventory') ~= 'started' then return end +if GetResourceState('ps-inventory') == 'missing' then return end local ps = exports['ps-inventory'] Inventory = Inventory or {} diff --git a/modules/inventory/ps-inventory/server.lua b/modules/inventory/ps-inventory/server.lua index 53194e4..335bc97 100644 --- a/modules/inventory/ps-inventory/server.lua +++ b/modules/inventory/ps-inventory/server.lua @@ -1,62 +1,62 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('ps-inventory') ~= 'started' then return end +if GetResourceState('ps-inventory') == 'missing' then return end local sloth = exports['ps-inventory'] -local registeredShops = {} Inventory = Inventory or {} -Inventory.Stashes = Inventory.Stashes or {} ----This will add an item, and return true or false based on success ----@param src number ----@param item string ----@param count number ----@param slot number ----@param metadata table ----@return boolean -Inventory.AddItem = function(src, item, count, slot, metadata) - TriggerClientEvent('ps-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'add', count) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return sloth:AddItem(src, item, count, slot, metadata, 'community_bridge') -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "ps-inventory" end ----This will remove an item, and return true or false based on success +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number ----@param slot number ----@param metadata table +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Inventory.AddItem = function(src, item, count, slot, metadata) + local success = sloth:AddItem(src, item, count, slot, metadata, 'community_bridge') + if not success then return false end + TriggerClientEvent('ps-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'add', count) + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) + return success or false +end + +local function runMetadataSearch(src, metadata) + local inv = Framework.GetPlayerInventory(src) or {} + for k, v in pairs(inv) do + if v.metadata and v.metadata == metadata then + return true, v.slot + end + end + return false +end + +---@description This will remove an item, and return true or false based on success +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) ---@return boolean Inventory.RemoveItem = function(src, item, count, slot, metadata) + if metadata then + local found, itemSlot = runMetadataSearch(src, metadata) + if found then + slot = itemSlot + end + end + local success = sloth:RemoveItem(src, item, count, slot, 'community_bridge') + if not success then return false end TriggerClientEvent('ps-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'remove', count) TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return sloth:RemoveItem(src, item, count, slot, 'community_bridge') + return success or false end ----This will add items to a trunk, and return true or false based on success ----@param identifier string ----@param items table ----@return boolean -Inventory.AddItemsToTrunk = function(identifier, items) - if type(items) ~= "table" then return false end - return false, print("AddItemsToTrunk is not implemented in ps-inventory, because of this we dont have a way to add items to a trunk.") -end - ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. ----@param id string ----@return boolean -Inventory.ClearStash = function(id, _type) - if type(id) ~= "string" then return false end - if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return false, print("ClearInventory is not implemented in ps-inventory, because of this we dont have a way to clear a stash.") -end - ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -72,100 +72,45 @@ Inventory.GetItemInfo = function(item) } end ----This will return the entire items table from the inventory. ----@return table -Inventory.Items = function() - return Framework.Shared.Items -end - ----Returns the specified slot data as a table. ---- ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) - local slotData = sloth:GetItemBySlot(src, slot) - if not slotData then return {} end + local item = sloth:GetItemBySlot(src, slot) + if not item then return {} end return { - name = slotData.name, - label = slotData.label or slotData.name, - weight = slotData.weight, + name = item.name, + label = item.label or item.name, + weight = item.weight, slot = slot, - count = slotData.amount, - metadata = slotData.info, - stack = slotData.unique, - description = slotData.description + count = item.amount, + metadata = item.info, + stack = item.unique, + description = item.description } end ----This will set the metadata of an item in the inventory. +---@description This will open the specified stash for the src passed. ---@param src number ----@param item string ----@param slot number ----@param metadata table ----@return nil -Inventory.SetMetadata = function(src, item, slot, metadata) - local itemData = Inventory.GetItemBySlot(src, slot) - if not itemData then return end - if itemData.count > 1 then return print("Items with more than 1 count cannot be set with metadata plase adjust item to unique in the qb shared item name : "..item) end - Inventory.RemoveItem(src, item, 1, slot) - return Inventory.AddItem(src, item, 1, slot, metadata) -end - ----This will open the specified stash for the src passed. ----@param src number ----@param _type string ----@param id number||string +---@param _type string "stash", "trunk", "glovebox" +---@param id string ---@return nil Inventory.OpenStash = function(src, _type, id) _type = _type or "stash" - local tbl = Inventory.Stashes[id] - TriggerClientEvent('community_bridge:client:ps-inventory:openStash', src, id, { label = tbl.label, maxweight = tbl.weight, slots = tbl.slots, }) + sloth:OpenInventory(_type, id, nil, src) end ----This will register a stash ----@param id number|string ----@param label string ----@param slots number ----@param weight number ----@param owner string ----@param groups table ----@param coords table ----@return boolean ----@return string|number -Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) - if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } - return true, id -end - ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) - return sloth:HasItem(src, item, 1) +Inventory.HasItem = function(src, item, requiredCount) + return sloth:HasItem(src, item, requiredCount or 1) end ----This is to get if there is available space in the inventory, will return boolean. ----@param src number ----@param item string ----@param count number ----@return boolean -Inventory.CanCarryItem = function(src, item, count) - return true -end - ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean @@ -176,11 +121,12 @@ Inventory.UpdatePlate = function(oldplate, newplate) } local values = { newplate = newplate, oldplate = oldplate } MySQL.transaction.await(queries, values) + -- ox standard doesnt return anything so probably shouldnt return so everything else has the same standard. Yeaaaa probably should change this. if GetResourceState('jg-mechanic') ~= 'started' then return true end return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -190,31 +136,41 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end --- This will open the specified shop for the src passed. +---@description This will open the specified shop for the src passed. ---@param src number ---@param shopTitle string Inventory.OpenShop = function(src, shopTitle) return sloth:OpenShop(src, shopTitle) end --- This will register a shop, if it already exists it will return true. +---@description This will register a shop, if it already exists it will return true. ---@param shopTitle string ----@param shopInventory table +---@param inventory table ---@param shopCoords table ---@param shopGroups table -Inventory.RegisterShop = function(src, shopTitle, shopInventory, shopCoords, shopGroups) - if not shopTitle or not shopInventory or not shopCoords then return end - if registeredShops[shopTitle] then return true end +Inventory.RegisterShop = function(shopTitle, inventory, shopCoords, shopGroups) + assert(shopTitle, "RegisterShop: shopTitle is required") + assert(inventory, "RegisterShop: shopInventory is required") + assert(shopCoords, "RegisterShop: shopCoords is required") + assert(shopGroups, "RegisterShop: shopGroups is required") local repackItems = {} - local repackedShopItems = {name = shopTitle, label = shopTitle, coords = shopCoords, items = repackItems, slots = #shopInventory, } - for k, v in pairs(shopInventory) do - table.insert(repackItems, { name = v.name, price = v.price or 1000, amount = v.count or 1, slot = k }) + for k, v in pairs(inventory) do + table.insert(repackItems, { name = v.name, price = v.price or 1000, amount = v.amount or v.count or 1, slot = k }) end + local repackedShopItems = {name = shopTitle, label = shopTitle, coords = shopCoords, items = repackItems, slots = #inventory, } sloth:CreateShop(repackedShopItems) - registeredShops[shopTitle] = true return true end +---@description This will open a players inventory, used for admin purposes and stuff. +---@param src number +---@param target number +Inventory.OpenPlayerInventory = function(src, target) + assert(src, "OpenPlayerInventory: src is required") + assert(target, "OpenPlayerInventory: target is required") + sloth:OpenInventoryById(src, target) +end + return Inventory \ No newline at end of file diff --git a/modules/inventory/qb-inventory/client.lua b/modules/inventory/qb-inventory/client.lua index 195441e..52a65fb 100644 --- a/modules/inventory/qb-inventory/client.lua +++ b/modules/inventory/qb-inventory/client.lua @@ -1,10 +1,18 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('qb-inventory') ~= 'started' then return end +if GetResourceState('qb-inventory') == 'missing' then return end +if GetResourceState('codem-inventory') ~= 'missing' then return end +if GetResourceState('origen_inventory') ~= 'missing' then return end local qb = exports['qb-inventory'] Inventory = Inventory or {} ----Return the item info in oxs format, {name, label, stack, weight, description, image} +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "qb-inventory" +end + +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -20,26 +28,21 @@ Inventory.GetItemInfo = function(item) } end ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "qb-inventory" -end - ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return Framework.Shared.Items end ----Will return boolean if the player has the item. +---@description Will return boolean if the player has the item. ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(item) - return qb:HasItem(item) +Inventory.HasItem = function(item, requiredCount) + return qb:HasItem(item, requiredCount or 1) end ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) diff --git a/modules/inventory/qb-inventory/server.lua b/modules/inventory/qb-inventory/server.lua index 9abd7cb..8086949 100644 --- a/modules/inventory/qb-inventory/server.lua +++ b/modules/inventory/qb-inventory/server.lua @@ -1,104 +1,64 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('qb-inventory') ~= 'started' then return end +if GetResourceState('qb-inventory') == 'missing' then return end +if GetResourceState('ox_inventory') ~= 'missing' then return end +if GetResourceState('codem-inventory') ~= 'missing' then return end +if GetResourceState('origen_inventory') ~= 'missing' then return end local qbInventory = exports['qb-inventory'] Inventory = Inventory or {} Inventory.Stashes = Inventory.Stashes or {} - -local registeredShops = {} -local v1ShopData = {} +Inventory.Old = {} +Inventory.Version = nil +Inventory.ShopData = {} local function getInventoryNewVersion() - if tonumber(string.sub(GetResourceMetadata("qb-inventory", "version", 0), 1, 1)) >= 2 then return true end - return false + if tonumber(string.sub(GetResourceMetadata("qb-inventory", "version", 0), 1, 1)) >= 2 then Inventory.Version = true end + Inventory.Version = false end ----This will add an item, and return true or false based on success ----@param src number ----@param item string ----@param count number ----@param slot number ----@param metadata table ----@return boolean -Inventory.AddItem = function(src, item, count, slot, metadata) - if getInventoryNewVersion() then if not qbInventory:CanAddItem(src, item, count) then return false end end - TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'add', count) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return qbInventory:AddItem(src, item, count, slot, metadata, 'community_bridge') -end +AddEventHandler('onResourceStart', function(resourceName) + if resourceName ~= "community_bridge" then return end + getInventoryNewVersion() +end) ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "qb-inventory" end ----This will remove an item, and return true or false based on success +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number ----@param slot number ----@param metadata table +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Inventory.AddItem = function(src, item, count, slot, metadata) + if Inventory.Version then if not qbInventory:CanAddItem(src, item, count) then return false end end + local success = qbInventory:AddItem(src, item, count, slot, metadata, 'community_bridge') + if not success then return false end + TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'add', count) + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) + return success or false +end + +---@description This will remove an item, and return true or false based on success +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) ---@return boolean Inventory.RemoveItem = function(src, item, count, slot, metadata) + local success = qbInventory:RemoveItem(src, item, count, slot, 'community_bridge') + if not success then return false end TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items[item], 'remove', count) TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return qbInventory:RemoveItem(src, item, count, slot, 'community_bridge') + return success or false end ----This will add items to a trunk, and return true or false based on success ----If a trunk with the identifier does not exist, it will create one with default values. ----@param identifier string ----@param items table ----@return boolean -Inventory.AddTrunkItems = function(identifier, items) - if type(items) ~= "table" then return false end - local fullTrunkId = "trunk-"..identifier - local repacked_items = {} - local slot = 0 - for _, item in pairs(items) do - slot = slot + 1 - repacked_items[slot] = { - name = item.item, - amount = item.count, - info = item.metadata, - type = item.type or "item", - slot = slot, - } - end - local newVersion = getInventoryNewVersion() - if newVersion then - qbInventory:CreateInventory(fullTrunkId, { label = fullTrunkId }) - Wait(1000) - for i = 1, #repacked_items do - local v = repacked_items[i] - qbInventory:AddItem(fullTrunkId, v.name, v.amount, v.slot, v.info, "community_bridge, adding items to trunk") - end - else - -- I dont have a copy of this version to test it, if you run into issues please let me know. - TriggerEvent("inventory:server:addTrunkItems", fullTrunkId, repacked_items) - end - return true -end - ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. ----@param id string ----@return boolean -Inventory.ClearStash = function(id, _type) - if type(id) ~= "string" then return false end - if _type == "trunk" then - id = "trunk-"..id - elseif _type == "glovebox" then - id = "glovebox-"..id - end - if qbInventory:GetInventory(id) then - qbInventory:ClearStash(id) - end - if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return true -end - ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -114,17 +74,16 @@ Inventory.GetItemInfo = function(item) } end ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return Framework.Shared.Items end ----Returns the specified slot data as a table. ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) local slotData = qbInventory:GetItemBySlot(src, slot) if not slotData then return {} end @@ -140,64 +99,88 @@ Inventory.GetItemBySlot = function(src, slot) } end ----This will open the specified stash for the src passed. +---@description This will open the specified stash for the src passed. ---@param src number ----@param _type string ----@param id number||string +---@param _type string "stash", "trunk", "glovebox" +---@param id string ---@return nil Inventory.OpenStash = function(src, _type, id) _type = _type or "stash" - local tbl = Inventory.Stashes[id] - if getInventoryNewVersion() then - return qbInventory:OpenInventory(src, id) - end - - TriggerClientEvent('community_bridge:client:qb-inventory:openStash', src, id, { weight = tbl.weight, slots = tbl.slots}) + if not Inventory.Version then return Inventory.Old.OpenStash(src, _type, id) end + return qbInventory:OpenInventory(src, id) end ----This will register a stash ----@param id number|string ----@param label string ----@param slots number ----@param weight number ----@param owner string ----@param groups table ----@param coords table +---@description This will add items to a stash, and return true or false based on success +---@param id string +---@param items table {item, count, metadata} ---@return boolean ----@return string|number -Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) - if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } - return true, id +Inventory.AddStashItems = function(id, items) + if type(items) ~= "table" then return false end + if not Inventory.Version then return Inventory.Old.AddStashItems(id, items) end + local success = false + for _, item in pairs(items) do + success = qbInventory:AddItem(id, item.item, item.count or item.amount, nil, item.metadata or item.info, "community_bridge, adding items to stash") + end + return success end ----This will return a boolean if the player has the item. +---@description This will add items to a trunk, and return true or false based on success +---@param identifier string +---@param items table +---@return boolean +Inventory.AddTrunkItems = function(identifier, items) + if type(items) ~= "table" then return false end + local fullTrunkId = "trunk-"..identifier + if not Inventory.Version then return Inventory.Old.AddTrunkItems(fullTrunkId, items) end + if not qbInventory:GetInventory(fullTrunkId) then + qbInventory:CreateInventory(fullTrunkId, {label = fullTrunkId, slots = 15, maxweight = 10000}) + end + Wait(1000) + for i = 1, #items do + qbInventory:AddItem(fullTrunkId, items[i].name, items[i].amount or items[i].count, items[i].slot or nil, items[i].info or items[i].metadata or {}, "community_bridge, adding items to trunk") + end + return true +end + +---@description This will clear the specified inventory, will always return true unless a value isnt passed correctly. +---@param id string +---@return boolean +Inventory.ClearStash = function(id, _type) + if type(id) ~= "string" then return false end + if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end + if not Inventory.Version then return Inventory.Old.ClearStash(id, _type) end + if _type == "trunk" then + id = "trunk-"..id + elseif _type == "glovebox" then + id = "glovebox-"..id + end + local inv = qbInventory:GetInventory(id) + if not inv then return true end + qbInventory:ClearStash(id) + return true +end + +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) - return qbInventory:HasItem(src, item, 1) +Inventory.HasItem = function(src, item, requiredCount) + return qbInventory:HasItem(src, item, requiredCount or 1) end ----This is to get if there is available space in the inventory, will return boolean. +---@description This is to get if there is available space in the inventory, will return boolean. ---@param src number ---@param item string ---@param count number ---@return boolean Inventory.CanCarryItem = function(src, item, count) - return true + if not Inventory.Version then return Inventory.Old.CanCarryItem(src, item, count) end + return qbInventory:CanAddItem(src, item, count) end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -207,87 +190,128 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean Inventory.UpdatePlate = function(oldplate, newplate) - local newVersion = getInventoryNewVersion() - if newVersion then - local gloveboxInv = qbInventory:GetInventory('glovebox-'..oldplate) or {slots = 5, maxweight = 10000, items = {}} - local storedGloveBox = Bridge.Tables.DeepClone(gloveboxInv, nil, nil) - local trunkInv = qbInventory:GetInventory('trunk-'..oldplate) or {slots = 5, maxweight = 10000, items = {}} - local storedTrunk = Bridge.Tables.DeepClone(trunkInv, nil, nil) - qbInventory:ClearStash('glovebox-'..oldplate) - qbInventory:ClearStash('trunk-'..oldplate) - qbInventory:CreateInventory('glovebox-'..newplate, {label = 'glovebox-'..newplate, slots = storedGloveBox.slots, maxweight = storedGloveBox.maxweight}) - qbInventory:SetInventory('glovebox-'..newplate, storedGloveBox.items, "Community Bridge Moving Items In GloveBox") - qbInventory:CreateInventory('trunk-'..newplate, {label = 'trunk-'..newplate, slots = storedTrunk.slots, maxweight = storedTrunk.maxweight}) - qbInventory:SetInventory('trunk-'..newplate, storedTrunk.items, "Community Bridge Moving Items In Trunk") - return true - else - local queries = { - 'UPDATE inventory_glovebox SET plate = @newplate WHERE plate = @oldplate', - 'UPDATE inventory_trunk SET plate = @newplate WHERE plate = @oldplate', - } - local values = { newplate = newplate, oldplate = oldplate } - MySQL.transaction.await(queries, values) - end + if not Inventory.Version then return Inventory.Old.UpdatePlate(oldplate, newplate) end + local gloveboxInv = qbInventory:GetInventory('glovebox-'..oldplate) or {slots = 5, maxweight = 10000, items = {}} + local storedGloveBox = Bridge.Tables.DeepClone(gloveboxInv, nil, nil) + local trunkInv = qbInventory:GetInventory('trunk-'..oldplate) or {slots = 5, maxweight = 10000, items = {}} + local storedTrunk = Bridge.Tables.DeepClone(trunkInv, nil, nil) + qbInventory:ClearStash('glovebox-'..oldplate) + qbInventory:ClearStash('trunk-'..oldplate) + qbInventory:CreateInventory('glovebox-'..newplate, {label = 'glovebox-'..newplate, slots = storedGloveBox.slots, maxweight = storedGloveBox.maxweight}) + qbInventory:SetInventory('glovebox-'..newplate, storedGloveBox.items, "Community Bridge Moving Items In GloveBox") + qbInventory:CreateInventory('trunk-'..newplate, {label = 'trunk-'..newplate, slots = storedTrunk.slots, maxweight = storedTrunk.maxweight}) + qbInventory:SetInventory('trunk-'..newplate, storedTrunk.items, "Community Bridge Moving Items In Trunk") if GetResourceState('jg-mechanic') ~= 'started' then return true end return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) end ----This will open the specified shop for the src passed. +---@description This will open the specified shop for the src passed. ---@param src number ---@param shopTitle string Inventory.OpenShop = function(src, shopTitle) - local newVersion = getInventoryNewVersion() - if newVersion then - return qbInventory:OpenShop(src, shopTitle) - else - local shopData = v1ShopData[shopTitle] - if not shopData then return false end - TriggerClientEvent("inventory:client:OpenInventory", src, "shop", shopTitle, shopData) - end + if not Inventory.Version then return Inventory.Old.OpenShop(src, shopTitle) end + return qbInventory:OpenShop(src, shopTitle) end ---This will register a shop, if it already exists it will return true. +---@description This will register a shop, if it already exists it will return true. ---@param shopTitle string ----@param shopInventory table +---@param inventory table ---@param shopCoords table ---@param shopGroups table -Inventory.RegisterShop = function(shopTitle, shopInventory, shopCoords, shopGroups) - if not shopTitle or not shopInventory then return end - if registeredShops[shopTitle] then return true end - registeredShops[shopTitle] = true - local newVersion = getInventoryNewVersion() - if newVersion then - local repackedShopItems = {} - for _, v in pairs(shopInventory) do - table.insert(repackedShopItems, {name = v.name, price = v.price, amount = v.count or 1000}) - end - qbInventory:CreateShop({ name = shopTitle, label = shopTitle, coords = shopCoords, items = repackedShopItems, }) - return true - else - local shopData = { label = shopTitle, items = {}, slots = 0 } - - for _, v in pairs(shopInventory) do - table.insert(shopData.items, { name = v.name, price = v.price, amount = v.count or 1000, info = {}, type = 'item' }) - end - - shopData.slots = #shopData.items - -- TriggerClientEvent("inventory:client:OpenInventory", src, "shop", shopTitle, shopData) - v1ShopData[shopTitle] = shopData - print("QB-INVENTORY: You are using an outdated version of qb-inventory, please update to the latest version. Stuff will still work but you are using litterally the most exploitable inventory in fivem.") +Inventory.RegisterShop = function(shopTitle, inventory, shopCoords, shopGroups) + if not shopTitle or not inventory then return end + if Inventory.ShopData[shopTitle] then return true end + if not Inventory.Version then return Inventory.Old.RegisterShop(shopTitle, inventory, shopCoords, shopGroups) end + local repackedShopItems = {} + for _, v in pairs(inventory) do + table.insert(repackedShopItems, {name = v.name, price = v.price, amount = v.count or v.amount or 1000}) end + Inventory.ShopData[shopTitle] = { inventory = repackedShopItems, coords = shopCoords, groups = shopGroups } + qbInventory:CreateShop({ name = shopTitle, label = shopTitle, coords = shopCoords, items = repackedShopItems, }) end +---@description This will open a players inventory, used for admin purposes and stuff. +---@param src number +---@param target number Inventory.OpenPlayerInventory = function(src, target) assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end + assert(target, "OpenPlayerInventory: target is required") exports['qb-inventory']:OpenInventory(src, target) end +Inventory.Old.OpenShop = function(src, shopTitle) + local shopData = Inventory.ShopData[shopTitle] + if not shopData then return false end + TriggerClientEvent("inventory:client:OpenInventory", src, "shop", shopTitle, shopData) +end + +Inventory.Old.RegisterShop = function(shopTitle, inventory, shopCoords, shopGroups) + local shopData = { label = shopTitle, items = {}, slots = 0 } + + for _, v in pairs(inventory) do + table.insert(shopData.items, { name = v.name, price = v.price, amount = v.count or v.amount or 1000, info = v.metadata or v.info or {}, type = 'item' }) + end + + shopData.slots = #shopData.items + Inventory.ShopData[shopTitle] = shopData + print("QB-INVENTORY: You are using an outdated version of qb-inventory, please update to the latest version. Stuff will still work but you are using litterally the most exploitable inventory in fivem.") +end + +Inventory.Old.UpdatePlate = function(oldplate, newplate) + local queries = { + 'UPDATE inventory_glovebox SET plate = @newplate WHERE plate = @oldplate', + 'UPDATE inventory_trunk SET plate = @newplate WHERE plate = @oldplate', + } + local values = { newplate = newplate, oldplate = oldplate } + MySQL.transaction.await(queries, values) + if GetResourceState('jg-mechanic') ~= 'started' then return true end + return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) +end + +Inventory.Old.OpenStash = function(src, _type, id) + local tbl = Inventory.Stashes[id] + TriggerClientEvent('community_bridge:client:qb-inventory:openStash', src, id, { weight = tbl.weight or 5000, slots = tbl.slots or 20}) +end + +Inventory.Old.AddTrunkItems = function(fullTrunkId, items) + TriggerEvent("inventory:server:addTrunkItems", fullTrunkId, items) + return true +end + +Inventory.Old.AddStashItems = function(id, items) + return false, print("AddStashItems is not supported with qb-inventory v1") +end + +Inventory.Old.ClearStash = function(id, _type) + return false, print("ClearStash is not supported with qb-inventory v1") +end + +Inventory.Old.CanCarryItem = function(src, item, count) + local oldQbInventoryConfig = Require('config.lua', 'qb-inventory') + local maxInvWeight = oldQbInventoryConfig.MaxWeight or 100000 + local maxInvSlots = oldQbInventoryConfig.MaxSlots or 30 + local packedWeight = 0 + local addedSlots = 1 + local stackCheck = Inventory.GetItemInfo(item).stack + local playerInv = Framework.GetPlayerInventory(src) + if not playerInv then return false end + for k, v in pairs(playerInv) do + if v.name then + local weight = Inventory.GetItemInfo(v.name).weight or 0 + count = count + v.count + packedWeight = packedWeight + (weight * v.count) + end + end + local slotsUsed = #playerInv + if not stackCheck then addedSlots = count end + if slotsUsed + addedSlots > maxInvSlots then return false end + if packedWeight + (Inventory.GetItemInfo(item).weight or 0) * count > maxInvWeight then return false end + return true +end + return Inventory \ No newline at end of file diff --git a/modules/inventory/qs-inventory/client.lua b/modules/inventory/qs-inventory/client.lua index 35d60e8..a389884 100644 --- a/modules/inventory/qs-inventory/client.lua +++ b/modules/inventory/qs-inventory/client.lua @@ -1,40 +1,40 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('qs-inventory') ~= 'started' then return end +if GetResourceState('qs-inventory') == 'missing' then return end local quasar = exports["qs-inventory"] Inventory = Inventory or {} ----Return the item info in oxs format, {name, label, stack, weight, description, image} ----@param item string ----@return table -Inventory.GetItemInfo = function(item) - local itemsData = quasar:GetItemList() - if not itemsData then return {} end - local itemData = itemsData[item] - if not itemData then return {} end - return { - name = itemData.name or "Missing Name", - label = itemData.label or "Missing Label", - stack = itemData.unique or "false", - weight = itemData.weight or "0", - description = itemData.description or "none", - image = Inventory.GetImagePath(item), - } -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "qs-inventory" end ----This will return the entire items table from the inventory. +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} +---@param item string +---@return table +Inventory.GetItemInfo = function(item) + local itemsData = quasar:GetItemList() + if not itemsData then return {} end + itemsData = itemsData[item] + if not itemsData then return {} end + return { + name = itemsData.name or "Missing Name", + label = itemsData.label or "Missing Label", + stack = itemsData.unique or "false", + weight = itemsData.weight or "0", + description = itemsData.description or "none", + image = Inventory.GetImagePath(item), + } +end + +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return quasar:GetItemList() end ----Will return boolean if the player has the item. +---@description Will return boolean if the player has the item. ---@param item string ---@return boolean Inventory.HasItem = function(item) @@ -42,7 +42,7 @@ Inventory.HasItem = function(item) return check and true or false end ----This will return th count of the item in the players inventory, if not found will return 0. +---@description This will return th count of the item in the players inventory, if not found will return 0. ---@param item string ---@return number Inventory.GetItemCount = function(item) @@ -50,7 +50,7 @@ Inventory.GetItemCount = function(item) return searchItem or 0 end ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -60,7 +60,7 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----This will return the players inventory in the format of {name, label, count, slot, metadata} +---@description This will return the players inventory in the format of {name, label, count, slot, metadata} ---@return table Inventory.GetPlayerInventory = function() local items = {} @@ -69,10 +69,10 @@ Inventory.GetPlayerInventory = function() table.insert(items, { name = v.name, label = v.label, - count = v.amount, + count = v.amount or v.count, slot = v.slot, - metadata = v.info, - stack = v.unique, + metadata = v.info or v.metadata or {}, + stack = v.unique or v.stack or false, close = v.useable, weight = v.weight }) @@ -80,11 +80,4 @@ Inventory.GetPlayerInventory = function() return items end ----comment ----@param id any ----@return nil -Inventory.OpenStash = function(id) - quasar:RegisterStash(id, 50, 50000) -end - return Inventory \ No newline at end of file diff --git a/modules/inventory/qs-inventory/server.lua b/modules/inventory/qs-inventory/server.lua index 0593105..cb7cc4d 100644 --- a/modules/inventory/qs-inventory/server.lua +++ b/modules/inventory/qs-inventory/server.lua @@ -1,12 +1,18 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('qs-inventory') ~= 'started' then return end +if GetResourceState('qs-inventory') == 'missing' then return end local quasar = exports['qs-inventory'] Inventory = Inventory or {} Inventory.Stashes = Inventory.Stashes or {} ----This will add an item, and return true or false based on success +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "qs-inventory" +end + +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number @@ -15,17 +21,13 @@ Inventory.Stashes = Inventory.Stashes or {} ---@return boolean Inventory.AddItem = function(src, item, count, slot, metadata) if not quasar:CanCarryItem(src, item, count) then return false end + local success = quasar:AddItem(src, item, count, slot, metadata) + if not success then return false end TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return quasar:AddItem(src, item, count, slot, metadata) + return success end ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "qs-inventory" -end - ----This will remove an item, and return true or false based on success +---@description This will remove an item, and return true or false based on success ---@param src number ---@param item string ---@param count number @@ -33,46 +35,22 @@ end ---@param metadata table ---@return boolean Inventory.RemoveItem = function(src, item, count, slot, metadata) + local success = quasar:RemoveItem(src, item, count, slot, metadata) + if not success then return false end TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return quasar:RemoveItem(src, item, count, slot, metadata) + return success end ----This will add items to a trunk, and return true or false based on success ----@param identifier string ----@param items table ----@return boolean -Inventory.AddTrunkItems = function(identifier, items) - if type(items) ~= "table" then return false end - return false - --[[ - for k, v in pairs(items) do - -- - In testing this inventory allowed it on owned vehicle but not unowned vehicles, - also attempted registering it as a stash with no luck. - was thinking about just forcing it in sql but there is data attached that I assume is a timestamp - kinda not sure on this one atm... - Also there is no GetInventory(identifier) only by player source - --quasar:AddToTrunk(identifier, v.count, v.metadata, v.item, v.metadata) - end - return true - --]] -end - ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. +---@description This will clear the specified inventory, will always return true unless a value isnt passed correctly. ---@param id string ---@return boolean Inventory.ClearStash = function(id, _type) if type(id) ~= "string" then return false end - if Inventory.Stashes[id] then Inventory.Stashes[id] = nil end - return false - --[[ quasar:ClearOtherInventory(_type, id) - return true - --]] end ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -90,24 +68,23 @@ Inventory.GetItemInfo = function(item) } end ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return quasar:GetItemList() end ----This will return the count of the item in the players inventory, if not found will return 0. ---- ----if metadata is passed it will find the matching items count. +---@description This will return the count of the item in the players inventory, if not found will return 0. ---@param src number ---@param item string ---@param metadata table ---@return number Inventory.GetItemCount = function(src, item, metadata) - return quasar:GetItemTotalAmount(src, item) + if metadata then print("qs-inventory does not support metadata searching for item counts, you will need to get the inventory and parse it manually.") end + return quasar:GetItemTotalAmount(src, item) or 0 end ----This wil return the players inventory. +---@description This wil return the players inventory. ---@param src number ---@return table Inventory.GetPlayerInventory = function(src) @@ -116,20 +93,18 @@ Inventory.GetPlayerInventory = function(src) for _, v in pairs(playerItems) do table.insert(repackedTable, { name = v.name, - count = v.amount, - metadata = v.info, + count = v.amount or v.count, + metadata = v.info or v.metadata or {}, slot = v.slot, }) end return repackedTable end ----Returns the specified slot data as a table. ---- ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) local playerItems = quasar:GetInventory(src) for _, item in pairs(playerItems) do @@ -139,9 +114,9 @@ Inventory.GetItemBySlot = function(src, slot) label = item.label, weight = item.weight, slot = slot, - count = item.amount, - metadata = item.info, - stack = item.unique or false, + count = item.amount or item.count, + metadata = item.info or item.metadata or {}, + stack = item.unique or item.stack or false, description = item.description } end @@ -149,7 +124,7 @@ Inventory.GetItemBySlot = function(src, slot) return {} end ----This will set the metadata of an item in the inventory. +---@description This will set the metadata of an item in the inventory. ---@param src number ---@param item string ---@param slot number @@ -159,62 +134,40 @@ Inventory.SetMetadata = function(src, item, slot, metadata) return quasar:SetItemMetadata(src, slot, metadata) end ----This will open the specified stash for the src passed. +---@description This will open the specified stash for the src passed. ---@param src number ---@param _type string ---@param id number||string ---@return nil Inventory.OpenStash = function(src, _type, id) _type = _type or "stash" + if not Inventory.Stashes[id] then return end local tbl = Inventory.Stashes[id] - TriggerEvent("inventory:server:OpenInventory", _type, id, tbl and { maxweight = tbl.weight, slots = tbl.slots }) + TriggerEvent("inventory:server:OpenInventory", _type, id, tbl and { maxweight = tbl.weight or 5000, slots = tbl.slots or 20 }) TriggerClientEvent("inventory:client:SetCurrentStash",src, id) end ----This will register a stash ----@param id number|string ----@param label string ----@param slots number ----@param weight number ----@param owner string ----@param groups table ----@param coords table ----@return boolean ----@return string|number -Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) - if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } - return true, id -end - ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(src, item) +Inventory.HasItem = function(src, item, requiredCount) local count = quasar:GetItemTotalAmount(src, item) if not count then return false end - return count > 0 + return count >= (requiredCount or 1) end ----This is to get if there is available space in the inventory, will return boolean. +---@description This is to get if there is available space in the inventory, will return boolean. ---@param src number ---@param item string ---@param count number ---@return boolean Inventory.CanCarryItem = function(src, item, count) - return quasar:CanCarryItem(src, item, count) + return quasar:CanCarryItem(src, item, count) or false end ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean @@ -229,7 +182,7 @@ Inventory.UpdatePlate = function(oldplate, newplate) return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) end ----This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) +---@description This will get the image path for an item, it is an alternate option to GetItemInfo. If a image isnt found will revert to community_bridge logo (useful for menus) ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -239,12 +192,4 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end -Inventory.OpenPlayerInventory = function(src, target) - assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end - exports['qs-inventory']:OpenInventory(src, target) -end - return Inventory \ No newline at end of file diff --git a/modules/inventory/tgiann-inventory/client.lua b/modules/inventory/tgiann-inventory/client.lua index aa62432..9f6cab1 100644 --- a/modules/inventory/tgiann-inventory/client.lua +++ b/modules/inventory/tgiann-inventory/client.lua @@ -1,10 +1,17 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('tgiann-inventory') ~= 'started' then return end +if GetResourceState('tgiann-inventory') == 'missing' then return end + local tgiann = exports["tgiann-inventory"] Inventory = Inventory or {} ----Return the item info in oxs format, {name, label, stack, weight, description, image} +---@description This will get the name of the in use resource. +---@return string +Inventory.GetResourceName = function() + return "tgiann-inventory" +end + +---@description Return the item info in oxs format, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -21,20 +28,15 @@ Inventory.GetItemInfo = function(item) } end ----This will get the name of the in use resource. ----@return string -Inventory.GetResourceName = function() - return "tgiann-inventory" -end - ----Will return boolean if the player has the item. +---@description Will return boolean if the player has the item. ---@param item string +---@param requiredCount number (optional) ---@return boolean -Inventory.HasItem = function(item) - return tgiann:HasItem(item) +Inventory.HasItem = function(item, requiredCount) + return tgiann:HasItem(item, requiredCount) end ----This will return th count of the item in the players inventory, if not found will return 0. +---@description This will return their count of the item in the players inventory, if not found will return 0. ---@param item string ---@return number Inventory.GetItemCount = function(item) @@ -42,7 +44,7 @@ Inventory.GetItemCount = function(item) return searchItem or 0 end ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -54,7 +56,7 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----This will return the players inventory in the format of {name, label, count, slot, metadata} +---@description This will return the players inventory in the format of {name, label, count, slot, metadata} ---@return table Inventory.GetPlayerInventory = function() local items = {} @@ -74,10 +76,4 @@ Inventory.GetPlayerInventory = function() return items end ----@param id any ----@return nil -Inventory.OpenStash = function(id) - tgiann:OpenInventory('stash', id, { maxweight = 400000, slots = 100 }) -end - return Inventory \ No newline at end of file diff --git a/modules/inventory/tgiann-inventory/server.lua b/modules/inventory/tgiann-inventory/server.lua index 92f7a59..2d7b629 100644 --- a/modules/inventory/tgiann-inventory/server.lua +++ b/modules/inventory/tgiann-inventory/server.lua @@ -1,43 +1,46 @@ ---@diagnostic disable: duplicate-set-field -if GetResourceState('tgiann-inventory') ~= 'started' then return end +if GetResourceState('tgiann-inventory') == 'missing' then return end local tgiann = exports["tgiann-inventory"] Inventory = Inventory or {} -Inventory.Stashes = Inventory.Stashes or {} ----This will add an item, and return true or false based on success ----@param src number ----@param item string ----@param count number ----@param slot number ----@param metadata table ----@return boolean -Inventory.AddItem = function(src, item, count, slot, metadata) - if not tgiann:CanCarryItem(src, item, count) then return false end - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) - return tgiann:AddItem(src, item, count, slot, metadata, false) -end - ----This will get the name of the in use resource. +---@description This will get the name of the in use resource. ---@return string Inventory.GetResourceName = function() return "tgiann-inventory" end ----This will remove an item, and return true or false based on success +---@description This will add an item, and return true or false based on success ---@param src number ---@param item string ---@param count number ----@param slot number ----@param metadata table +---@param slot number (optional) +---@param metadata table (optional) ---@return boolean -Inventory.RemoveItem = function(src, item, count, slot, metadata) - TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) - return tgiann:RemoveItem(src, item, count, slot, metadata) +Inventory.AddItem = function(src, item, count, slot, metadata) + if not tgiann:CanCarryItem(src, item, count) then return false end + local success = tgiann:AddItem(src, item, count, slot, metadata, false) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "add", item = item, count = count, slot = slot, metadata = metadata}) + return success or false end ----This will return a table with the item info, {name, label, stack, weight, description, image} +---@description This will remove an item, and return true or false based on success +---@param src number +---@param item string +---@param count number +---@param slot number (optional) +---@param metadata table (optional) +---@return boolean +Inventory.RemoveItem = function(src, item, count, slot, metadata) + local success = tgiann:RemoveItem(src, item, count, slot, metadata) + if not success then return false end + TriggerClientEvent("community_bridge:client:inventory:updateInventory", src, {action = "remove", item = item, count = count, slot = slot, metadata = metadata}) + return success or false +end + +---@description This will return a table with the item info, {name, label, stack, weight, description, image} ---@param item string ---@return table Inventory.GetItemInfo = function(item) @@ -53,25 +56,23 @@ Inventory.GetItemInfo = function(item) } end ----This will return the entire items table from the inventory. +---@description This will return the entire items table from the inventory. ---@return table Inventory.Items = function() return tgiann:GetItemList() end ----This will return the count of the item in the players inventory, if not found will return 0. ---- ----if metadata is passed it will find the matching items count. +---@description This will return the count of the item in the players inventory, if not found will return 0. ---@param src number ---@param item string ----@param metadata table +---@param metadata table (optional) ---@return number Inventory.GetItemCount = function(src, item, metadata) local _item = tgiann:GetItemByName(src, item, metadata) return _item.amount or 0 end ----This wil return the players inventory. +---@description This will return the players inventory. ---@param src number ---@return table Inventory.GetPlayerInventory = function(src) @@ -85,12 +86,10 @@ Inventory.GetPlayerInventory = function(src) return items end ----Returns the specified slot data as a table. ---- ----format {weight, name, metadata, slot, label, count} +---@description Returns the specified slot data as a table. ---@param src number ---@param slot number ----@return table +---@return table {weight, name, metadata, slot, label, count} Inventory.GetItemBySlot = function(src, slot) local item = tgiann:GetItemBySlot(src, slot) if not item then return {} end @@ -99,14 +98,14 @@ Inventory.GetItemBySlot = function(src, slot) label = item.label, weight = item.weight, slot = slot, - count = item.amount, - metadata = item.info, - stack = item.unique or false, + count = item.amount or item.count, + metadata = item.info or item.metadata or {}, + stack = item.unique or item.stack or false, description = item.description } end ----This will set the metadata of an item in the inventory. +---@description This will set the metadata of an item in the inventory. ---@param src number ---@param item string ---@param slot number @@ -116,42 +115,18 @@ Inventory.SetMetadata = function(src, item, slot, metadata) tgiann:UpdateItemMetadata(src, item, slot, metadata) end ----This will open the specified stash for the src passed. +---@description This will open the specified stash for the src passed. ---@param src number ---@param _type string ---@param id number||string ---@return nil Inventory.OpenStash = function(src, _type, id) _type = _type or "stash" - local tbl = Inventory.Stashes[id] + local tbl = Inventory.Stashes[id] or {weight = 1000000, slot = 50, label = "Stash"} return tgiann:ForceOpenInventory(src, _type, id, tbl and { maxWeight = tbl.weight , slots = tbl.slot, label = tbl.label}) end ----This will register a stash ----@param id number|string ----@param label string ----@param slots number ----@param weight number ----@param owner string ----@param groups table ----@param coords table ----@return boolean ----@return string|number -Inventory.RegisterStash = function(id, label, slots, weight, owner, groups, coords) - if Inventory.Stashes[id] then return true, id end - Inventory.Stashes[id] = { - id = id, - label = label, - slots = slots, - weight = weight, - owner = owner, - groups = groups, - coords = coords - } - return true, id -end - ----This will return a boolean if the player has the item. +---@description This will return a boolean if the player has the item. ---@param src number ---@param item string ---@return boolean @@ -159,7 +134,7 @@ Inventory.HasItem = function(src, item) return tgiann:HasItem(src, item, 1) end ----This is to get if there is available space in the inventory, will return boolean. +---@description This is to get if there is available space in the inventory, will return boolean. ---@param src number ---@param item string ---@param count number @@ -168,7 +143,7 @@ Inventory.CanCarryItem = function(src, item, count) return tgiann:CanCarryItem(src, item, count) end ----This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) +---@description This will update the plate to the vehicle inside the inventory. (It will also update with jg-mechanic if using it) ---@param oldplate string ---@param newplate string ---@return boolean @@ -184,7 +159,7 @@ Inventory.UpdatePlate = function(oldplate, newplate) return true, exports["jg-mechanic"]:vehiclePlateUpdated(oldplate, newplate) end ----This will add items to a trunk, and return true or false based on success +---@description This will add items to a trunk, and return true or false based on success ---@param identifier string ---@param items table ---@return boolean @@ -197,7 +172,7 @@ Inventory.AddTrunkItems = function(identifier, items) return true end ----This will clear the specified inventory, will always return true unless a value isnt passed correctly. +---@description This will clear the specified inventory, will always return true unless a value isnt passed correctly. ---@param id string ---@return boolean Inventory.ClearStash = function(id, _type) @@ -207,7 +182,7 @@ Inventory.ClearStash = function(id, _type) return true end ----This will get the image path for this item, if not found will return placeholder. +---@description This will get the image path for this item, if not found will return placeholder. ---@param item string ---@return string Inventory.GetImagePath = function(item) @@ -219,30 +194,13 @@ Inventory.GetImagePath = function(item) return imagePath or "https://avatars.githubusercontent.com/u/47620135" end ----UNUSED: ----This will return generic item data from the specified inventory, with the items total count. ---- ----format without metadata { count, stack, name, weight, label } ---- ----fortmat with metadata { count, stack, name, weight, label, metadata } +---@description This will open a players inventory, used for admin purposes and stuff. ---@param src number ----@param item string ----@param metadata table ----@return table -Inventory.GetItem = function(src, item, metadata) - local item = tgiann:GetItemByName(src, item, metadata) - item.count = item.amount - item.metadata = item.info - return item -end - +---@param target number Inventory.OpenPlayerInventory = function(src, target) assert(src, "OpenPlayerInventory: src is required") - if not target then - target = src - end - exports['tgiann-inventory']:OpenInventoryById(src, target) + assert(target, "OpenPlayerInventory: target is required") + tgiann:OpenInventoryById(src, target) end - return Inventory \ No newline at end of file diff --git a/modules/locales/shared.lua b/modules/locales/shared.lua index 4074ac2..8e98e57 100644 --- a/modules/locales/shared.lua +++ b/modules/locales/shared.lua @@ -25,14 +25,14 @@ function Language.Locale(str, ...) -- Handle nested tables via dot notation local current = locales - for part in str:gmatch("[^%.]+") do + for part in str:gmatch("([^%.]+)") do if type(current) ~= "table" then - warn(("Invalid nested locale path: %s"):format(str)) + warn(("Invalid nested locale path: %s for resource: %s"):format(str, resource)) return str end current = current[part] if not current then - warn(("Locale not found for key: %s in language: %s"):format(str, Lang)) + warn(("Locale not found for key: %s in language: %s for resource: %s"):format(str, Lang, resource)) return str end end diff --git a/modules/menu/ox_lib/client.lua b/modules/menu/ox_lib/client.lua index 710dac0..c601069 100644 --- a/modules/menu/ox_lib/client.lua +++ b/modules/menu/ox_lib/client.lua @@ -3,7 +3,7 @@ local configValue = BridgeClientConfig.MenuSystem if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end Menus = Menus or {} -lib = lib or Require("init.lua", "ox_lib") +if not lib then Require('init.lua', 'ox_lib') end ---Converts a QB menu to an Ox menu. ---@param id string The menu ID. diff --git a/modules/menu/wasabi_uikit/client.lua b/modules/menu/wasabi_uikit/client.lua new file mode 100644 index 0000000..78f8ce0 --- /dev/null +++ b/modules/menu/wasabi_uikit/client.lua @@ -0,0 +1,58 @@ +local resourceName = "wasabi_uikit" +local configValue = BridgeClientConfig.MenuSystem +if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end +Menus = Menus or {} + +---Converts a QB menu to an Wasabi menu. +---@param id string The menu ID. +---@param menu table The QB menu data. +---@return table The Wasabi menu data. +local function QBToWasabiMenu(id, menu) + local wasabiMenu = { + id = id, + title = "", + canClose = true, + options = {}, + } + for i, v in pairs(menu) do + if v.isMenuHeader then + if wasabiMenu.title == "" then + wasabiMenu.title = v.header + end + else + local option = { + title = v.header, + description = v.txt, + icon = v.icon, + args = v.params.args, + onSelect = v.action or function(selected, secondary, args) + local params = menu[id]?.options?[selected]?.params + if not params then return end + local event = params.event + local isServer = params.isServer + if not event then return end + if isServer then + return TriggerServerEvent(event, args) + end + return TriggerEvent(event, args) + end + + } + table.insert(wasabiMenu.options, option) + end + end + return wasabiMenu +end + +function OpenMenu(id, data, useQBinput) + if useQBinput then + data = QBToWasabiMenu(id, data) + end + exports.wasabi_uikit:RegisterContextMenu(data) + exports.wasabi_uikit:OpenContextMenu(id) + return data +end + +GetMenuResourceName = function() + return resourceName +end \ No newline at end of file diff --git a/modules/notify/_default/client.lua b/modules/notify/_default/client.lua index 3dc7dc5..ebbcedd 100644 --- a/modules/notify/_default/client.lua +++ b/modules/notify/_default/client.lua @@ -5,18 +5,30 @@ Notify.GetResourceName = function() return "default" end ----This will send a notify message of the type and time passed +---DEPRICATED: PLEASE SWITCH TO Notify.SendNotification +---12/13/25 ---@param message string ---@param _type string ---@param time number ---@return nil Notify.SendNotify = function(message, _type, time) + return Notify.SendNotification(nil, message, _type, time) +end + +---This will send a notify message of the type and time passed +---@param title string +---@param message string +---@param _type string +---@param time number +---@props table optional +---@return nil +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 return Framework.Notify(message, nil, time) end -RegisterNetEvent('community_bridge:Client:Notify', function(message, _type, time) - Notify.SendNotify(message, _type, time) +RegisterNetEvent('community_bridge:Client:Notify', function(title, message, _type, time, props) + Notify.SendNotification(title, message, _type, time, props) end) ---------[[Depricated Stuff Below, please adjust to the HelpText module instead]]-------- diff --git a/modules/notify/_default/server.lua b/modules/notify/_default/server.lua index ddceb67..fb0d7f6 100644 --- a/modules/notify/_default/server.lua +++ b/modules/notify/_default/server.lua @@ -1,17 +1,35 @@ ---@diagnostic disable: duplicate-set-field Notify = Notify or {} ----This will send a notification to the specified player of the passed message and type +Notify.GetResourceName = function() + return "default" +end + +---DEPRICATED: PLEASE SWITCH TO Notify.SendNotification +---12/13/25 ---@param src number ---@param message string ---@param _type string ---@param time number +---@return nil Notify.SendNotify = function(src, message, _type, time) - TriggerClientEvent('community_bridge:Client:Notify', src, message, _type, time) + Notify.SendNotification(src, nil, message, _type, time) end -Notify.GetResourceName = function() - return "default" +---This will send a notify message of the type and time passed +---@param src number +---@param title string +---@param message string +---@param _type string +---@param time number +---@props table optional +---@return nil +Notify.SendNotification = function(src, title, message, _type, time, props) + time = time or 3000 + if not title then + title = Bridge.Language.Locale("Notifications.PlaceholderTitle") + end + TriggerClientEvent('community_bridge:Client:Notify', src, title, message, _type, time, props) end ---------[[Depricated Stuff Below, please adjust to the HelpText module instead]]-------- diff --git a/modules/notify/brutal_notify/client.lua b/modules/notify/brutal_notify/client.lua index d40104f..1ed7bdf 100644 --- a/modules/notify/brutal_notify/client.lua +++ b/modules/notify/brutal_notify/client.lua @@ -10,13 +10,16 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 - return exports['brutal_notify']:SendAlert('Notification', message, time, _type or "success", false) + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end + return exports['brutal_notify']:SendAlert(title, message, time, _type or "success", false) end return Notify \ No newline at end of file diff --git a/modules/notify/fl-notify/client.lua b/modules/notify/fl-notify/client.lua index 68d9cd3..5aa54bd 100644 --- a/modules/notify/fl-notify/client.lua +++ b/modules/notify/fl-notify/client.lua @@ -4,18 +4,20 @@ local resourceName = "FL-Notify" local configValue = BridgeSharedConfig.Notify if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end - Notify.GetResourceName = function() return resourceName end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end if _type == "error" or _type == "info" then _type = tostring(1) elseif _type == "success" then diff --git a/modules/notify/lation_ui/client.lua b/modules/notify/lation_ui/client.lua index 186ec79..336b603 100644 --- a/modules/notify/lation_ui/client.lua +++ b/modules/notify/lation_ui/client.lua @@ -10,13 +10,16 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 - return exports.lation_ui:notify({ message = message, type = _type or "success", duration = time, position = 'top-right' }) + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end + return exports.lation_ui:notify({ title = title, message = message, type = _type or "success", duration = time, position = 'top-right' }) end return Notify \ No newline at end of file diff --git a/modules/notify/mythic_notify/client.lua b/modules/notify/mythic_notify/client.lua index e1d7585..df083f5 100644 --- a/modules/notify/mythic_notify/client.lua +++ b/modules/notify/mythic_notify/client.lua @@ -9,12 +9,15 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end _type = _type or "inform" return exports['mythic_notify']:SendAlert(_type, message, time) end diff --git a/modules/notify/okokNotify/client.lua b/modules/notify/okokNotify/client.lua index 4c7d2fa..a5bcb23 100644 --- a/modules/notify/okokNotify/client.lua +++ b/modules/notify/okokNotify/client.lua @@ -9,13 +9,16 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 - return exports['okokNotify']:Alert('Notification', message, time, _type or "Success", false) + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end + return exports['okokNotify']:Alert(title, message, time, _type or "Success", false) end return Notify \ No newline at end of file diff --git a/modules/notify/ox_lib/client.lua b/modules/notify/ox_lib/client.lua index 99838b3..a946cb3 100644 --- a/modules/notify/ox_lib/client.lua +++ b/modules/notify/ox_lib/client.lua @@ -4,19 +4,21 @@ local resourceName = "ox_lib" local configValue = BridgeSharedConfig.Notify if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end - Notify.GetResourceName = function() return resourceName end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 - return exports.ox_lib:notify({ description = message, type = _type, duration = time, position = 'top-right' }) + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end + return exports.ox_lib:notify({ title = title, description = message, type = _type or "success", duration = time, position = 'top-right' }) end return Notify \ No newline at end of file diff --git a/modules/notify/pNotify/client.lua b/modules/notify/pNotify/client.lua index a79f24b..138878b 100644 --- a/modules/notify/pNotify/client.lua +++ b/modules/notify/pNotify/client.lua @@ -9,13 +9,16 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 - return exports['pNotify']:SendNotification({ text = message, type = _type, timeout = time, layout = 'centerRight' }) + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end + return exports['pNotify']:SendNotification({ title = title, text = message, type = _type or "success", timeout = time, layout = 'centerRight' }) end return Notify \ No newline at end of file diff --git a/modules/notify/r_notify/client.lua b/modules/notify/r_notify/client.lua index d8305a8..fd2fc38 100644 --- a/modules/notify/r_notify/client.lua +++ b/modules/notify/r_notify/client.lua @@ -9,13 +9,16 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 - return exports.r_notify:notify({title = 'Notification', content = message, type = _type, icon = "fas fa-check", duration = time, position = 'top-right', sound = false}) + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end + return exports.r_notify:notify({title = title, content = message, type = _type or "success", icon = "fas fa-check", duration = time, position = 'top-right', sound = false}) end return Notify \ No newline at end of file diff --git a/modules/notify/t-notify/client.lua b/modules/notify/t-notify/client.lua index c300adc..43d4a36 100644 --- a/modules/notify/t-notify/client.lua +++ b/modules/notify/t-notify/client.lua @@ -9,14 +9,17 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end _type = _type or "info" - return exports['t-notify']:Alert({ style = _type, message = message, duration = time, }) + return exports['t-notify']:Alert({ title = title, style = _type, message = message, duration = time, }) end return Notify \ No newline at end of file diff --git a/modules/notify/wasabi_notify/client.lua b/modules/notify/wasabi_notify/client.lua index 21dedc8..e3b777e 100644 --- a/modules/notify/wasabi_notify/client.lua +++ b/modules/notify/wasabi_notify/client.lua @@ -9,12 +9,15 @@ Notify.GetResourceName = function() end ---This will send a notify message of the type and time passed +---@param title string ---@param message string ---@param _type string ---@param time number +---@props table optional ---@return nil -Notify.SendNotify = function(message, _type, time) +Notify.SendNotification = function(title, message, _type, time, props) time = time or 3000 + if not title then title = Bridge.Language.Locale("Notifications.PlaceholderTitle") end _type = _type or "info" return exports.wasabi_notify:notify(_type, message, time, _type) end diff --git a/modules/phone/_default/client.lua b/modules/phone/_default/client.lua index 529df0c..5e921a2 100644 --- a/modules/phone/_default/client.lua +++ b/modules/phone/_default/client.lua @@ -17,7 +17,7 @@ end ---@param message string ---@return boolean Phone.SendEmail = function(email, title, message) - return false, Print.Error('There Is No Phone Bridged.') + return false, print('^6 There is no phone bridged in community_bridge. ^0') end return Phone \ No newline at end of file diff --git a/modules/phone/_default/server.lua b/modules/phone/_default/server.lua index c945be4..b00de31 100644 --- a/modules/phone/_default/server.lua +++ b/modules/phone/_default/server.lua @@ -15,7 +15,7 @@ end ---@param src number ---@return number|boolean Phone.GetPlayerPhone = function(src) - return false, Print.Error('There Is No Phone Bridged.') + return false, print('^6 There is no phone bridged in community_bridge. ^0') end ---This will send an email to the passed source, email address, title and message. @@ -25,7 +25,7 @@ end ---@param message string ---@return boolean Phone.SendEmail = function(src, email, title, message) - return false, Print.Error('There Is No Phone Bridged.') + return false, print('^6 There is no phone bridged in community_bridge. ^0') end return Phone \ No newline at end of file diff --git a/modules/phone/lb-phone/server.lua b/modules/phone/lb-phone/server.lua index 2b03f4a..337a263 100644 --- a/modules/phone/lb-phone/server.lua +++ b/modules/phone/lb-phone/server.lua @@ -28,21 +28,20 @@ end ---@return boolean Phone.SendEmail = function(src, email, title, message) local numberNumber = exports["lb-phone"]:GetEquippedPhoneNumber(src) - if not numberNumber then return false, Prints.Error("Could not Find Phone number") end + if not numberNumber then return false, print(" ^6 Could not Find Phone number ^0") end local playerEmail = exports["lb-phone"]:GetEmailAddress(numberNumber) - if not playerEmail then return false, Prints.Error("Could not Find email") end + if not playerEmail then return false, print(" ^6 Could not Find email ^0") end local success, id = exports["lb-phone"]:SendMail({ to = playerEmail, sender = email, subject = title, message = message, }) - return success + return success or false end RegisterNetEvent('community_bridge:Server:genericEmail', function(data) local src = source - Prints.Debug('community_bridge:Server:genericEmail Hit') return Phone.SendEmail(src, data.email, data.title, data.message) end) diff --git a/modules/phone/qb-phone/client.lua b/modules/phone/qb-phone/client.lua new file mode 100644 index 0000000..102e735 --- /dev/null +++ b/modules/phone/qb-phone/client.lua @@ -0,0 +1,30 @@ +---@diagnostic disable: duplicate-set-field +local resourceName = "qb-phone" +if GetResourceState(resourceName) == 'missing' then return end +if GetResourceState("lb-phone") ~= 'missing' then return end +if GetResourceState("gksphone") ~= 'missing' then return end +if GetResourceState("okokPhone") ~= 'missing' then return end +if GetResourceState("qs-smartphone") ~= 'missing' then return end +if GetResourceState("yseries") ~= 'missing' then return end +Phone = Phone or {} + +---This will get the name of the Phone system being being used. +---@return string +Phone.GetPhoneName = function() + return resourceName +end + +Phone.GetResourceName = function() + return resourceName +end + +---This will send an email to the passed email address with the title and message. +---@param email string +---@param title string +---@param message string +---@return boolean +Phone.SendEmail = function(email, title, message) + TriggerServerEvent('community_bridge:Server:genericEmail', {email = email, title = title, message = message}) +end + +return Phone \ No newline at end of file diff --git a/modules/phone/qb-phone/server.lua b/modules/phone/qb-phone/server.lua new file mode 100644 index 0000000..ad2f30e --- /dev/null +++ b/modules/phone/qb-phone/server.lua @@ -0,0 +1,48 @@ +---@diagnostic disable: duplicate-set-field +local resourceName = "qb-phone" +if GetResourceState(resourceName) == 'missing' then return end +if GetResourceState("lb-phone") ~= 'missing' then return end +if GetResourceState("gksphone") ~= 'missing' then return end +if GetResourceState("okokPhone") ~= 'missing' then return end +if GetResourceState("qs-smartphone") ~= 'missing' then return end +if GetResourceState("yseries") ~= 'missing' then return end +Phone = Phone or {} + +---This will get the name of the Phone system being being used. +---@return string +Phone.GetPhoneName = function() + return resourceName +end + +Phone.GetResourceName = function() + return resourceName +end + +---This will get the phone number of the passed source. +---@param src number +---@return number|boolean +Phone.GetPlayerPhone = function(src) + return Bridge.Framework.GetPlayerPhone(src) or false +end + +---This will send an email to the passed source, email address, title and message. +---@param src number +---@param email string +---@param title string +---@param message string +---@return boolean +Phone.SendEmail = function(src, email, title, message) + local identifier = Bridge.Framework.GetPlayerIdentifier(src) + if not identifier then return false, print(" ^6 Could not Find Player Identifier ^0") end + + local mailData = { sender = email, subject = title, message = message } + exports["qb-phone"]:sendNewMailToOffline(identifier, mailData) + return true +end + +RegisterNetEvent('community_bridge:Server:genericEmail', function(data) + local src = source + return Phone.SendEmail(src, data.email, data.title, data.message) +end) + +return Phone \ No newline at end of file diff --git a/modules/progressbar/_default/client.lua b/modules/progressbar/_default/client.lua new file mode 100644 index 0000000..7b4dc07 --- /dev/null +++ b/modules/progressbar/_default/client.lua @@ -0,0 +1,18 @@ +---@diagnostic disable: duplicate-set-field +local resourceName = "default" +ProgressBar = ProgressBar or {} + +---This function opens a progress bar. +---@param options table +---@param cb any +---@param isQBInput boolean||optional +---@return boolean +function ProgressBar.Open(options, cb, isQBInput) + return true, print("No supported progress bar system found.") +end + +ProgressBar.GetResourceName = function() + return resourceName +end + +return ProgressBar \ No newline at end of file diff --git a/modules/progressbar/keep-progressbar/client.lua b/modules/progressbar/keep-progressbar/client.lua new file mode 100644 index 0000000..6bf9ada --- /dev/null +++ b/modules/progressbar/keep-progressbar/client.lua @@ -0,0 +1,71 @@ +---@diagnostic disable: duplicate-set-field +local resourceName = "keep-progressbar" +local configValue = BridgeClientConfig.ProgressBarSystem +if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end + +ProgressBar = ProgressBar or {} + +---This function converts a QB progress bar options table to an Ox progress bar options table. +---@param options table +---@return table +local function convertFromQB(options) + if not options then return options end + local prop1 = options.prop or {} + local prop2 = options.propTwo or {} + local props = { + { + model = prop1.model, + bone = prop1.bone, + pos = prop1.coords, + rot = prop1.rotation, + }, + { + model = prop2.model, + bone = prop2.bone, + pos = prop2.coords, + rot = prop2.rotation, + } + } + return { + duration = options.duration, + label = options.label, + position = 'bottom', + useWhileDead = options.useWhileDead, + canCancel = options.canCancel, + disable = { + move = options.controlDisables?.disableMovement, + car = options.controlDisables?.disableCarMovement, + combat = options.controlDisables?.disableCombat, + mouse = options.controlDisables?.disableMouse + }, + anim = { + dict = options.animation?.animDict, + clip = options.animation?.anim, + flag = options.animation?.flags or 49, + }, + prop = props, + } +end + +---This function opens a progress bar. +---@param options table +---@param cb any +---@param isQBInput boolean||optional +---@return boolean +function ProgressBar.Open(options, cb, isQBInput) + if isQBInput then + options = convertFromQB(options) + end + + local style = options.style or 'bar' + local success = style == 'circle' and exports['keep-progressbar']:ox_lib_progressBar(options) or exports['keep-progressbar']:ox_lib_progressBar(options) + + if cb then cb(success) end + return success +end + +ProgressBar.GetResourceName = function() + return resourceName +end + +return ProgressBar \ No newline at end of file diff --git a/modules/progressbar/ox_lib/client.lua b/modules/progressbar/ox_lib/client.lua index 96ba26b..1fc6903 100644 --- a/modules/progressbar/ox_lib/client.lua +++ b/modules/progressbar/ox_lib/client.lua @@ -65,7 +65,7 @@ function ProgressBar.Open(options, cb, isQBInput) end ProgressBar.GetResourceName = function() - return "ox_lib" + return resourceName end return ProgressBar \ No newline at end of file diff --git a/modules/progressbar/wasabi_uikit/client.lua b/modules/progressbar/wasabi_uikit/client.lua new file mode 100644 index 0000000..64e8409 --- /dev/null +++ b/modules/progressbar/wasabi_uikit/client.lua @@ -0,0 +1,71 @@ +---@diagnostic disable: duplicate-set-field +local resourceName = "wasabi_uikit" +local configValue = BridgeClientConfig.ProgressBarSystem +if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end + +ProgressBar = ProgressBar or {} + +---This function converts a QB progress bar options table to an Ox progress bar options table. +---@param options table +---@return table +local function convertFromQB(options) + if not options then return options end + local prop1 = options.prop or {} + local prop2 = options.propTwo or {} + local props = { + { + model = prop1.model, + bone = prop1.bone, + pos = prop1.coords, + rot = prop1.rotation, + }, + { + model = prop2.model, + bone = prop2.bone, + pos = prop2.coords, + rot = prop2.rotation, + } + } + return { + duration = options.duration, + label = options.label, + position = 'bottom', + useWhileDead = options.useWhileDead, + canCancel = options.canCancel, + disable = { + move = options.controlDisables?.disableMovement, + car = options.controlDisables?.disableCarMovement, + combat = options.controlDisables?.disableCombat, + mouse = options.controlDisables?.disableMouse + }, + anim = { + dict = options.animation?.animDict, + clip = options.animation?.anim, + flag = options.animation?.flags or 49, + }, + prop = props, + } +end + +---This function opens a progress bar. +---@param options table +---@param cb any +---@param isQBInput boolean||optional +---@return boolean +function ProgressBar.Open(options, cb, isQBInput) + if isQBInput then + options = convertFromQB(options) + end + + local style = options.style or 'bar' + local success = style == 'circle' and exports.wasabi_uikit:ProgressBar(options, 'circle') or exports.wasabi_uikit:ProgressBar(options, 'bar') + + if cb then cb(success) end + return success +end + +ProgressBar.GetResourceName = function() + return resourceName +end + +return ProgressBar \ No newline at end of file diff --git a/modules/shops/_default/client.lua b/modules/shops/_default/client.lua index 84dd8f9..0f63e53 100644 --- a/modules/shops/_default/client.lua +++ b/modules/shops/_default/client.lua @@ -1,46 +1,57 @@ ---@diagnostic disable: duplicate-set-field Shops = Shops or {} -RegisterNetEvent('community_bridge:openShop', function(_type, _title, shopData) +---This is an internal event used to be hit from server for the shop context menus. Please do not use this event directly. +---@param shopType string +---@param shopLabel string +---@param shopData table +RegisterNetEvent('community_bridge:Client:openShop', function(shopType, shopLabel, shopData) if source ~= 65535 then return end - if not _title and not _title and not shopData then return end - if _type ~= 'shop' then return end - Shops.OpenShop(_title, shopData.inventory) + if not shopType or not shopLabel or not shopData then return end + if shopType ~= 'shop' then return end + Shops.OpenShop(shopLabel, shopData.inventory) end) ----This is an internal event that is used to complete a transaction and offer cash/card pay +---This is an internal function that is used to complete a transaction and offer cash/card pay. Please do not use this function directly. +---@param shopName string +---@param item string +---@param itemLabel string +---@param price number +---@param amount number Shops.FinalizeCheckOut = function(shopName, item, itemLabel, price, amount) if not shopName and not item and not itemLabel and not price then return end - local mathStuff = tonumber(price) * tonumber(amount) + local mathStuff = (tonumber(price) * tonumber(amount)) local generatedID = Ids.CreateUniqueId() local buildMenu = { { - title = string.format(locale('Shops.PayByCash'), tostring(mathStuff)), - description = string.format(locale('Shops.AreYouSure'), itemLabel), + title = locale('Shops.PayByCash', tostring(mathStuff)), + description = locale('Shops.AreYouSure', itemLabel), icon = locale('Shops.CashIcon'), onSelect = function(_, __, ___) - TriggerServerEvent('community_bridge:completeCheckout', shopName, item, amount, "money") + TriggerServerEvent('community_bridge:Server:completeCheckout', shopName, item, amount, "money") end }, { - title = string.format(locale('Shops.PayByCard'), tostring(mathStuff)), - description = string.format(locale('Shops.AreYouSure'), itemLabel), + title = locale('Shops.PayByCard', tostring(mathStuff)), + description = locale('Shops.AreYouSure', itemLabel), icon = locale('Shops.CardIcon'), onSelect = function(_, __, ___) - TriggerServerEvent('community_bridge:completeCheckout', shopName, item, amount, "bank") + TriggerServerEvent('community_bridge:Server:completeCheckout', shopName, item, amount, "bank") end } } Menu.Open({ id = generatedID, title = locale("Shops.Input"), options = buildMenu }, false) end ----This is an internal event that is used to open the amount select menu +---This is an internal functions that is used to open the amount select menu. Please do not use this function directly. ---@param shopName string ---@param item string ---@param itemLabel string ---@param price number Shops.AmountSelect = function(shopName, item, itemLabel, price) if not shopName and not item and not itemLabel and not price then return end + if not tonumber(price) then return end + if price <= 0 then return end local numberOptions = {} for i = 1, 100 do table.insert(numberOptions, {label = tostring(i), value = i}) @@ -54,28 +65,27 @@ Shops.AmountSelect = function(shopName, item, itemLabel, price) end end ----This will open a shop with the passed title and data. It will create a menu with the items in the shopData table. The items will be clickable and will open a checkout menu. +---This will open a shop with the passed shopName and data. It will create a menu with the items in the shopData table. The items will be clickable and will open a checkout menu. ---This also verifies the shop exsists and was made first server side. This will not work when only used client side and the server side verifies the item exsists in the table as well as the shop id. ----@param title any ----@param shopData any +---@param shopName string +---@param shopData table ---@return nil -Shops.OpenShop = function(title, shopData) - if not title and not shopData and not title then return Prints.Error("No Title Passed") end +Shops.OpenShop = function(shopName, shopData) + if not shopName and not shopData then return print("^6 No Shop Name or Shop Data Passed ^0") end local generatedID = Ids.CreateUniqueId() local buildMenu = {} for _, v in pairs(shopData) do local getItemName = Inventory.GetItemInfo(v.name).label table.insert(buildMenu, { title = getItemName, - description = string.format(locale('Shops.CurrencySymbol'), tostring(v.price)), + description = locale('Shops.CurrencySymbol', tostring(v.price)), icon = locale('Shops.ShopIcon'), onSelect = function(selected, secondary, args) - Shops.AmountSelect(title, v.name, getItemName, v.price) - --Shops.FinalizeCheckOut(title, v.name, getItemName, v.price) + Shops.AmountSelect(shopName, v.name, getItemName, v.price) end }) end - Menu.Open({ id = generatedID, title = title, options = buildMenu }, false) + Menu.Open({ id = generatedID, title = shopName, options = buildMenu }, false) end return Shops \ No newline at end of file diff --git a/modules/shops/_default/server.lua b/modules/shops/_default/server.lua index 768bc5a..f6ef0c8 100644 --- a/modules/shops/_default/server.lua +++ b/modules/shops/_default/server.lua @@ -3,41 +3,46 @@ Shops = Shops or {} local registeredShops = {} +local Language = Language or Require("modules/locales/shared.lua") +local locales = Language.Locale + ---This can open a shop for the client ---@param src number ----@param shopTitle string +---@param shopName string ---@return boolean -Shops.OpenShop = function(src, shopTitle) - if not shopTitle and not registeredShops[shopTitle] then return false end - TriggerClientEvent('community_bridge:openShop', src, 'shop', shopTitle, registeredShops[shopTitle]) +Shops.OpenShop = function(src, shopName) + if not shopName and not registeredShops[shopName] then return false, print("community_bridge PLAYERID "..src.." attempted to open invalid shop: "..shopName) end + TriggerClientEvent('community_bridge:Client:openShop', src, 'shop', shopName, registeredShops[shopName]) return true end ---This will create a shop to use on the client side, shops must be registered server side and exsist in the shop inventory table to allow any purchases passed. ----@param shopTitle string +---@param shopName string ---@param shopInventory table ---@param shopCoords table ---@param shopGroups table ---@return boolean -Shops.CreateShop = function(shopTitle, shopInventory, shopCoords, shopGroups) - if not shopTitle and not shopInventory and not shopCoords then return false end - if registeredShops[shopTitle] then return true end - registeredShops[shopTitle] = {name = shopTitle, inventory = shopInventory, shopCoords = shopCoords, groups = shopGroups} +Shops.CreateShop = function(shopName, shopInventory, shopCoords, shopGroups) + if not shopName and not shopInventory and not shopCoords then return false end + if registeredShops[shopName] then return true end + registeredShops[shopName] = {name = shopName, inventory = shopInventory, shopCoords = shopCoords, groups = shopGroups} return true end ----This is an internal event to complete a shop transaction, it will verify pass items and amounts are registered to the created shop. +---This is an internal event to complete a shop transaction, it will verify pass items and amounts are registered to the created shop. Please do not use this function directly. ---@param src number ---@param shopName string ---@param item string ---@param amount number ----@param paymentType string +---@param account string ---@return nil -Shops.CompleteCheckout = function(src, shopName, item, amount, paymentType) - if not src and not shopName and not item and not amount and not paymentType then return end - local ilocale = Language.Locale +Shops.CompleteCheckout = function(src, shopName, item, amount, account) + if not src or not shopName or not item or not amount or not account then return end + if not amount or amount <= 0 then return end + local shopData = registeredShops[shopName] if not shopData then return end + local itemData = nil for _, data in pairs(shopData.inventory) do if data.name == item then @@ -45,22 +50,38 @@ Shops.CompleteCheckout = function(src, shopName, item, amount, paymentType) break end end - if not itemData then return Prints.Error("Player ID "..src.." Is Possibly A Cheater And Has Attempted To Purchase A "..item) end - if not itemData.price then return end - local balance = Framework.GetAccountBalance(src, paymentType) - local mathStuff = tonumber(itemData.price) * tonumber(amount) - if balance < mathStuff then return Notify.SendNotify(src, ilocale('Shops.NotEnoughMoney'), "error", 5000) end - if not Framework.RemoveAccountBalance(src, paymentType, mathStuff) then return end - Inventory.AddItem(src, itemData.name, tonumber(amount)) - local itemLabel = Inventory.GetItemInfo(itemData.name).label - Notify.SendNotify(src, ilocale('Shops.PurchasedItem')..itemLabel, "success", 5000) + if not itemData or not itemData.price then return print("community_bridge Player ID "..src.." attempted to purchase invalid item from shop: "..shopName) end + if itemData.count and itemData.count <= 0 then return Notify.SendNotify(src, locales('Shops.NotEnoughStock'), "error", 5000) end + local totalCost = tonumber(itemData.price) * amount + local balance = Framework.GetAccountBalance(src, account) + if not balance then return end + if balance <= 0 then return Notify.SendNotify(src, locales('Shops.NotEnoughMoney'), "error", 5000) end + if balance < totalCost then return Notify.SendNotify(src, locales('Shops.NotEnoughMoney'), "error", 5000) end + + if not Framework.RemoveAccountBalance(src, account, totalCost) then return end + + local success = Inventory.AddItem(src, itemData.name, amount) + if not success then + Framework.AddAccountBalance(src, account, totalCost) + return Notify.SendNotify(src, locales('Shops.PurchaseFailed'), "error", 5000) + end + + local itemLabel = Inventory.GetItemInfo(itemData.name).label or itemData.name + Notify.SendNotify(src, locales('Shops.PurchasedItem', itemLabel), "success", 5000) end -RegisterNetEvent("community_bridge:completeCheckout", function(shopName, item, amount, paymentType) +---This is an internal event to complete a checkout, complete with multiple validations. Please do not use this event directly. +---@param shopName string +---@param item string +---@param amount number +---@param account string +RegisterNetEvent("community_bridge:Server:completeCheckout", function(shopName, item, amount, account) local src = source - if not shopName and not item and not paymentType then return end - if not paymentType == "money" or not paymentType == "bank" then return end - Shops.CompleteCheckout(src, shopName, item, amount, paymentType) + if not shopName or not item or not account or not amount then return end + if account ~= "money" and account ~= "bank" then return end + amount = tonumber(amount) + if not amount or amount <= 0 then return end + Shops.CompleteCheckout(src, shopName, item, amount, account) end) -return Shops +return Shops \ No newline at end of file diff --git a/modules/skills/_default/client.lua b/modules/skills/_default/client.lua index 3acf9ae..15cd0cb 100644 --- a/modules/skills/_default/client.lua +++ b/modules/skills/_default/client.lua @@ -47,7 +47,7 @@ end ---@return number Skills.GetSkillLevel = function(skillName) if not skillName then return 0 end - local plyrSkills = Framework.GetPlayerMetaData("community_bridge_skills") + local plyrSkills = Bridge.Framework.GetPlayerMetaData("community_bridge_skills") if not plyrSkills or not plyrSkills[skillName] then return 1 end return plyrSkills[skillName].level or 1 end @@ -57,7 +57,7 @@ end ---@return number Skills.GetXP = function(skillName) if not skillName then return 0 end - local plyrSkills = Framework.GetPlayerMetaData("community_bridge_skills") + local plyrSkills = Bridge.Framework.GetPlayerMetaData("community_bridge_skills") if not plyrSkills or not plyrSkills[skillName] then return 1 end return plyrSkills[skillName].currentXP or 1 end diff --git a/modules/target/_default/client.lua b/modules/target/_default/client.lua index ef3f214..d554be4 100644 --- a/modules/target/_default/client.lua +++ b/modules/target/_default/client.lua @@ -76,13 +76,12 @@ Target.AddLocalEntity = function(entities, _options) end for _, entity in pairs(entities) do local id = Ids.RandomString() - local menuData = { id = id, title = "Options", options = {} } + local title = Language.Locale("target.title") + local menuData = { id = id, title = title, options = {} } for k, v in pairs(fixedOptions) do table.insert(menuData.options, { - title = ("Option " .. k), - description = "No Description", - icon = v.icon or "fas fa-code-pull-request", - args = {}, + title = title .. " " .. k, + description = Language.Locale("target.description"), onSelect = function(selected, secondary, args) if v.onSelect then v.onSelect(selected, secondary, args) @@ -90,23 +89,25 @@ Target.AddLocalEntity = function(entities, _options) end }) end - Point.Register(id, entity, 5, args, - function() + Point.Register(id, entity, 5, nil, function() local coords = GetEntityCoords(entity) local sleep = 3000 - while DoesEntityExist(entity) do - Wait(sleep) - local distance = #(coords - GetEntityCoords(PlayerPedId())) - if distance < 10 then - sleep = 0 - Utility.Draw3DHelpText(coords, "Press [E] To Interact", 0.35) - if IsControlJustPressed(0, 38) then - Menu.Open(menuData, false) + local test = Language.Locale("target.interact") + CreateThread(function() + while DoesEntityExist(entity) do + Wait(sleep) + local distance = #(coords - GetEntityCoords(PlayerPedId())) + if distance < 2 then + sleep = 0 + Utility.Draw3DHelpText(coords, test, 0.35) + if IsControlJustPressed(0, 38) then + Menu.Open(menuData, false) + end + else + sleep = 1000 end - else - sleep = 3000 end - end + end) end, function() Point.Remove(id) @@ -121,13 +122,14 @@ Target.AddModel = function(models, options) end Target.AddBoxZone = function(name, coords, size, heading, options) - local fixedOptions = Target.FixOptions(_options) + local fixedOptions = Target.FixOptions(options) local id = Ids.RandomString() - local menuData = { id = id, title = "Options", options = {} } + local title = Bridge.Language.Locale("target.title") + local menuData = { id = id, title = title, options = {} } for k, v in pairs(fixedOptions) do table.insert(menuData.options, { - title = ("Option " .. k), - description = "No Description", + title = title .. " " .. k, + description = Bridge.Language.Locale("target.description"), onSelect = function(selected, secondary, args) if v.onSelect then v.onSelect(selected, secondary, args) @@ -135,26 +137,27 @@ Target.AddBoxZone = function(name, coords, size, heading, options) end }) end - Point.Register(id, coords, 5, args, + local inZone = false + Point.Register(id, coords, 5, nil, function() local sleep = 3000 - while true do + while inZone do Wait(sleep) local distance = #(coords - GetEntityCoords(PlayerPedId())) if distance < 10 then sleep = 0 - Utility.Draw3DHelpText(coords, "Press [E] To Interact", 0.35) + Utility.Draw3DHelpText(coords, Bridge.Language.Locale("target.interact"), 0.35) if IsControlJustPressed(0, 38) then Menu.Open(menuData, false) end - else - sleep = 3000 end end end, function() + inZone = false Point.Remove(id) - end, function() + end, + function() --No need for this in this one end) end diff --git a/modules/target/ox_target/client.lua b/modules/target/ox_target/client.lua index f98c26b..639c18c 100644 --- a/modules/target/ox_target/client.lua +++ b/modules/target/ox_target/client.lua @@ -2,25 +2,23 @@ local resourceName = "ox_target" if GetResourceState(resourceName) == 'missing' then return end -local targetDebug = false -local function detectDebugEnabled() - if BridgeSharedConfig.DebugLevel == 2 then - targetDebug = true - end -end - -detectDebugEnabled() +Target = Target or {} +local targetDebug = BridgeSharedConfig and BridgeSharedConfig.DebugLevel == 2 or false local ox_target = exports.ox_target local targetZones = {} Target = Target or {} +Target.GetResourceName = function() + return "ox_target" +end + ---This is an internal function that is used to fix the options passed to fit alternative target systems, for example qb-ox or ox-qb etc. ---@param options table ---@return table Target.FixOptions = function(options) - for k, v in pairs(options) do + for _, v in pairs(options) do local action = v.onSelect or v.action if not action then local _type = v.type @@ -37,17 +35,15 @@ Target.FixOptions = function(options) return action(entityOrData) end v.onSelect = select - end v.groups = v.job or v.groups - local optionsCanInteract = v.canInteract - if optionsCanInteract then + local optionsCanInteract = v.canInteract + if optionsCanInteract then local id = Target.CreateCanInteract(optionsCanInteract) v.canInteract = function(...) return Target.CanInteract(id, ...) end end - -- print(json.encode(v)) end return options end @@ -205,8 +201,4 @@ AddEventHandler('onResourceStop', function(resource) targetZones = {} end) -Target.GetResourceName = function() - return "ox_target" -end - return Target \ No newline at end of file diff --git a/modules/target/qb-target/client.lua b/modules/target/qb-target/client.lua index 6dc9adb..4a8fa90 100644 --- a/modules/target/qb-target/client.lua +++ b/modules/target/qb-target/client.lua @@ -1,22 +1,21 @@ ---@diagnostic disable: duplicate-set-field local resourceName = "qb-target" if GetResourceState(resourceName) == 'missing' then return end -if GetResourceState("ox_target") == 'started' then return end +if GetResourceState("ox_target") ~= 'missing' then return end -local targetDebug = false -local function detectDebugEnabled() - if BridgeSharedConfig.DebugLevel == 2 then - targetDebug = true - end -end - -detectDebugEnabled() +Target = Target or {} +local targetDebug = BridgeSharedConfig and BridgeSharedConfig.DebugLevel == 2 or false local targetZones = {} Target = Target or {} + local qb_target = exports['qb-target'] +Target.GetResourceName = function() + return "qb-target" +end + function GetLargestDistance(data) local largestDistance = -1 for _, v in pairs(data) do @@ -50,8 +49,8 @@ Target.FixOptions = function(options) options[k].action = select options[k].job = v.job or v.groups options[k].jobType = v.jobType - local optionsCanInteract = v.canInteract - if optionsCanInteract then + local optionsCanInteract = v.canInteract + if optionsCanInteract then local id = Target.CreateCanInteract(optionsCanInteract) v.canInteract = function(...) return Target.CanInteract(id, ...) @@ -188,6 +187,7 @@ Target.AddBoxZone = function(name, coords, size, heading, options, debug) distance = GetLargestDistance(options), }) table.insert(targetZones, { name = name, creator = GetInvokingResource() }) + return name end ---This will add a circle zone to the target system. This is useful for when you want to add target options to a specific area. @@ -205,6 +205,7 @@ Target.AddSphereZone = function(name, coords, radius, options, debug) distance = GetLargestDistance(options), }) table.insert(targetZones, { name = name, creator = GetInvokingResource() }) + return name end ---This will remove target options from a specific zone. @@ -230,8 +231,4 @@ AddEventHandler('onResourceStop', function(resource) targetZones = {} end) -Target.GetResourceName = function() - return "qb-target" -end - return Target \ No newline at end of file diff --git a/modules/vehicleKey/_default/client/client.lua b/modules/vehiclekey/_default/client/client.lua similarity index 100% rename from modules/vehicleKey/_default/client/client.lua rename to modules/vehiclekey/_default/client/client.lua diff --git a/modules/vehicleKey/cd_garage/client/client.lua b/modules/vehiclekey/cd_garage/client/client.lua similarity index 100% rename from modules/vehicleKey/cd_garage/client/client.lua rename to modules/vehiclekey/cd_garage/client/client.lua diff --git a/modules/vehicleKey/F_RealCarKeysSystem/client/client.lua b/modules/vehiclekey/f_realcarkeyssystem/client/client.lua similarity index 100% rename from modules/vehicleKey/F_RealCarKeysSystem/client/client.lua rename to modules/vehiclekey/f_realcarkeyssystem/client/client.lua diff --git a/modules/vehicleKey/jacksam/client.lua b/modules/vehiclekey/jacksam/client.lua similarity index 100% rename from modules/vehicleKey/jacksam/client.lua rename to modules/vehiclekey/jacksam/client.lua diff --git a/modules/vehicleKey/mVehicle/client/client.lua b/modules/vehiclekey/mVehicle/client/client.lua similarity index 100% rename from modules/vehicleKey/mVehicle/client/client.lua rename to modules/vehiclekey/mVehicle/client/client.lua diff --git a/modules/vehicleKey/mk_vehiclekeys/client/client.lua b/modules/vehiclekey/mk_vehiclekeys/client/client.lua similarity index 100% rename from modules/vehicleKey/mk_vehiclekeys/client/client.lua rename to modules/vehiclekey/mk_vehiclekeys/client/client.lua diff --git a/modules/vehicleKey/MrNewbVehicleKeys/client/client.lua b/modules/vehiclekey/mrnewbvehiclekeys/client/client.lua similarity index 97% rename from modules/vehicleKey/MrNewbVehicleKeys/client/client.lua rename to modules/vehiclekey/mrnewbvehiclekeys/client/client.lua index 6f6b8fa..6f0514d 100644 --- a/modules/vehicleKey/MrNewbVehicleKeys/client/client.lua +++ b/modules/vehiclekey/mrnewbvehiclekeys/client/client.lua @@ -11,7 +11,7 @@ VehicleKey = VehicleKey or {} VehicleKey.GiveKeys = function(vehicle, plate) assert(vehicle, "vehicle is nil") assert(DoesEntityExist(vehicle), "vehicle does not exist") - + if not plate then plate = GetVehicleNumberPlateText(vehicle) end @@ -26,11 +26,11 @@ end VehicleKey.RemoveKeys = function(vehicle, plate) assert(vehicle, "vehicle is nil") assert(DoesEntityExist(vehicle), "vehicle does not exist") - + if not plate then plate = GetVehicleNumberPlateText(vehicle) end - + return exports.MrNewbVehicleKeys:RemoveKeysByPlate(plate) end @@ -38,4 +38,4 @@ VehicleKey.GetResourceName = function() return resourceName end -return VehicleKey \ No newline at end of file +return VehicleKey diff --git a/modules/vehicleKey/okokGarage/client/client.lua b/modules/vehiclekey/okokGarage/client/client.lua similarity index 100% rename from modules/vehicleKey/okokGarage/client/client.lua rename to modules/vehiclekey/okokGarage/client/client.lua diff --git a/modules/vehicleKey/qb-vehiclekeys/client/client.lua b/modules/vehiclekey/qb-vehiclekeys/client/client.lua similarity index 100% rename from modules/vehicleKey/qb-vehiclekeys/client/client.lua rename to modules/vehiclekey/qb-vehiclekeys/client/client.lua diff --git a/modules/vehicleKey/qbx_vehiclekeys/client/client.lua b/modules/vehiclekey/qbx_vehiclekeys/client/client.lua similarity index 100% rename from modules/vehicleKey/qbx_vehiclekeys/client/client.lua rename to modules/vehiclekey/qbx_vehiclekeys/client/client.lua diff --git a/modules/vehicleKey/qs-vehiclekeys/client/client.lua b/modules/vehiclekey/qs-vehiclekeys/client/client.lua similarity index 100% rename from modules/vehicleKey/qs-vehiclekeys/client/client.lua rename to modules/vehiclekey/qs-vehiclekeys/client/client.lua diff --git a/modules/vehicleKey/Renewed-Vehiclekeys/client/client.lua b/modules/vehiclekey/renewed-vehiclekeys/client/client.lua similarity index 100% rename from modules/vehicleKey/Renewed-Vehiclekeys/client/client.lua rename to modules/vehiclekey/renewed-vehiclekeys/client/client.lua diff --git a/modules/vehicleKey/t1ger_keys/client/client.lua b/modules/vehiclekey/t1ger_keys/client/client.lua similarity index 100% rename from modules/vehicleKey/t1ger_keys/client/client.lua rename to modules/vehiclekey/t1ger_keys/client/client.lua diff --git a/modules/vehicleKey/wasabi_carlock/client/client.lua b/modules/vehiclekey/wasabi_carlock/client/client.lua similarity index 100% rename from modules/vehicleKey/wasabi_carlock/client/client.lua rename to modules/vehiclekey/wasabi_carlock/client/client.lua diff --git a/modules/zones/oxlib/client.lua b/modules/zones/oxlib/client.lua index f181615..cdd885f 100644 --- a/modules/zones/oxlib/client.lua +++ b/modules/zones/oxlib/client.lua @@ -23,7 +23,7 @@ ---@diagnostic disable: duplicate-set-field local resourceName = "ox_lib" if GetResourceState(resourceName) == 'missing' then return end -lib = lib or Require("init.lua", "ox_lib") +if not lib then Require('init.lua', 'ox_lib') end Ids = Ids or Require('lib/utility/shared/ids.lua') cZones = {} --conflict with ox diff --git a/settings/clientConfig.lua b/settings/clientConfig.lua index 0d6f579..9d4862a 100644 --- a/settings/clientConfig.lua +++ b/settings/clientConfig.lua @@ -1,7 +1,7 @@ BridgeClientConfig = {} BridgeClientConfig.InputSystem = "auto" -- [ auto | ox_lib | lation_ui | qb-input ] -BridgeClientConfig.MenuSystem = "auto" -- [ auto | ox_lib | lation_ui | qb-menu ] -BridgeClientConfig.ProgressBarSystem = "auto" -- [ auto | ox_lib | lation_ui | progressbar ] +BridgeClientConfig.MenuSystem = "auto" -- [ auto | ox_lib | wasabi_uikit | lation_ui | qb-menu ] +BridgeClientConfig.ProgressBarSystem = "auto" -- [ auto | ox_lib | wasabi_uikit | lation_ui | keep-progressbar | progressbar ] BridgeClientConfig.VehicleKey = "auto" -- [ auto | qb-vehiclekeys | MrNewbVehicleKeys | jaksams_VehiclesKeys | wasabi_carlock | mk_vehiclekeys | qbx_vehiclekeys | qs-vehiclekeys | t1ger_keys | Renewed-Vehiclekeys | mono_carkeys| cd_garage | okokGarage | F_RealCarKeysSystem BridgeClientConfig.Fuel = "auto" -- [ auto | LegacyFuel | ox_fuel | ps-fuel | qs-fuelstations | Renewed-Fuel | ti_fuel | lc_fuel | x-fuel | cdn-fuel | esx-sna-fuel | BigDaddy-Fuel | okokGasStation ] BridgeClientConfig.TargetSystem = "auto" -- [ auto | ox_target | qb-target | sleepless_interact ] -- sleepless is only partially supported and would need another system in place diff --git a/settings/serverConfig.lua b/settings/serverConfig.lua index ebde8e6..2bcdf32 100644 --- a/settings/serverConfig.lua +++ b/settings/serverConfig.lua @@ -1,6 +1,6 @@ BridgeServerConfig = {} BridgeServerConfig.MaxInventorySlots = 50 -BridgeServerConfig.LogSystem = "built-in" -- can be "none", "built-in", "qb", "fivemerr" or "ox_lib" +BridgeServerConfig.LogSystem = "none" -- can be "none", "built-in", "qb", "fivemerr", "fivemanage", or "ox_lib" BridgeServerConfig.WebhookURL = "" -- Add webhook URL here if using built-in logging system BridgeServerConfig.FivemerrApiKey = "" -- Add Fivemerr API key here if using fiveMerr BridgeServerConfig.EmbedLogo = "https://cdn.discordapp.com/avatars/299410129982455808/31ce635662206e8bd0132c34ce9ce683?size=1024"