diff --git a/fxmanifest.lua b/fxmanifest.lua index 8c28da5..8572e07 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -60,9 +60,9 @@ files { 'web/dist/assets/*.css', 'web/dist/assets/*.js', 'locales/*.json', - 'lib/client/*.lua', - 'lib/shared/*.lua', - 'lib/server/*.lua', + 'lib/**/client/*.lua', + 'lib/**/shared/*.lua', + 'lib/**/server/*.lua', 'lib/init.lua', } diff --git a/init.lua b/init.lua index 09e15b2..0bc21a1 100644 --- a/init.lua +++ b/init.lua @@ -107,6 +107,7 @@ Bridge.RegisterModule("Scaleform", cLib.Scaleform) Bridge.RegisterModule("Raycast", cLib.Raycast) Bridge.RegisterModule("PlaceableObject", cLib.PlaceableObject) Bridge.RegisterModule("Point", cLib.Point) +Bridge.RegisterModule("Object", cLib.Object) diff --git a/lib/entities/client/entity_base.lua b/lib/entities/client/entity_base.lua new file mode 100644 index 0000000..f778a86 --- /dev/null +++ b/lib/entities/client/entity_base.lua @@ -0,0 +1,52 @@ + +-- Objects +Utility = Utility or Require("lib/utility/client/utility.lua") +Ids = Ids or Require("lib/utility/shared/ids.lua") +Point = Point or Require("lib/points/client/points.lua") + +local Entities = {} +BaseEntity = {} + +function BaseEntity.Create(id, model, coords, rotation, meta) + local self = meta or {} + if id and type(id) == "table" then + self = id + self.id = id.id or Ids.CreateUniqueId(Entities) + self.rotation = id.rotation or vector3(0.0, 0.0, 0.0) + else + self.id = id or Ids.CreateUniqueId(Entities) + self.model = model + self.coords = coords + self.rotation = rotation or vector3(0.0, 0.0, 0.0) + end + assert(self.id, "ID Failed to generate") + assert(self.model, "Model is required for entity creation") + assert(self.coords, "Coords are required for entity creation") + + self.Spawn = self.Spawn or function() end + self.Remove = self.Remove or function() end + + return Point.Register(self.id, self.coords, 50.0, self.Spawn, self.Remove, nil, self) +end + +function BaseEntity.GetAll() + return Entities +end + +function BaseEntity.Get(id) + return Entities[id] +end + +function BaseEntity.Add(self) + Entities[self.id] = self +end + +function BaseEntity.Remove(id) + Entities[id] = nil +end + +function BaseEntity.LoadModel(model) + return Utility.LoadModel(model) +end + +return BaseEntity \ No newline at end of file diff --git a/lib/entities/client/entity_object.lua b/lib/entities/client/entity_object.lua new file mode 100644 index 0000000..ab6ee2d --- /dev/null +++ b/lib/entities/client/entity_object.lua @@ -0,0 +1,71 @@ +BaseEntity = BaseEntity or Require("lib/entities/client/entity_base.lua") +local Objects = {} + +Object = {} + +function Object.Create(id, model, coords, rotation, meta) + local base = meta or {} + if id and type(id) == "table" then + base = id + base.id = id.id or Ids.CreateUniqueId(Objects) + base.rotation = id.rotation or vector3(0.0, 0.0, 0.0) + else + base.id = id or Ids.CreateUniqueId(Objects) + base.model = model + base.coords = coords + base.rotation = rotation or vector3(0.0, 0.0, 0.0) + end + assert(base.id, "ID Failed to generate") + assert(base.model, "Model is required for entity creation") + assert(base.coords, "Coords are required for entity creation") + + base.Spawn = function(self) + print("Spawning object", self) + if not BaseEntity.LoadModel(self.model) then return end + self.entity = CreateObject(self.model, self.coords.x, self.coords.y, self.coords.z, false, false, false) + SetEntityRotation(self.entity, self.rotation.x, self.rotation.y, self.rotation.z, 2, false) + SetEntityAsMissionEntity(self.entity, true, true) + SetModelAsNoLongerNeeded(self.model) + if self.OnSpawn then self.OnSpawn(self, self.entity, self.coords, self.rotation) end + return self.entity + end + base.Remove = function(self) + DeleteEntity(self.entity) + if self.OnRemove then self.OnRemove(self, self.entity) end + self.entity = nil + end + Object.Add(base) + return BaseEntity.Create(base) +end + +function Object.GetAll() + return Objects +end + +function Object.Get(id) + return Objects[id] +end + +function Object.Add(self) + Objects[self.id] = self +end + +function Object.Remove(id) + Objects[id] = nil +end + +function Object.SetOnSpawn(id, callback) + local obj = Object.Get(id) + if not obj then return end + obj.OnSpawn = callback + return true +end + +function Object.SetOnRemove(id, callback) + local obj = Object.Get(id) + if not obj then return end + obj.OnRemove = callback + return true +end + +return Object \ No newline at end of file diff --git a/lib/entities/server/entity_relay.lua b/lib/entities/server/entity_relay.lua new file mode 100644 index 0000000..5c2f2d0 --- /dev/null +++ b/lib/entities/server/entity_relay.lua @@ -0,0 +1,65 @@ + +-- Objects +Ids = Ids or Require("lib/utility/shared/ids.lua") + + +local Entities = {} +EntityRelay = {} + +function EntityRelay.Create(id, model, coords, rotation, meta) + local self = meta or {} + if id and type(id) == "table" then + self = id + self.id = id.id or Ids.CreateUniqueId(Entities) + self.rotation = id.rotation or vector3(0.0, 0.0, 0.0) + else + self.id = id or Ids.CreateUniqueId(Entities) + self.model = model + self.coords = coords + self.rotation = rotation or vector3(0.0, 0.0, 0.0) + end + assert(self.id, "ID Failed to generate") + assert(self.model, "Model is required for entity creation") + assert(self.coords, "Coords are required for entity creation") + EntityRelay.Add(self) + TriggerClientEvent(GetCurrentResourceName() .. "client:CreateEntity", -1, self) +end + +function EntityRelay.GetAll() + return Entities +end + +function EntityRelay.Get(id) + return Entities[id] +end + +function EntityRelay.Add(self) + Entities[self.id] = self +end + +function EntityRelay.Remove(id) + Entities[id] = nil +end + +function EntityRelay.LoadModel(model) + return Utility.LoadModel(model) +end + +return EntityRelay + + + -- RegisterCommand("entityobj", function() + -- local entity = Bridge.Object.Create({ + -- id = "something", -- optional + -- model = "prop_beach_fire", + -- coords = GetEntityCoords(PlayerPedId()), + -- rotation = vector3(0.0, 0.0, 0.0), + -- }) + -- Bridge.Object.SetOnSpawn("something", function(self, coords, rotation) + -- print("Entity spawned") + -- end) + + -- Bridge.Object.SetOnRemove("something", function(self, entity) + -- print("Entity removed") + -- end) + -- end) \ No newline at end of file diff --git a/lib/shared/actions.lua b/lib/entities/shared/actions.lua similarity index 100% rename from lib/shared/actions.lua rename to lib/entities/shared/actions.lua diff --git a/lib/server/ItemsBuilder.lua b/lib/generators/server/ItemsBuilder.lua similarity index 100% rename from lib/server/ItemsBuilder.lua rename to lib/generators/server/ItemsBuilder.lua diff --git a/lib/server/lootTables.lua b/lib/generators/server/lootTables.lua similarity index 100% rename from lib/server/lootTables.lua rename to lib/generators/server/lootTables.lua diff --git a/lib/init.lua b/lib/init.lua index 53ad880..32df25c 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -37,14 +37,14 @@ end cLib = { Require = Require, - Callback = Callback or Require("lib/shared/callbacks.lua"), - Ids = Ids or Require("lib/shared/ids.lua"), - ReboundEntities = ReboundEntities or Require("lib/shared/rebound_entities.lua"), - Tables = Tables or Require("lib/shared/tables.lua"), - Prints = Prints or Require("lib/shared/prints.lua"), - Math = Math or Require("lib/shared/math.lua"), - LA = LA or Require("lib/shared/la.lua"), - Perlin = Perlin or Require("lib/shared/perlin.lua"), + Callback = Callback or Require("lib/utility/shared/callbacks.lua"), + Ids = Ids or Require("lib/utility/shared/ids.lua"), + ReboundEntities = ReboundEntities or Require("lib/utility/shared/rebound_entities.lua"), + Tables = Tables or Require("lib/utility/shared/tables.lua"), + 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"), + Perlin = Perlin or Require("lib/utility/shared/perlin.lua"), -- Actions = Actions or Require("lib/shared/actions.lua"), } @@ -52,20 +52,21 @@ exports('cLib', cLib) if not IsDuplicityVersion() then goto client end -cLib.SQL = SQL or Require("lib/server/sqlHandler.lua") -cLib.Logs = Logs or Require("lib/server/logs.lua") -cLib.ItemsBuilder = ItemsBuilder or Require("lib/server/ItemsBuilder.lua") -cLib.LootTables = LootTables or Require("lib/server/lootTables.lua") +cLib.SQL = SQL or Require("lib/sql/server/sqlHandler.lua") +cLib.Logs = Logs or Require("lib/logs/server/logs.lua") +cLib.ItemsBuilder = ItemsBuilder or Require("lib/generators/server/ItemsBuilder.lua") +cLib.LootTables = LootTables or Require("lib/generators/server/lootTables.lua") if IsDuplicityVersion() then return cLib end ::client:: -cLib.Gizmo = Gizmo or Require("lib/client/gizmo.lua") -cLib.Scaleform = Scaleform or Require("lib/client/scaleform.lua") -cLib.Placeable = Placeable or Require("lib/client/object_placer.lua") -cLib.Utility = Utility or Require("lib/client/utility.lua") -cLib.PlaceableObject = PlaceableObject or Require("lib/client/placeable_object.lua") -cLib.Raycast = Raycast or Require("lib/client/raycast.lua") -cLib.Point = Point or Require("lib/client/points.lua") +cLib.Gizmo = Gizmo or Require("lib/placers/client/gizmo.lua") +cLib.Scaleform = Scaleform or Require("lib/scaleform/client/scaleform.lua") +cLib.Placeable = Placeable or Require("lib/placers/client/object_placer.lua") +cLib.Utility = Utility or Require("lib/utility/client/utility.lua") +cLib.PlaceableObject = PlaceableObject or Require("lib/placers/client/placeable_object.lua") +cLib.Raycast = Raycast or Require("lib/raycast/client/raycast.lua") +cLib.Point = Point or Require("lib/points/client/points.lua") +cLib.Object = Object or Require("lib/entities/client/entity_object.lua") return cLib \ No newline at end of file diff --git a/lib/server/logs.lua b/lib/logs/server/logs.lua similarity index 100% rename from lib/server/logs.lua rename to lib/logs/server/logs.lua diff --git a/lib/client/markers.lua b/lib/markers/client/markers.lua similarity index 100% rename from lib/client/markers.lua rename to lib/markers/client/markers.lua diff --git a/lib/client/particles.lua b/lib/particles/client/particles.lua similarity index 100% rename from lib/client/particles.lua rename to lib/particles/client/particles.lua diff --git a/lib/client/dataview.lua b/lib/placers/client/dataview.lua similarity index 100% rename from lib/client/dataview.lua rename to lib/placers/client/dataview.lua diff --git a/lib/client/gizmo.lua b/lib/placers/client/gizmo.lua similarity index 99% rename from lib/client/gizmo.lua rename to lib/placers/client/gizmo.lua index b4612a2..7bb1010 100644 --- a/lib/client/gizmo.lua +++ b/lib/placers/client/gizmo.lua @@ -2,7 +2,7 @@ -- CREDITS -- Andyyy7666: https://github.com/overextended/ox_lib/pull/453 -- AvarianKnight: https://forum.cfx.re/t/allow-drawgizmo-to-be-used-outside-of-fxdk/5091845/8?u=demi-automatic -local dataview = Require("lib/client/dataview.lua") +local dataview = Require("lib/placers/client/dataview.lua") local enableScale = false -- allow scaling mode. doesnt scale collisions and resets when physics are applied it seems local gizmoEnabled = false local currentMode = 'translate' diff --git a/lib/client/object_Placer.lua b/lib/placers/client/object_Placer.lua similarity index 98% rename from lib/client/object_Placer.lua rename to lib/placers/client/object_Placer.lua index 5a65efb..a56dea8 100644 --- a/lib/client/object_Placer.lua +++ b/lib/placers/client/object_Placer.lua @@ -1,5 +1,5 @@ Placeable = Placeable or {} -Utility = Utility or Require("lib/client/utility.lua") +Utility = Utility or Require("lib/utility/client/utility.lua") local activePlacementProp = nil lib.locale() diff --git a/lib/client/placeable_object.lua b/lib/placers/client/placeable_object.lua similarity index 97% rename from lib/client/placeable_object.lua rename to lib/placers/client/placeable_object.lua index 9e338db..26b10c5 100644 --- a/lib/client/placeable_object.lua +++ b/lib/placers/client/placeable_object.lua @@ -1,7 +1,7 @@ -Scaleform = Scaleform or Require("lib/client/scaleform.lua") -Utility = Utility or Require("lib/client/utility.lua") -Gizmo = Gizmo or Require("lib/client/gizmo.lua") -Raycast = Raycast or Require("lib/client/raycast.lua") +Scaleform = Scaleform or Require("lib/scaleform/client/scaleform.lua") +Utility = Utility or Require("lib/utility/client/utility.lua") +Gizmo = Gizmo or Require("lib/placers/client/gizmo.lua") +Raycast = Raycast or Require("lib/raycast/client/raycast.lua") PlaceableObject = PlaceableObject or {} diff --git a/lib/client/points.lua b/lib/points/client/points.lua similarity index 100% rename from lib/client/points.lua rename to lib/points/client/points.lua diff --git a/lib/client/raycast.lua b/lib/raycast/client/raycast.lua similarity index 100% rename from lib/client/raycast.lua rename to lib/raycast/client/raycast.lua diff --git a/lib/client/scaleform.lua b/lib/scaleform/client/scaleform.lua similarity index 100% rename from lib/client/scaleform.lua rename to lib/scaleform/client/scaleform.lua diff --git a/lib/shared/callbacks.lua b/lib/shared/callbacks.lua deleted file mode 100644 index 88a228a..0000000 --- a/lib/shared/callbacks.lua +++ /dev/null @@ -1,144 +0,0 @@ -Callbacks = {} -cbData = {} -Callback = Callback or {} - ---======================================= --- ▀█▀ █▄█ █ █▄ █ █▄▀ ▄▀▄ ██▄ ▄▀▄ █ █ ▀█▀ ▄▀▄ █▀▄ █▀▄ █ █▄ █ ▄▀ █▀▄ █▀▄ ▄▀▄ █▄ ▄█ █ ▄▀▀ ██▀ ▄▀▀ ▀█▀ ▄▀▄ ▄▀▀ ▄▀▄ █ █ ██▄ ▄▀▄ ▄▀▀ █▄▀ ▄▀▀ --- █ █ █ █ █ ▀█ █ █ █▀█ █▄█ ▀▄▀ ▀▄█ █ █▀█ █▄▀ █▄▀ █ █ ▀█ ▀▄█ █▀ █▀▄ ▀▄▀ █ ▀ █ █ ▄█▀ █▄▄ ▄█▀ █ ▀▄▀ ▀▄▄ █▀█ █▄▄ █▄▄ █▄█ █▀█ ▀▄▄ █ █ ▄█▀ ---======================================= - -local resource = GetCurrentResourceName() or 'unknown' - -local clientToServerName = resource .. ':server:CS:TriggerCallback' -local clientToServerBackToClientName = resource .. ':client:CSC:TriggerCallback' - - -local serverToClientName = resource .. ':client:SC:TriggerCallback' -local serverToClientBackToServerName = resource .. ':server:SCS:TriggerCallback' - - -exports('Callback', Callback) - -if not IsDuplicityVersion() then goto client end - --- -- -- -- -- -- -- -- -- -- --- ▄▀▀ ██▀ █▀▄ █ █ ██▀ █▀▄ --- ▄█▀ █▄▄ █▀▄ ▀▄▀ █▄▄ █▀▄ --- -- -- -- -- -- -- -- -- -- - - - --- client to server rebound -function Callback.Register(name, callback, all) - Callback[name] = { - callback = callback, - toAll = all - } -end - -RegisterNetEvent(clientToServerName, function(name, ...) - local src = source - local data = Callback[name] - if not data then return end - local func = data.callback - if not func then return end - local toAll = data.toAll and -1 or src - local cb = function(...) - TriggerClientEvent(clientToServerBackToClientName, toAll, name, ...) - end - func(src, cb, ...) -end) ------------------------------ - --- server to client rebound - -function Callback.Trigger(name, src, func, ...) - if src == nil then src = -1 end - local p = promise.new() - cbData[name] = {cb = func, p = p} - if type(src) == 'table' then - for i, d in pairs(src) do - TriggerClientEvent(serverToClientName, tonumber(d), name, ...) - end - return Citizen.Await(p) - end - TriggerClientEvent(serverToClientName, tonumber(src), name, ...) - return Citizen.Await(p) -end - -RegisterNetEvent(serverToClientBackToServerName, function(name, ...) - print('Rebound') - local data = cbData[name] - if not data then return end - local func = data.cb - if not func then return end - data.p:resolve(func(...) or true) - cbData[name] = nil -end) ------------------------------ -exports('RegisterCallback', Callback.Register) -exports('TriggerCallback', Callback.Trigger) - - --- -- -- -- -- -- -- -- -- -- --- ▄▀▀ █ █ ██▀ █▄ █ ▀█▀ --- ▀▄▄ █▄▄ █ █▄▄ █ ▀█ █ --- -- -- -- -- -- -- -- -- -- -if IsDuplicityVersion() then return Callback end -::client:: - - -cbRebounds = {} -function Callback.Register(name, callback, all) - Callback[name] = { - callback = callback, - } -end - - -function Callback.RegisterRebound(name, callback) - cbRebounds[name] = callback -end - - --- client to server rebound -function Callback.Trigger(name, func, ...) - local p = promise.new() - TriggerServerEvent(clientToServerName, name, ...) - cbData[name] = {cb = func, p = p} - - return Citizen.Await(p) -end - -RegisterNetEvent(clientToServerBackToClientName, function(name, ...) - local clientRebound = cbRebounds[name] - if clientRebound then - clientRebound(...) - end - local data = cbData[name] - if not data then return end - local func = data.cb - if not func then return end - data.p:resolve(func(...) or true) - cbData[name] = nil -end) ------------------------------ - --- server to client rebound -RegisterNetEvent(serverToClientName, function(name, ...) - local data = Callback[name] - if not data then return end - local func = data.callback - if not func then return end - local cb = function(...) - TriggerServerEvent(serverToClientBackToServerName, name, ...) - end - func(cb, ...) -end) ------------------------------ - -exports('RegisterCallback', Callback.Register) -exports('RegisterRebound', Callback.RegisterRebound) -exports('TriggerCallback', Callback.Trigger) - -return Callback \ No newline at end of file diff --git a/lib/shared/rebound_entitiy_actions.lua b/lib/shared/rebound_entitiy_actions.lua deleted file mode 100644 index ba45e1f..0000000 --- a/lib/shared/rebound_entitiy_actions.lua +++ /dev/null @@ -1,35 +0,0 @@ -local ReboundEntities = ReboundEntities or Require("shared/rebound_entities.lua") -local Actions = Actions or Require("shared/actions.lua") -local LA = LA or Require("shared/la.lua") - -REA = {} - -if not IsDuplicityVersion() then goto client end - - - -if IsDuplicityVersion() then return end -::client:: - -local ActionsInProgress = {} - - -Action.Create("LerpToPosition", function(reboundId, start, position, duration, shouldRepeat, overrideStartTime) - local re = ReboundEntities.Get(reboundId) - assert(re, "Rebound entity not found") - local entity = re and re.entity - if not entity then return end - local startTime = GetGameTimer() - local endTime = overrideStartTime or startTime + duration - ActionsInProgress[reboundId] = {reboundId, start, position, duration, shouldRepeat, startTime} - local t = 0 - CreateThread(function() - while shouldRepeat or t < 1 do - t = (GetGameTimer() - startTime) / duration - local lerpPosition = LA.LerpVector(start, position, t) - SetEntityCoords(entity, lerpPosition) - Wait(0) - - end - end) -end) diff --git a/lib/server/sqlHandler.lua b/lib/sql/server/sqlHandler.lua similarity index 100% rename from lib/server/sqlHandler.lua rename to lib/sql/server/sqlHandler.lua diff --git a/lib/client/utility.lua b/lib/utility/client/utility.lua similarity index 100% rename from lib/client/utility.lua rename to lib/utility/client/utility.lua diff --git a/lib/utility/shared/cache.lua b/lib/utility/shared/cache.lua new file mode 100644 index 0000000..e69de29 diff --git a/lib/utility/shared/callbacks.lua b/lib/utility/shared/callbacks.lua new file mode 100644 index 0000000..b4a5ce7 --- /dev/null +++ b/lib/utility/shared/callbacks.lua @@ -0,0 +1,203 @@ +Callbacks = {} +cbData = {} +Callback = Callback or {} + +--======================================= +-- ▀█▀ █▄█ █ █▄ █ █▄▀ ▄▀▄ ██▄ ▄▀▄ █ █ ▀█▀ ▄▀▄ █▀▄ █▀▄ █ █▄ █ ▄▀ █▀▄ █▀▄ ▄▀▄ █▄ ▄█ █ ▄▀▀ ██▀ ▄▀▀ ▀█▀ ▄▀▄ ▄▀▀ ▄▀▄ █ █ ██▄ ▄▀▄ ▄▀▀ █▄▀ ▄▀▀ +-- █ █ █ █ █ ▀█ █ █ █▀█ █▄█ ▀▄▀ ▀▄█ █ █▀█ █▄▀ █▄▀ █ █ ▀█ ▀▄█ █▀ █▀▄ ▀▄▀ █ ▀ █ █ ▄█▀ █▄▄ ▄█▀ █ ▀▄▀ ▀▄▄ █▀█ █▄▄ █▄▄ █▄█ █▀█ ▀▄▄ █ █ ▄█▀ +--======================================= + +local resource = GetCurrentResourceName() or 'unknown' + +local clientToServerName = resource .. ':server:CS:TriggerCallback' +local clientToServerBackToClientName = resource .. ':client:CSC:TriggerCallback' + +local serverToClientName = resource .. ':client:SC:TriggerCallback' +local serverToClientBackToServerName = resource .. ':server:SCS:TriggerCallback' + +exports('Callback', Callback) + +if not IsDuplicityVersion() then goto client end + +-- -- -- -- -- -- -- -- -- -- +-- ▄▀▀ ██▀ █▀▄ █ █ ██▀ █▀▄ +-- ▄█▀ █▄▄ █▀▄ ▀▄▀ █▄▄ █▀▄ +-- -- -- -- -- -- -- -- -- -- + +-- client to server rebound +function Callback.Register(name, callback, all) + Callback[name] = { + callback = callback, + toAll = all + } +end + +-- Handle client requests and send response back to client(s) +RegisterNetEvent(clientToServerName, function(name, cbId, ...) + local src = source + local data = Callback[name] + if not data then return end + local func = data.callback + if not func then return end + local toAll = data.toAll and -1 or src + + -- Create response handler + local cb = function(...) + TriggerClientEvent(clientToServerBackToClientName, toAll, name, cbId, ...) + end + + -- Call the callback + func(src, cb, ...) +end) + +-- Server to client trigger function - supports both callback and direct return +function Callback.Trigger(name, src, callbackOrArg, ...) + if src == nil then src = -1 end + + -- Determine if the third parameter is a callback function or an argument + local hasCallback = type(callbackOrArg) == 'function' or (type(callbackOrArg) == 'table' and rawget(callbackOrArg, '__cfx_functionReference')) + local callback = hasCallback and callbackOrArg or nil + -- Adjust args based on whether the callback is present + local args = hasCallback and {...} or {callbackOrArg, ...} + + local cbId = name .. '_' .. math.random(1000000, 9999999) + local p = promise.new() + + -- Store promise data + cbData[cbId] = { + cb = callback, + p = p + } + + -- Trigger for single player or multiple players + if type(src) == 'table' then + for i, d in pairs(src) do + TriggerClientEvent(serverToClientName, tonumber(d), name, cbId, table.unpack(args)) + end + else + TriggerClientEvent(serverToClientName, tonumber(src), name, cbId, table.unpack(args)) + end + + -- If no callback was provided, wait for the promise and return directly + if not hasCallback then + return Citizen.Await(p) + end + + -- Otherwise, return nothing (callback will handle it) + return nil +end + +-- Handle responses to server requests +RegisterNetEvent(serverToClientBackToServerName, function(name, cbId, ...) + local data = cbData[cbId] + if not data then return end + + -- Process callback if provided + if data.cb then + data.cb(...) + end + + -- Always resolve the promise with all args for direct returns + data.p:resolve({...}) + cbData[cbId] = nil +end) + +exports('RegisterCallback', Callback.Register) +exports('TriggerCallback', Callback.Trigger) + +-- -- -- -- -- -- -- -- -- -- +-- ▄▀▀ █ █ ██▀ █▄ █ ▀█▀ +-- ▀▄▄ █▄▄ █ █▄▄ █ ▀█ █ +-- -- -- -- -- -- -- -- -- -- +if IsDuplicityVersion() then return Callback end +::client:: + +cbRebounds = {} +function Callback.Register(name, callback) + Callback[name] = { + callback = callback, + } +end + +function Callback.RegisterRebound(name, callback) + cbRebounds[name] = callback +end + +-- Client to server trigger - supports both callback and direct return +function Callback.Trigger(name, callbackOrArg, ...) + -- Determine if the second parameter is a callback function or an argument + local hasCallback = type(callbackOrArg) == 'function' or (type(callbackOrArg) == 'table' and rawget(callbackOrArg, '__cfx_functionReference')) + local callback = hasCallback and callbackOrArg or nil + -- Adjust args based on whether the callback is present + local args = hasCallback and {...} or {callbackOrArg, ...} + + local cbId = name .. '_' .. math.random(1000000, 9999999) + local p = promise.new() + + -- Store promise data + cbData[cbId] = { + cb = callback, + p = p + } + + -- Trigger the server event + TriggerServerEvent(clientToServerName, name, cbId, table.unpack(args)) + + -- If no callback was provided, wait for the promise and return directly + if not hasCallback then + local result = Citizen.Await(p) + -- If there's only one value, return it directly + if #result == 1 then + return result[1] + else + return table.unpack(result) + end + end + + -- Otherwise, return nothing (callback will handle it) + return nil +end + +-- Handle responses from server +RegisterNetEvent(clientToServerBackToClientName, function(name, cbId, ...) + -- Check for global rebounding callbacks + local clientRebound = cbRebounds[name] + if clientRebound then + clientRebound(...) + end + + -- Handle the specific callback instance + local data = cbData[cbId] + if not data then return end + + -- Process callback if provided + if data.cb then + data.cb(...) + end + + -- Always resolve the promise with all args for direct returns + data.p:resolve({...}) + cbData[cbId] = nil +end) + +-- Handle server requests to client +RegisterNetEvent(serverToClientName, function(name, cbId, ...) + local data = Callback[name] + if not data then return end + local func = data.callback + if not func then return end + + -- Create response handler + local cb = function(...) + TriggerServerEvent(serverToClientBackToServerName, name, cbId, ...) + end + + -- Execute the callback + func(cb, ...) +end) + +exports('RegisterCallback', Callback.Register) +exports('RegisterRebound', Callback.RegisterRebound) +exports('TriggerCallback', Callback.Trigger) + +return Callback \ No newline at end of file diff --git a/lib/shared/ids.lua b/lib/utility/shared/ids.lua similarity index 100% rename from lib/shared/ids.lua rename to lib/utility/shared/ids.lua diff --git a/lib/shared/la.lua b/lib/utility/shared/la.lua similarity index 100% rename from lib/shared/la.lua rename to lib/utility/shared/la.lua diff --git a/lib/shared/math.lua b/lib/utility/shared/math.lua similarity index 100% rename from lib/shared/math.lua rename to lib/utility/shared/math.lua diff --git a/lib/shared/perlin.lua b/lib/utility/shared/perlin.lua similarity index 100% rename from lib/shared/perlin.lua rename to lib/utility/shared/perlin.lua diff --git a/lib/shared/prints.lua b/lib/utility/shared/prints.lua similarity index 100% rename from lib/shared/prints.lua rename to lib/utility/shared/prints.lua diff --git a/lib/shared/rebound_entities.lua b/lib/utility/shared/rebound_entities.lua similarity index 100% rename from lib/shared/rebound_entities.lua rename to lib/utility/shared/rebound_entities.lua diff --git a/lib/utility/shared/rebound_entitiy_actions.lua b/lib/utility/shared/rebound_entitiy_actions.lua new file mode 100644 index 0000000..552bd8f --- /dev/null +++ b/lib/utility/shared/rebound_entitiy_actions.lua @@ -0,0 +1,35 @@ +-- local ReboundEntities = ReboundEntities or Require("shared/rebound_entities.lua") +-- local Actions = Actions or Require("shared/actions.lua") +-- local LA = LA or Require("shared/la.lua") + +-- REA = {} + +-- if not IsDuplicityVersion() then goto client end + + + +-- if IsDuplicityVersion() then return end +-- ::client:: + +-- local ActionsInProgress = {} + + +-- Action.Create("LerpToPosition", function(reboundId, start, position, duration, shouldRepeat, overrideStartTime) +-- local re = ReboundEntities.Get(reboundId) +-- assert(re, "Rebound entity not found") +-- local entity = re and re.entity +-- if not entity then return end +-- local startTime = GetGameTimer() +-- local endTime = overrideStartTime or startTime + duration +-- ActionsInProgress[reboundId] = {reboundId, start, position, duration, shouldRepeat, startTime} +-- local t = 0 +-- CreateThread(function() +-- while shouldRepeat or t < 1 do +-- t = (GetGameTimer() - startTime) / duration +-- local lerpPosition = LA.LerpVector(start, position, t) +-- SetEntityCoords(entity, lerpPosition) +-- Wait(0) + +-- end +-- end) +-- end) diff --git a/lib/shared/tables.lua b/lib/utility/shared/tables.lua similarity index 100% rename from lib/shared/tables.lua rename to lib/utility/shared/tables.lua diff --git a/modules/dialogue/default/client/client.lua b/modules/dialogue/default/client/client.lua index c00ed6d..5cbb940 100644 --- a/modules/dialogue/default/client/client.lua +++ b/modules/dialogue/default/client/client.lua @@ -59,7 +59,7 @@ function Dialogue.Open( name, dialogue, characterOptions, dialogueOptions, onSel local offsetY = math.cos(angleRad) * 1.5 -- Get position in front of ped based on their heading - local endLocation = GetEntityCoords(entity) + vector3(offsetX, offsetY, 0.5) + offset + local endLocation = GetEntityCoords(entity) + vector3(offsetX * offset.x, offsetY * offset.y, 0.5) if not cam then cam = CreateCam("DEFAULT_SCRIPTED_CAMERA", 1) end local camPos = GetCamCoord(cam) diff --git a/modules/framework/qb-core/server.lua b/modules/framework/qb-core/server.lua index 9441ca9..88b1ba1 100644 --- a/modules/framework/qb-core/server.lua +++ b/modules/framework/qb-core/server.lua @@ -369,7 +369,7 @@ RegisterNetEvent("QBCore:Server:OnPlayerLoaded", function() TriggerEvent("community_bridge:Server:OnPlayerLoaded", src) end) -RegisterNetEvent("QBCore:Server:OnPlayerUnload", function() +RegisterNetEvent("QBCore:Server:OnPlayerUnload", function(source) local src = source TriggerEvent("community_bridge:Server:OnPlayerUnload", src) end) diff --git a/modules/inventory/_default/server.lua b/modules/inventory/_default/server.lua index 18f5b23..d179eaf 100644 --- a/modules/inventory/_default/server.lua +++ b/modules/inventory/_default/server.lua @@ -83,4 +83,4 @@ end ---@return string Inventory.GetImagePath = function(item) return "https://avatars.githubusercontent.com/u/47620135" -end \ No newline at end of file +end