Merge pull request #67 from The-Order-Of-The-Sacred-Framework/dev
0.5.0
This commit is contained in:
90 files changed
+2083
-765
No files matched your search
+4
-4
@@ -8,11 +8,11 @@ This project incorporates code from several libraries and resources licensed und
|
||||
- **Credit**: **r_bridge** inventory bridging code for codem-inventory is used in this. Targeting code still remains as is and is used.
|
||||
[\[r_bridge\]](https://github.com/rumaier/r_bridge)
|
||||
|
||||
## clean_lib
|
||||
## dirk_lib
|
||||
- **Purpose**: Vehicle fuel, vehicle key bridging.
|
||||
- **Modifications to the code**: None.
|
||||
- **Credit**: **clean_lib** client side code is used to manage vehicle fuel and keys, bridging these systems.
|
||||
[\[clean_lib\]](https://github.com/Clean-Server-Pack/clean_lib)
|
||||
- **Credit**: **dirk_lib** client side code is used to manage vehicle fuel and keys, bridging these systems.
|
||||
[\[dirk_lib\]](https://github.com/DirkDigglerz/dirk_lib)
|
||||
|
||||
## ox_lib
|
||||
- **Purpose**: Utility functions for printing raycasting and point registering.
|
||||
@@ -34,4 +34,4 @@ This project incorporates code from several libraries and resources licensed und
|
||||
|
||||
|
||||
|
||||
Thank you to the creators and maintainers of these libraries/bridges/internet points for their hard work and contributions to the FiveM community.
|
||||
Thank you to the creators and maintainers of these libraries/bridges/internet points for their hard work and contributions to the FiveM community.
|
||||
+5
-4
@@ -4,7 +4,7 @@ lua54 'yes'
|
||||
use_experimental_fxv2_oal 'yes'
|
||||
author 'The Order of the Sacred Framework'
|
||||
description 'A bridge made for the community to use as a base for their own projects. This bridge will allow a single format to work with nearly all commonly used systems while still offering expandability.'
|
||||
version '0.4.0'
|
||||
version '0.5.0'
|
||||
|
||||
shared_scripts {
|
||||
'@ox_lib/init.lua',
|
||||
@@ -50,6 +50,7 @@ client_scripts {
|
||||
'modules/notify/**/client.lua',
|
||||
'modules/dialogue/**/client/*.lua',
|
||||
'modules/shops/**/client.lua',
|
||||
'modules/accessibility/client.lua',
|
||||
'init.lua',
|
||||
}
|
||||
|
||||
@@ -60,9 +61,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',
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ if not IsDuplicityVersion() then goto client end
|
||||
|
||||
Bridge.RegisterModule("SQL", cLib.SQL)
|
||||
Bridge.RegisterModule("Logs", cLib.Logs)
|
||||
Bridge.RegisterModule("ItemsBuilder", cLib.ItemsBuilder)
|
||||
Bridge.RegisterModule("LootTables", cLib.LootTables)
|
||||
Bridge.RegisterModule("Version", Version)
|
||||
|
||||
@@ -98,6 +99,7 @@ Bridge.RegisterModule("Weather", Weather)
|
||||
Bridge.RegisterModule("Target", Target)
|
||||
Bridge.RegisterModule("Menu", Menu)
|
||||
Bridge.RegisterModule("Dialogue", Dialogue)
|
||||
Bridge.RegisterModule("Accessibility", Accessibility) -- new
|
||||
|
||||
Bridge.RegisterModule("Utility", cLib.Utility)
|
||||
Bridge.RegisterModule("Placeable", cLib.Placeable)--new
|
||||
@@ -105,6 +107,8 @@ Bridge.RegisterModule("Gizmo", cLib.Gizmo)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
-- 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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
File renamed without changes.
@@ -0,0 +1,100 @@
|
||||
ItemsBuilder = ItemsBuilder or {}
|
||||
|
||||
ItemsBuilder = {}
|
||||
|
||||
---This will generate the items in the formats of qb_core, qb_core_old and ox_inventory. It will then build a lua file in the generateditems folder of the community_bridge.
|
||||
---@param invoking string
|
||||
---@param itemsTable table
|
||||
ItemsBuilder.Generate = function(invoking, itemsTable)
|
||||
if not invoking or not itemsTable then return end
|
||||
|
||||
local resourcePath = GetResourcePath(GetCurrentResourceName()) .. "/generateditems/"
|
||||
|
||||
local function fileExists(path)
|
||||
local file = io.open(path, "r")
|
||||
if file then
|
||||
file:close()
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local qbOldFilePath = resourcePath .. invoking .. "_qb_core_old.lua"
|
||||
local qbNewFilePath = resourcePath .. invoking .. "_qb_core_new.lua"
|
||||
local oxInventoryFilePath = resourcePath .. invoking .. "_ox_inventory.lua"
|
||||
|
||||
if fileExists(qbOldFilePath) or fileExists(qbNewFilePath) or fileExists(oxInventoryFilePath) then return end
|
||||
|
||||
local qbOld = {}
|
||||
for key, item in pairs(itemsTable) do
|
||||
qbOld[key] = string.format(
|
||||
"['%s'] = {label = '%s', weight = %d, stack = %s, close = %s, description = '%s'}",
|
||||
key, item.label, item.weight, tostring(item.stack), tostring(item.close), item.description
|
||||
)
|
||||
end
|
||||
|
||||
local qbNew = {}
|
||||
for key, item in pairs(itemsTable) do
|
||||
qbNew[key] = string.format(
|
||||
"%s = {label = '%s', weight = %d, stack = %s, close = %s, description = '%s'}",
|
||||
key, item.label, item.weight, tostring(item.stack), tostring(item.close), item.description
|
||||
)
|
||||
end
|
||||
|
||||
local oxInventory = {}
|
||||
for key, item in pairs(itemsTable) do
|
||||
oxInventory[key] = {
|
||||
label = item.label,
|
||||
weight = item.weight,
|
||||
stack = item.stack,
|
||||
close = item.close
|
||||
}
|
||||
end
|
||||
|
||||
local function writeInlineFile(fileName, content, useBrackets)
|
||||
local filePath = resourcePath .. fileName
|
||||
local file = io.open(filePath, "w")
|
||||
if file then
|
||||
for key, value in pairs(content) do
|
||||
if useBrackets then
|
||||
-- For qb_core_old with brackets
|
||||
file:write(string.format("['%s'] = %s,\n", key, value))
|
||||
else
|
||||
-- For qb_core_new without brackets
|
||||
file:write(string.format("%s = %s,\n", key, value))
|
||||
end
|
||||
end
|
||||
file:close()
|
||||
print("🌮 Items File Created: " .. filePath)
|
||||
else
|
||||
print("🌮 Something Broke for: " .. filePath)
|
||||
end
|
||||
end
|
||||
|
||||
local function writeSimplifiedFile(fileName, content)
|
||||
local filePath = resourcePath .. fileName
|
||||
local file = io.open(filePath, "w")
|
||||
if file then
|
||||
for key, item in pairs(content) do
|
||||
file:write(string.format('["%s"] = {\n', key))
|
||||
for k, v in pairs(item) do
|
||||
local formattedValue = type(v) == "string" and string.format('"%s"', v) or tostring(v)
|
||||
file:write(string.format(" %s = %s,\n", k, formattedValue))
|
||||
end
|
||||
file:write("},\n")
|
||||
end
|
||||
file:close()
|
||||
print("🌮 Items File Created: " .. filePath)
|
||||
else
|
||||
print("🌮 Something Broke for: " .. filePath)
|
||||
end
|
||||
end
|
||||
|
||||
writeInlineFile(invoking.."_".."qb_core_old.lua", qbOld, true)
|
||||
writeInlineFile(invoking.."_".."qb_core_new.lua", qbNew, false)
|
||||
writeSimplifiedFile(invoking.."_".."ox_inventory.lua", oxInventory)
|
||||
end
|
||||
|
||||
exports('ItemsBuilder', ItemsBuilder)
|
||||
return ItemsBuilder
|
||||
File renamed without changes.
+20
-17
@@ -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,18 +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.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.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
|
||||
@@ -3,6 +3,10 @@ Logs = Logs or {}
|
||||
local WebhookURL = ""
|
||||
local LogoForEmbed = ""
|
||||
|
||||
---This will send a log to the configured webhook or log system.
|
||||
---@param src number
|
||||
---@param message string
|
||||
---@return nil
|
||||
Logs.Send = function(src, message)
|
||||
if not src or not message then return end
|
||||
if BridgeServerConfig.LogSystem == "builtin" then
|
||||
File renamed without changes.
@@ -1,4 +1,3 @@
|
||||
|
||||
function CreateParticleFX(dict, ptfx, pos, rot, scale, color, looped, loopLength)
|
||||
CreateThread(function()
|
||||
local failed = 5
|
||||
@@ -45,8 +44,6 @@ function CreateParticleFXOnEntityBone(dict, ptfx, entity, bone, offset, rot, sc
|
||||
return bleh
|
||||
end
|
||||
|
||||
|
||||
|
||||
function PlayParticleFX(dict, name, looped, x, y, z, rotX, rotY, rotZ, scale)
|
||||
RequestNamedPtfxAsset(dict)
|
||||
while not HasNamedPtfxAssetLoaded(dict) do
|
||||
File renamed without changes.
@@ -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'
|
||||
@@ -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()
|
||||
@@ -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 {}
|
||||
|
||||
@@ -71,7 +71,7 @@ function PlaceableObject.Create(data, model, onConfirm, onUpdate, onCancel, sett
|
||||
{type = "SET_BACKGROUND_COLOUR"},
|
||||
})
|
||||
local heading = -GetEntityHeading(PlayerPedId())
|
||||
|
||||
|
||||
local pos = PlaceableObject.Eyetrace(depth, disableSphere)
|
||||
if not data.spawned and model then
|
||||
--get player heading
|
||||
@@ -81,7 +81,7 @@ function PlaceableObject.Create(data, model, onConfirm, onUpdate, onCancel, sett
|
||||
assert(data.spawned, "Failed to create object")
|
||||
SetEntityCollision(data.spawned, false, false)
|
||||
SetEntityAlpha(data.spawned, 150, false)
|
||||
|
||||
|
||||
SetPedConfigFlag(PlayerPedId(), 146, true)
|
||||
SetCanClimbOnEntity(data.spawned, false)
|
||||
SetEntityCompletelyDisableCollision(data.spawned, true, false)
|
||||
@@ -96,7 +96,7 @@ function PlaceableObject.Create(data, model, onConfirm, onUpdate, onCancel, sett
|
||||
inBounds = true
|
||||
SetEntityDrawOutlineColor(0, 255, 0, 255)
|
||||
SetEntityDrawOutline(data.spawned, true)
|
||||
end
|
||||
end
|
||||
elseif inBounds then
|
||||
inBounds = false
|
||||
SetEntityDrawOutline(data.spawned, false)
|
||||
@@ -113,7 +113,7 @@ function PlaceableObject.Create(data, model, onConfirm, onUpdate, onCancel, sett
|
||||
DisableControlAction(0, 24, true) -- Attack
|
||||
DisableControlAction(0, 25, true) -- Aim
|
||||
DisableControlAction(0, 36, true) -- INPUT_DUCK.
|
||||
|
||||
|
||||
if IsDisabledControlJustPressed(0, 223) then -- left click
|
||||
if not inBounds then
|
||||
Notify.SendNotify("You can't place this object here", "error", 5000)
|
||||
@@ -190,6 +190,4 @@ function PlaceableObject.Create(data, model, onConfirm, onUpdate, onCancel, sett
|
||||
end)
|
||||
end
|
||||
|
||||
return PlaceableObject
|
||||
|
||||
|
||||
return PlaceableObject
|
||||
@@ -0,0 +1,266 @@
|
||||
-- Grid-based point system
|
||||
Point = {}
|
||||
local ActivePoints = {}
|
||||
local GridCells = {}
|
||||
local LoopStarted = false
|
||||
local insidePoints = {}
|
||||
local data = {} -- 👈 Move this outside the function
|
||||
|
||||
-- Grid configuration
|
||||
local GRID_SIZE = 500.0 -- Size of each grid cell
|
||||
local CELL_BUFFER = 1 -- Number of adjacent cells to check
|
||||
|
||||
-- Consider adding these optimizations
|
||||
local ADAPTIVE_WAIT = true -- Adjust wait time based on player speed
|
||||
|
||||
---This is an internal function, do not call this externally
|
||||
function Point.GetCellKey(coords)
|
||||
local cellX = math.floor(coords.x / GRID_SIZE)
|
||||
local cellY = math.floor(coords.y / GRID_SIZE)
|
||||
return cellX .. ":" .. cellY
|
||||
end
|
||||
|
||||
---This is an internal function, do not call this externally
|
||||
function Point.RegisterInGrid(point)
|
||||
local cellKey = Point.GetCellKey(point.coords)
|
||||
|
||||
-- Initialize cell if it doesn't exist
|
||||
GridCells[cellKey] = GridCells[cellKey] or {
|
||||
points = {},
|
||||
count = 0
|
||||
}
|
||||
|
||||
-- Add point to cell
|
||||
GridCells[cellKey].points[point.id] = point
|
||||
GridCells[cellKey].count = GridCells[cellKey].count + 1
|
||||
|
||||
-- Store cell reference in point
|
||||
point.cellKey = cellKey
|
||||
end
|
||||
|
||||
---This is an internal function, do not call this externally
|
||||
function Point.UpdateInGrid(point, oldCellKey)
|
||||
-- Remove from old cell if cell key changed
|
||||
if oldCellKey and oldCellKey ~= point.cellKey then
|
||||
if GridCells[oldCellKey] and GridCells[oldCellKey].points[point.id] then
|
||||
GridCells[oldCellKey].points[point.id] = nil
|
||||
GridCells[oldCellKey].count = GridCells[oldCellKey].count - 1
|
||||
|
||||
-- Clean up empty cells
|
||||
if GridCells[oldCellKey].count <= 0 then
|
||||
GridCells[oldCellKey] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Add to new cell
|
||||
Point.RegisterInGrid(point)
|
||||
end
|
||||
end
|
||||
|
||||
---Gets nearby cells based on the coords
|
||||
---@param coords table
|
||||
---@return table
|
||||
function Point.GetNearbyCells(coords)
|
||||
local cellX = math.floor(coords.x / GRID_SIZE)
|
||||
local cellY = math.floor(coords.y / GRID_SIZE)
|
||||
local nearbyCells = {}
|
||||
|
||||
-- Get current and adjacent cells
|
||||
for x = cellX - CELL_BUFFER, cellX + CELL_BUFFER do
|
||||
for y = cellY - CELL_BUFFER, cellY + CELL_BUFFER do
|
||||
local key = x .. ":" .. y
|
||||
if GridCells[key] then
|
||||
table.insert(nearbyCells, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nearbyCells
|
||||
end
|
||||
|
||||
---Returns all points in the same cell as the given point
|
||||
---This will require you to pass the point object
|
||||
---@param point table
|
||||
---@return table
|
||||
function Point.CheckPointsInSameCell(point)
|
||||
local cellKey = point.cellKey
|
||||
if not GridCells[cellKey] then return {} end
|
||||
|
||||
local nearbyPoints = {}
|
||||
for id, otherPoint in pairs(GridCells[cellKey].points) do
|
||||
if id ~= point.id then
|
||||
local distance = #(point.coords - otherPoint.coords)
|
||||
if distance < (point.distance + otherPoint.distance) then
|
||||
nearbyPoints[id] = otherPoint
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nearbyPoints
|
||||
end
|
||||
|
||||
---Internal function that starts the loop. Do not call this function directly.
|
||||
function Point.StartLoop()
|
||||
if LoopStarted then return false end
|
||||
LoopStarted = true
|
||||
-- Remove the "local data = {}" line from here
|
||||
CreateThread(function()
|
||||
while LoopStarted do
|
||||
local playerPed = PlayerPedId()
|
||||
while playerPed == -1 do
|
||||
Wait(100)
|
||||
playerPed = PlayerPedId()
|
||||
end
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local targetsExist = false
|
||||
local playerCellKey = Point.GetCellKey(playerCoords)
|
||||
local nearbyCells = Point.GetNearbyCells(playerCoords)
|
||||
|
||||
local playerSpeed = GetEntitySpeed(playerPed)
|
||||
local maxWeight = 1000
|
||||
local waitTime = ADAPTIVE_WAIT and math.max(maxWeight/10, maxWeight - playerSpeed * maxWeight/10) or maxWeight
|
||||
-- Process only points in nearby cells
|
||||
for _, cellKey in ipairs(nearbyCells) do
|
||||
if GridCells[cellKey] then
|
||||
for id, point in pairs(GridCells[cellKey].points) do
|
||||
targetsExist = true
|
||||
|
||||
-- Update entity position if needed
|
||||
local oldCellKey = point.cellKey
|
||||
if point.isEntity then
|
||||
point.coords = GetEntityCoords(point.target)
|
||||
point.cellKey = Point.GetCellKey(point.coords)
|
||||
Point.UpdateInGrid(point, oldCellKey)
|
||||
end
|
||||
local coords = point.coords and vector3(point.coords.x, point.coords.y, point.coords.z) or vector3(0, 0, 0)
|
||||
local distance = #(playerCoords - coords)
|
||||
--local distance = #(playerCoords - point.coords)
|
||||
|
||||
-- Check if player entered/exited the point
|
||||
if distance < point.distance then
|
||||
if not point.inside then
|
||||
point.inside = true
|
||||
data[point.id] = data[point.id] or point.args or {}
|
||||
data[point.id] = point.onEnter(point, data[point.id])
|
||||
insidePoints[point.id] = point
|
||||
end
|
||||
-- Modified main loop exit handler
|
||||
elseif point.inside then
|
||||
point.inside = false
|
||||
data[point.id] = data[point.id] or point.args or {}
|
||||
local result = point.onExit(point, data[point.id])
|
||||
data[point.id] = result ~= nil and result or data[point.id] -- ← Use consistent fallback
|
||||
point.args = data[point.id] -- ← Update point.args to match data[point.id]
|
||||
insidePoints[point.id] = nil
|
||||
end
|
||||
|
||||
if point.onNearby then
|
||||
point.onNearby(GridCells[cellKey]?.points, waitTime)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for id, insidepoint in pairs(insidePoints) do
|
||||
local pos = insidepoint.coords and vector3(insidepoint.coords.x, insidepoint.coords.y, insidepoint.coords.z) or vector3(0, 0, 0)
|
||||
local dist = #(playerCoords - pos)
|
||||
if dist > insidepoint.distance then
|
||||
insidepoint.inside = false
|
||||
data[insidepoint.id] = data[insidepoint.id] or insidepoint.args or {}
|
||||
local result = insidepoint.onExit(insidepoint, data[insidepoint.id])
|
||||
data[insidepoint.id] = result ~= nil and result or data[insidepoint.id]
|
||||
insidepoint.args = data[insidepoint.id] -- ← Keep data in sync
|
||||
insidePoints[insidepoint.id] = nil
|
||||
end
|
||||
end
|
||||
Wait(waitTime) -- Faster updates when moving quickly
|
||||
end
|
||||
end)
|
||||
return true
|
||||
end
|
||||
|
||||
---Create a point based on a vector or entityID
|
||||
---@param id string
|
||||
---@param target number || vector3
|
||||
---@param distance number
|
||||
---@param _onEnter function
|
||||
---@param _onExit function
|
||||
---@param _onNearby function
|
||||
---@param data self
|
||||
---@return table
|
||||
function Point.Register(id, target, distance, args, _onEnter, _onExit, _onNearby)
|
||||
local isEntity = type(target) == "number"
|
||||
local coords = isEntity and GetEntityCoords(target) or target
|
||||
|
||||
local self = {}
|
||||
self.id = id
|
||||
self.target = target -- Store entity ID or Vector3
|
||||
self.isEntity = isEntity
|
||||
self.coords = coords
|
||||
self.distance = distance
|
||||
self.onEnter = _onEnter or function() end
|
||||
self.onExit = _onExit or function() end
|
||||
self.onNearby = _onNearby or function() end
|
||||
self.inside = false -- Track if player is inside
|
||||
self.args = args or {}
|
||||
|
||||
ActivePoints[id] = self
|
||||
Point.RegisterInGrid(self)
|
||||
Point.StartLoop()
|
||||
return self
|
||||
end
|
||||
|
||||
---Remove an exsisting point by its id
|
||||
---@param id string
|
||||
function Point.Remove(id)
|
||||
local point = ActivePoints[id]
|
||||
if point then
|
||||
local cellKey = point.cellKey
|
||||
if GridCells[cellKey] and GridCells[cellKey].points[id] then
|
||||
GridCells[cellKey].points[id] = nil
|
||||
GridCells[cellKey].count = GridCells[cellKey].count - 1
|
||||
|
||||
if GridCells[cellKey].count <= 0 then
|
||||
GridCells[cellKey] = nil
|
||||
end
|
||||
end
|
||||
|
||||
ActivePoints[id] = nil
|
||||
end
|
||||
end
|
||||
|
||||
---Returnes a point by its id
|
||||
---@param id string
|
||||
---@return table
|
||||
function Point.Get(id)
|
||||
return ActivePoints[id]
|
||||
end
|
||||
|
||||
---Returns all points
|
||||
---@return table
|
||||
function Point.GetAll()
|
||||
return ActivePoints
|
||||
end
|
||||
|
||||
-- Usage example for checking nearby points
|
||||
-- --
|
||||
-- ▀█▀ █▄█ █ ▄▀▀ █ ▄▀▀ █▀ █ █ ▄▀▀ █▄▀ █ █▄ █ ▄▀ █▄█ ▄▀▄ ▀█▀ █▀▄ ▄▀▄ █ █▄ █ ▀█▀ ▄▀▀ █▀ ▄▀▄ █▀▄ ▄▀▀ █▀▄ ▄▀▄ █ █ █ ██▀ ▀▄▀
|
||||
-- █ █ █ █ ▄█▀ █ ▄█▀ █▀ ▀▄█ ▀▄▄ █ █ █ █ ▀█ ▀▄█ █ █ ▀▄▀ █ ██ █▀ ▀▄▀ █ █ ▀█ █ ▄█▀ █▀ ▀▄▀ █▀▄ ▀▄▄ █▀▄ ▀▄▀ ▀▄▀▄▀ █▄▄ █▄▄ █
|
||||
--[[
|
||||
Point.Register("point1", vector3(100, 100, 30), 5.0,
|
||||
function(point)
|
||||
print("Entered point1")
|
||||
end,
|
||||
function(point)
|
||||
print("Exited point1")
|
||||
end,
|
||||
function(nearbyPoints)
|
||||
print("Point1 has nearby points:")
|
||||
for id, point in pairs(nearbyPoints) do
|
||||
print("- " .. id .. " at distance: " .. #(point.coords - ActivePoints["point1"].coords))
|
||||
end
|
||||
end
|
||||
)
|
||||
--]]
|
||||
|
||||
return Point
|
||||
@@ -3,12 +3,12 @@ Raycast = {}
|
||||
--Rework of oxs Raycast system
|
||||
function Raycast.GetForwardVector(rotation)
|
||||
local camRot = rotation or GetFinalRenderedCamRot(2)
|
||||
|
||||
|
||||
-- Convert each component to radians
|
||||
local rx = math.rad(camRot.x)
|
||||
local ry = math.rad(camRot.y)
|
||||
local rz = math.rad(camRot.z)
|
||||
|
||||
|
||||
-- Calculate sin and cos for each axis
|
||||
local sx = math.sin(rx)
|
||||
local cx = math.cos(rx)
|
||||
@@ -16,12 +16,12 @@ function Raycast.GetForwardVector(rotation)
|
||||
local cy = math.cos(ry)
|
||||
local sz = math.sin(rz)
|
||||
local cz = math.cos(rz)
|
||||
|
||||
|
||||
-- Create forward vector components
|
||||
local x = -sz * math.abs(cx)
|
||||
local y = cz * math.abs(cx)
|
||||
local z = sx
|
||||
|
||||
|
||||
return vector3(x, y, z)
|
||||
end
|
||||
|
||||
@@ -34,7 +34,7 @@ function Raycast.ToCoords(startCoords, endCoords, flag, ignore)
|
||||
retval, entity, finalCoords, normals, material = GetShapeTestResultIncludingMaterial(probe)
|
||||
timeout = timeout - 1
|
||||
Wait(0)
|
||||
end
|
||||
end
|
||||
return retval, entity, finalCoords, normals, material
|
||||
end
|
||||
|
||||
File renamed without changes.
@@ -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
|
||||
@@ -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)
|
||||
File renamed without changes.
@@ -1,20 +1,43 @@
|
||||
Utility = Utility or {}
|
||||
local blipIDs = {}
|
||||
local spawnedPeds = {}
|
||||
local ActivePoints = {}
|
||||
|
||||
---commentThis will create a prop with the passed model string at the coords and heading specified optionally networked or not.
|
||||
---@param model string | number
|
||||
---@param coords table
|
||||
---@param heading number
|
||||
---@param networked boolean
|
||||
---@return number | nil
|
||||
Utility.CreateProp = function(model, coords, heading, networked)
|
||||
Utility.LoadModel(model)
|
||||
if not HasModelLoaded(model) then return Prints.Error("Model Has Not Loaded") end
|
||||
if not HasModelLoaded(model) then return nil, Prints.Error("Model Has Not Loaded") end
|
||||
local propEntity = CreateObject(model, coords.x, coords.y, coords.z, networked, false, false)
|
||||
SetEntityHeading(propEntity, heading)
|
||||
SetModelAsNoLongerNeeded(model)
|
||||
return propEntity
|
||||
end
|
||||
|
||||
---This will get the street name and crossing name at the specified coordinates.
|
||||
---@param coords table
|
||||
---@return string
|
||||
---@return string
|
||||
Utility.GetStreetNameAtCoords = function(coords)
|
||||
local streetHash, crossingHash = GetStreetNameAtCoord(coords.x, coords.y, coords.z)
|
||||
local streetName = GetStreetNameFromHashKey(streetHash)
|
||||
local crossingName = GetStreetNameFromHashKey(crossingHash)
|
||||
return streetName, crossingName
|
||||
end
|
||||
|
||||
---This will create a vehicle with the passed model string at the coords and heading specified.
|
||||
---@param model string
|
||||
---@param coords table
|
||||
---@param heading number
|
||||
---@param networked boolean
|
||||
---@return number| nil
|
||||
---@return table
|
||||
Utility.CreateVehicle = function(model, coords, heading, networked)
|
||||
Utility.LoadModel(model)
|
||||
if not HasModelLoaded(model) then return Prints.Error("Model Has Not Loaded") end
|
||||
if not HasModelLoaded(model) then return nil, {}, Prints.Error("Model Has Not Loaded") end
|
||||
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, networked, false)
|
||||
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
|
||||
SetVehicleNeedsToBeHotwired(vehicle, false)
|
||||
@@ -23,15 +46,24 @@ Utility.CreateVehicle = function(model, coords, heading, networked)
|
||||
return vehicle, { networkid = NetworkGetNetworkIdFromEntity(vehicle) or 0, coords = GetEntityCoords(vehicle), heading = GetEntityHeading(vehicle), }
|
||||
end
|
||||
|
||||
---This will create a ped with the passed model string at the coords and heading specified.
|
||||
---@param model string
|
||||
---@param coords table
|
||||
---@param heading number
|
||||
---@param networked boolean
|
||||
---@return number| nil
|
||||
Utility.CreatePed = function(model, coords, heading, networked, settings)
|
||||
Utility.LoadModel(model)
|
||||
if not HasModelLoaded(model) then return Prints.Error("Model Has Not Loaded") end
|
||||
if not HasModelLoaded(model) then return nil, Prints.Error("Model Has Not Loaded") end
|
||||
local spawnedEntity = CreatePed(0, model, coords.x, coords.y, coords.z, heading, networked, false)
|
||||
SetModelAsNoLongerNeeded(model)
|
||||
table.insert(spawnedPeds, spawnedEntity)
|
||||
return spawnedEntity
|
||||
end
|
||||
|
||||
---This will display a busy spinner with the passed text.
|
||||
---@param text string
|
||||
---@return boolean
|
||||
Utility.StartBusySpinner = function(text)
|
||||
AddTextEntry(text, text)
|
||||
BeginTextCommandBusyString(text)
|
||||
@@ -40,6 +72,8 @@ Utility.StartBusySpinner = function(text)
|
||||
return true
|
||||
end
|
||||
|
||||
---This will stop a busy spinner if one is currently active.
|
||||
---@return boolean
|
||||
Utility.StopBusySpinner = function()
|
||||
if BusyspinnerIsOn() then
|
||||
BusyspinnerOff()
|
||||
@@ -48,6 +82,15 @@ Utility.StopBusySpinner = function()
|
||||
return false
|
||||
end
|
||||
|
||||
---comment Creates a blip at the specified coordinates with the specified parameters. If sprite/color/scale/label are not provided, default values will be used.
|
||||
---@param coords table
|
||||
---@param sprite number
|
||||
---@param color number
|
||||
---@param scale number
|
||||
---@param label string
|
||||
---@param shortRange boolean
|
||||
---@param displayType number
|
||||
---@return integer
|
||||
Utility.CreateBlip = function(coords, sprite, color, scale, label, shortRange, displayType)
|
||||
local blip = AddBlipForCoord(coords.x, coords.y, coords.z)
|
||||
SetBlipSprite(blip, sprite or 8)
|
||||
@@ -62,6 +105,9 @@ Utility.CreateBlip = function(coords, sprite, color, scale, label, shortRange, d
|
||||
return blip
|
||||
end
|
||||
|
||||
---This will remove a blip if it exists in the blipIDs table.
|
||||
---@param blip number
|
||||
---@return boolean
|
||||
Utility.RemoveBlip = function(blip)
|
||||
local success = false
|
||||
for i, storedBlip in ipairs(blipIDs) do
|
||||
@@ -75,6 +121,9 @@ Utility.RemoveBlip = function(blip)
|
||||
return success
|
||||
end
|
||||
|
||||
---Loads a model into memory. If the model is not valid or not in the game files, it will return false.
|
||||
---@param model string | number
|
||||
---@return boolean
|
||||
Utility.LoadModel = function(model)
|
||||
if type(model) ~= 'number' then model = joaat(model) end
|
||||
if not IsModelValid(model) and not IsModelInCdimage(model) then return false end
|
||||
@@ -87,6 +136,9 @@ Utility.LoadModel = function(model)
|
||||
return HasModelLoaded(model)
|
||||
end
|
||||
|
||||
---This function will request an animation dictionary and wait until it is loaded. If the dictionary is not valid, it will return false.
|
||||
---@param dict string
|
||||
---@return boolean
|
||||
Utility.RequestAnimDict = function(dict)
|
||||
RequestAnimDict(dict)
|
||||
local count = 0
|
||||
@@ -97,6 +149,9 @@ Utility.RequestAnimDict = function(dict)
|
||||
return HasAnimDictLoaded(dict)
|
||||
end
|
||||
|
||||
---This will remove a ped if it exists in the spawnedPeds table. It will also delete the entity if it exists.
|
||||
---@param entity number
|
||||
---@return boolean
|
||||
Utility.RemovePed = function(entity)
|
||||
local success = false
|
||||
if DoesEntityExist(entity) then
|
||||
@@ -112,6 +167,10 @@ Utility.RemovePed = function(entity)
|
||||
return success
|
||||
end
|
||||
|
||||
---This will use a native text input menu to allow the user to enter text. It will return the entered text or false if cancelled.
|
||||
---@param text string
|
||||
---@param length number
|
||||
---@return string
|
||||
Utility.NativeInputMenu = function(text, length)
|
||||
local maxLength = Math.Clamp(length, 1, 50)
|
||||
local menutText = text or 'enter text'
|
||||
@@ -128,6 +187,9 @@ Utility.NativeInputMenu = function(text, length)
|
||||
return false
|
||||
end
|
||||
|
||||
---This will get the current skin data of the entity passed. It will return a table with the clothing and props data.
|
||||
---@param entity number
|
||||
---@return table
|
||||
Utility.GetEntitySkinData = function(entity)
|
||||
local skinData = {}
|
||||
for i = 0, 11 do
|
||||
@@ -139,6 +201,10 @@ Utility.GetEntitySkinData = function(entity)
|
||||
return skinData
|
||||
end
|
||||
|
||||
---This will set the skin data of the entity passed. It will set the clothing and props data from the skinData table.
|
||||
---@param entity number
|
||||
---@param skinData table
|
||||
---@return boolean
|
||||
Utility.SetEntitySkinData = function(entity, skinData)
|
||||
for i = 0, 11 do
|
||||
SetPedComponentVariation(entity, i, skinData.clothing[i][1], skinData.clothing[i][2], 0)
|
||||
@@ -149,6 +215,8 @@ Utility.SetEntitySkinData = function(entity, skinData)
|
||||
return true
|
||||
end
|
||||
|
||||
---This will reload the skin data of the entity passed. It will set the clothing and props data from the skinData table and delete any attached objects.
|
||||
---@return boolean
|
||||
Utility.ReloadSkin = function()
|
||||
local skinData = Utility.GetEntitySkinData(cache.ped)
|
||||
Utility.SetEntitySkinData(cache.ped, skinData)
|
||||
@@ -162,18 +230,47 @@ Utility.ReloadSkin = function()
|
||||
return true
|
||||
end
|
||||
|
||||
---This will display a native help text on the screen. It will add a text entry and display it for the specified duration.
|
||||
---@param text string
|
||||
---@param duration number
|
||||
Utility.HelpText = function(text, duration)
|
||||
AddTextEntry(text, text)
|
||||
BeginTextCommandDisplayHelp(text)
|
||||
EndTextCommandDisplayHelp(0, false, true, duration or 5000)
|
||||
end
|
||||
|
||||
---This will display 3D help text at the specified coordinates.
|
||||
---@param coords table
|
||||
---@param text string
|
||||
---@param scale number
|
||||
Utility.Draw3DHelpText = function(coords, text, scale)
|
||||
local onScreen, x, y = GetScreenCoordFromWorldCoord(coords.x, coords.y, coords.z)
|
||||
if onScreen then
|
||||
SetTextScale(scale or 0.35, scale or 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry("STRING")
|
||||
SetTextCentre(1)
|
||||
AddTextComponentString(text)
|
||||
DrawText(x, y)
|
||||
local factor = (string.len(text)) / 370
|
||||
DrawRect(x, y + 0.0125, 0.015 + factor, 0.03, 41, 11, 41, 100)
|
||||
end
|
||||
end
|
||||
|
||||
---This will display a native help text on the screen. It will add a text entry and display it for the specified duration.
|
||||
---@param text string
|
||||
Utility.NotifyText = function(text)
|
||||
AddTextEntry(text, text)
|
||||
SetNotificationTextEntry(text)
|
||||
DrawNotification(false, true)
|
||||
end
|
||||
|
||||
---This will teleport a player to the specified coordinates. If a condition function is passed it will verify that condition is met and then it will fade the screen out and in, freeze the player during the teleport to allow for collisions to load, and call the afterTeleportFunction if provided.
|
||||
---@param coords table
|
||||
---@param conditionFunction function | optional
|
||||
---@param afterTeleportFunction function | optional
|
||||
Utility.TeleportPlayer = function(coords, conditionFunction, afterTeleportFunction)
|
||||
if conditionFunction ~= nil then
|
||||
if not conditionFunction() then
|
||||
@@ -200,11 +297,21 @@ Utility.TeleportPlayer = function(coords, conditionFunction, afterTeleportFuncti
|
||||
end
|
||||
end
|
||||
|
||||
---This will get a model hash from a string or number.
|
||||
---@param model string | number
|
||||
---@return number
|
||||
Utility.GetEntityHashFromModel = function(model)
|
||||
if type(model) ~= 'number' then model = joaat(model) end
|
||||
return model
|
||||
end
|
||||
|
||||
---commentThis will get the closest player, the distance to that player from the coords and the server ID of that player.
|
||||
---@param coords table
|
||||
---@param distanceScope number
|
||||
---@param includeMe boolean
|
||||
---@return integer
|
||||
---@return integer
|
||||
---@return integer
|
||||
Utility.GetClosestPlayer = function(coords, distanceScope, includeMe)
|
||||
local players = GetActivePlayers()
|
||||
local closestPlayer = 0
|
||||
@@ -227,7 +334,7 @@ Utility.GetClosestPlayer = function(coords, distanceScope, includeMe)
|
||||
return closestPlayer, closestDistance, GetPlayerServerId(closestPlayer)
|
||||
end
|
||||
|
||||
---This function is used to register a point on the map, functions are fired when in the distance/exiting the area
|
||||
---This function is is deprecated and will be removed in the future. Please use Pont.Register instead.
|
||||
---@param pointID string
|
||||
---@param pointCoords table
|
||||
---@param pointDistance number
|
||||
@@ -235,39 +342,26 @@ end
|
||||
---@param _onExit function
|
||||
---@param _nearby function
|
||||
Utility.RegisterPoint = function(pointID, pointCoords, pointDistance, _onEnter, _onExit, _nearby)
|
||||
ActivePoints[pointID] = lib.points.new({
|
||||
coords = pointCoords,
|
||||
distance = pointDistance,
|
||||
onEnter = function(self)
|
||||
_onEnter(self)
|
||||
end,
|
||||
onExit = function(self)
|
||||
_onExit(self)
|
||||
end,
|
||||
nearby = function(self)
|
||||
_nearby(self)
|
||||
end
|
||||
})
|
||||
return Point.Register(pointID, pointCoords, pointDistance, nil, _onEnter, _onExit, _nearby)
|
||||
end
|
||||
|
||||
-- Function to retrieve the zone by the pointID
|
||||
---This function is is deprecated and will be removed in the future. Please use Point.Get instead.
|
||||
---@param pointID string
|
||||
Utility.GetPointById = function(pointID)
|
||||
return ActivePoints[pointID]
|
||||
return Point.Get(pointID)
|
||||
end
|
||||
|
||||
---This function is is deprecated and will be removed in the future. Please use Point.GetAll instead.
|
||||
---@return table | nil
|
||||
Utility.GetActivePoints = function()
|
||||
return ActivePoints
|
||||
return Point.GetAll()
|
||||
end
|
||||
---Pass the point ID to remove the point from the map
|
||||
|
||||
---This function is is deprecated and will be removed in the future. Please use Point.Remove instead.
|
||||
---@param pointID string
|
||||
---@return boolean
|
||||
---@return nil
|
||||
Utility.RemovePoint = function(pointID)
|
||||
if not ActivePoints[pointID] then return false end
|
||||
ActivePoints[pointID]:remove()
|
||||
ActivePoints[pointID] = nil
|
||||
return true
|
||||
return Point.Remove(pointID)
|
||||
end
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
Whitespace-only changes.
@@ -0,0 +1,197 @@
|
||||
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 packed = table.pack(func(src, ...))
|
||||
TriggerClientEvent(clientToServerBackToClientName, toAll, name, cbId, table.unpack(packed))
|
||||
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
|
||||
|
||||
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 or {})
|
||||
end
|
||||
|
||||
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
|
||||
TriggerServerEvent(serverToClientBackToServerName, name, cbId, func(...))
|
||||
end)
|
||||
|
||||
exports('RegisterCallback', Callback.Register)
|
||||
exports('RegisterRebound', Callback.RegisterRebound)
|
||||
exports('TriggerCallback', Callback.Trigger)
|
||||
|
||||
return Callback
|
||||
@@ -1,5 +1,11 @@
|
||||
Ids = Ids or {}
|
||||
-- for unique ids
|
||||
|
||||
|
||||
---This will generate a unique id.
|
||||
---@param tbl table
|
||||
---@param len number
|
||||
---@param pattern string
|
||||
---@return string
|
||||
Ids.CreateUniqueId = function(tbl, len, pattern) -- both optional
|
||||
tbl = tbl or {} -- table to check uniqueness. Ids to check against must be the key to the tables value
|
||||
len = len or 8
|
||||
@@ -21,22 +27,43 @@ Ids.CreateUniqueId = function(tbl, len, pattern) -- both optional
|
||||
return id
|
||||
end
|
||||
|
||||
|
||||
---This will generate a unique id.
|
||||
---@param tbl table
|
||||
---@param len number
|
||||
---@return string
|
||||
Ids.RandomUpper = function(tbl, len)
|
||||
return Ids.CreateUniqueId(tbl, len, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
end
|
||||
|
||||
---This will generate a unique id.
|
||||
---@param tbl table
|
||||
---@param len number
|
||||
---@return string
|
||||
Ids.RandomLower = function(tbl, len)
|
||||
return Ids.CreateUniqueId(tbl, len, "abcdefghijklmnopqrstuvwxyz")
|
||||
end
|
||||
|
||||
---This will generate a unique id.
|
||||
---@param tbl table
|
||||
---@param len number
|
||||
---@return string
|
||||
Ids.RandomString = function(tbl, len)
|
||||
return Ids.CreateUniqueId(tbl, len, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
end
|
||||
|
||||
---This will generate a unique id.
|
||||
---@param tbl table
|
||||
---@param len number
|
||||
---@return string
|
||||
Ids.RandomNumber = function(tbl, len)
|
||||
return Ids.CreateUniqueId(tbl, len, "0123456789")
|
||||
end
|
||||
|
||||
---This will generate a unique id.
|
||||
---@param tbl table
|
||||
---@param len number
|
||||
---@return string
|
||||
Ids.Random = function(tbl, len)
|
||||
return Ids.CreateUniqueId(tbl, len)
|
||||
end
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -6,18 +6,27 @@ local function printMessage(level, color, message)
|
||||
print(color .. '[' .. level .. ']:', message)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
end
|
||||
File renamed without changes.
@@ -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)
|
||||
@@ -46,6 +46,14 @@ Table.TableContainsKey = function(tbl, search)
|
||||
return false
|
||||
end
|
||||
|
||||
Table.TableGetKeys = function(tbl)
|
||||
local keys = {}
|
||||
for k ,_ in pairs(tbl) do
|
||||
table.insert(keys,k)
|
||||
end
|
||||
return keys
|
||||
end
|
||||
|
||||
Table.GetClosest = function(coords, tbl)
|
||||
local closestPoint = nil
|
||||
local dist = math.huge
|
||||
+43
-14
@@ -1,16 +1,45 @@
|
||||
{
|
||||
"locale-unit-test": "This is a test string",
|
||||
"place_object_place": "[E] Place \n",
|
||||
"place_object_cancel": "[X] Cancel \n",
|
||||
"place_object_scroll_up": "[SCROLL UP] Turn right \n",
|
||||
"place_object_scroll_down": "[SCROLL DOWN] Turn left",
|
||||
"enter_text": "Enter Text",
|
||||
"no_prop_defined": "You didnt define any object to place",
|
||||
"Shops": {"NotEnoughMoney": "You dont have enough money to buy this item", "Input":"Amount Input", "PurchaseAmount":"Purchase Quanity","PurchasedItem": "You Have Purchased ", "CurrencySymbol": "$", "Confirm":"Confirm Purchase","AreYouSure":"Are you sure you want to purchase a ", "PayByCash": "Pay by cash", "PayByCard": "Pay by card" },
|
||||
"locale-unit-test": "This is a test string",
|
||||
"place_object_place": "[E] Place \n",
|
||||
"place_object_cancel": "[X] Cancel \n",
|
||||
"place_object_scroll_up": "[SCROLL UP] Turn right \n",
|
||||
"place_object_scroll_down": "[SCROLL DOWN] Turn left",
|
||||
"enter_text": "Enter Text",
|
||||
"no_prop_defined": "You didnt define any object to place",
|
||||
"Shops": {
|
||||
"NotEnoughMoney": "You dont have enough money to buy this item",
|
||||
"Input": "Amount Input",
|
||||
"PurchaseAmount": "Purchase Quanity",
|
||||
"PurchasedItem": "You Have Purchased ",
|
||||
"CurrencySymbol": "$",
|
||||
"Confirm": "Confirm Purchase",
|
||||
"AreYouSure": "Are you sure you want to purchase a ",
|
||||
"PayByCash": "Pay by cash",
|
||||
"PayByCard": "Pay by card"
|
||||
},
|
||||
"UNITTEST": {
|
||||
"UNITTESTA": "Im a %s %s",
|
||||
"UNITTEST": {
|
||||
"UNITTESTA": "Im a %s %s",
|
||||
"UNITTEST": {
|
||||
"UNITTESTA": "\n.-._ _,-,\n`._`-._ _,-'_,'\n `._ `-._ _,-' _,'\n `._ `-._ __.-----.__ _,-' _,'\n `._ `#===\\\"\\\"\\\" \\\"\\\"\\\"===#' _,'\n `._/) ._ _. (\\_,'\n )*' **.__ __.** '*(\n # .==..__ \\\"\\\" \\\"\\\" __..==, #\n # `\\\"._(_). .(_)_.\\\"' #"
|
||||
}
|
||||
}
|
||||
}
|
||||
"UNITTESTA": "\n.-._ _,-,\n`._`-._ _,-'_,'\n `._ `-._ _,-' _,'\n `._ `-._ __.-----.__ _,-' _,'\n `._ `#===\\\"\\\"\\\" \\\"\\\"\\\"===#' _,'\n `._/) ._ _. (\\_,'\n )*' **.__ __.** '*(\n # .==..__ \\\"\\\" \\\"\\\" __..==, #\n # `\\\"._(_). .(_)_.\\\"' #"
|
||||
}
|
||||
},
|
||||
"accessibility": {
|
||||
"cb_command": "colourblindness",
|
||||
"cb_title": "Colourblindness Options",
|
||||
"cb_desc": "Select your type of colourblindness\nCurrent Colourblindness: %s",
|
||||
"cb_none": "None",
|
||||
"cb_updated": "Colourblindness has been updated to %s",
|
||||
"cb_default_title": "No Colourblindness",
|
||||
"cb_default_desc": "No colourblindness.\nThis is the default option.",
|
||||
"cb_protanomaly_title": "Protanomaly",
|
||||
"cb_protanomaly_desc": "Red-green color blindness.\nMakes certain shades of red look more green and less bright.\nThis type is mild and usually doesn’t get in the way of normal activities.",
|
||||
"cb_deuteranomaly_title": "Deuteranomaly",
|
||||
"cb_deuteranomaly_desc": "Red-green color blindness.\nIt makes certain shades of green look more red.\nThis type is mild and doesn’t usually get in the way of normal activities.",
|
||||
"cb_dual_title": "Protanopia and Deuteranopia",
|
||||
"cb_dual_desc": "Red-green color blindness.\nMakes someone unable to tell the difference between red and green at all.",
|
||||
"cb_tritanopia_title": "Tritanopia",
|
||||
"cb_tritanopia_desc": "Blue-yellow color blindness that makes someone unable to tell the difference between blue and green, purple and red, and yellow and pink.\nIt also makes colors look less bright.",
|
||||
"cb_tritanomaly_title": "Tritanomaly",
|
||||
"cb_tritanomaly_desc": "Blue-yellow color blindness makes it hard to tell the difference between blue and green and between yellow and red."
|
||||
}
|
||||
}
|
||||
+20
-1
@@ -5,5 +5,24 @@
|
||||
"place_object_scroll_up": "[SCROLL UP] Direita\n",
|
||||
"place_object_scroll_down": "[SCROLL DOWN] Esquerda",
|
||||
"enter_text": "Inserir Texto",
|
||||
"no_prop_defined": "Não definiu nenhum objeto para colocar"
|
||||
"no_prop_defined": "Não definiu nenhum objeto para colocar",
|
||||
"accessibility": {
|
||||
"cb_command": "daltônico",
|
||||
"cb_title": "Opções de daltonismo",
|
||||
"cb_desc": "Selecione seu tipo de daltonismo\nDaltonismo atual: %s",
|
||||
"cb_none": "Nenhum",
|
||||
"cb_updated": "O daltonismo foi atualizado para %s",
|
||||
"cb_default_title": "Sem daltonismo",
|
||||
"cb_default_desc": "Sem daltonismo.\nEsta é a opção padrão.",
|
||||
"cb_protanomaly_title": "Protanomalia",
|
||||
"cb_protanomaly_desc": "Daltonismo vermelho-verde.\nFaz com que certos tons de vermelho pareçam mais verdes e menos brilhantes.\nEste tipo é leve e geralmente não atrapalha as atividades normais.",
|
||||
"cb_deuteranomaly_title": "Deuteranomalia",
|
||||
"cb_deuteranomaly_desc": "Daltonismo vermelho-verde.\nFaz com que certos tons de verde pareçam mais vermelhos.\nEste tipo é leve e geralmente não atrapalha as atividades normais.",
|
||||
"cb_dual_title": "Protanopia e Deuteranopia",
|
||||
"cb_dual_desc": "Daltonismo vermelho-verde.\nFaz com que alguém não consiga distinguir entre vermelho e verde.",
|
||||
"cb_tritanopia_title": "Tritanopia",
|
||||
"cb_tritanopia_desc": "Daltonismo azul-amarelo que faz com que alguém não consiga distinguir a diferença entre azul e verde, roxo e vermelho, e amarelo e rosa.\nTambém faz com que as cores pareçam menos brilhantes.",
|
||||
"cb_tritanomaly_title": "Tritanomalia",
|
||||
"cb_tritanomaly_desc": "O daltonismo azul-amarelo dificulta a distinção entre azul e verde e entre amarelo e vermelho.",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
local colourblind = GetResourceKvpString('colourblind') or "default"
|
||||
local QB = false
|
||||
if (BridgeClientConfig.MenuSystem == "auto" and GetResourceState("qb-menu") ~= "started") or (BridgeClientConfig.MenuSystem ~= "auto" and BridgeClientConfig.MenuSystem == "qb-menu") then
|
||||
QB = true
|
||||
end
|
||||
|
||||
Accessibility = Accessibility or {}
|
||||
|
||||
RegisterCommand(locale("accessibility.cb_command"), function()
|
||||
Accessibility.updatecolourblindness()
|
||||
end, false)
|
||||
|
||||
Accessibility.updatecolourblindness = function()
|
||||
local currentCB = locale("accessibility.cb_"..colourblind.."_title")
|
||||
local cbIcon = "fas fa-eye-low-vision"
|
||||
Menu.Open({
|
||||
id = 'colourblind_update',
|
||||
title = locale("accessibility.cb_title"),
|
||||
options = {
|
||||
{
|
||||
title = locale("accessibility.cb_title"),
|
||||
description = locale("accessibility.cb_desc"):format(currentCB),
|
||||
disabled = true,
|
||||
},
|
||||
{
|
||||
title = locale("accessibility.cb_default_title"),
|
||||
description = locale("accessibility.cb_default_desc"),
|
||||
icon = "fas fa-eye",
|
||||
onSelect = function()
|
||||
colourblind = "default"
|
||||
SetResourceKvp('colourblind', colourblind)
|
||||
Notify.SendNotify(locale("accessibility.cb_updated"):format(locale("accessibility.cb_"..colourblind.."_title")), 'success', 3000)
|
||||
end
|
||||
},
|
||||
{
|
||||
title = locale("accessibility.cb_protanomaly_title"),
|
||||
description = locale("accessibility.cb_protanomaly_desc"),
|
||||
icon = cbIcon,
|
||||
onSelect = function()
|
||||
colourblind = "protanomaly"
|
||||
SetResourceKvp('colourblind', colourblind)
|
||||
Notify.SendNotify(locale("accessibility.cb_updated"):format(locale("accessibility.cb_"..colourblind.."_title")), 'success', 3000)
|
||||
end
|
||||
},
|
||||
{
|
||||
title = locale("accessibility.cb_deuteranomaly_title"),
|
||||
description = locale("accessibility.cb_deuteranomaly_desc"),
|
||||
icon = cbIcon,
|
||||
onSelect = function()
|
||||
colourblind = "deuteranomaly"
|
||||
SetResourceKvp('colourblind', colourblind)
|
||||
Notify.SendNotify(locale("accessibility.cb_updated"):format(locale("accessibility.cb_"..colourblind.."_title")), 'success', 3000)
|
||||
end
|
||||
},
|
||||
{
|
||||
title = locale('accessibility.cb_dual_title'),
|
||||
description = locale("accessibility.cb_dual_desc"),
|
||||
icon = cbIcon,
|
||||
onSelect = function()
|
||||
colourblind = "dual"
|
||||
SetResourceKvp('colourblind', colourblind)
|
||||
Notify.SendNotify(locale("accessibility.cb_updated"):format(locale("accessibility.cb_"..colourblind.."_title")), 'success', 3000)
|
||||
end
|
||||
},
|
||||
{
|
||||
title = locale("accessibility.cb_tritanopia_title"),
|
||||
description = locale("accessibility.cb_tritanopia_desc"),
|
||||
icon = cbIcon,
|
||||
onSelect = function()
|
||||
colourblind = "tritanopia"
|
||||
SetResourceKvp('colourblind', colourblind)
|
||||
Notify.SendNotify(locale("accessibility.cb_updated"):format(locale("accessibility.cb_"..colourblind.."_title")), 'success', 3000)
|
||||
end
|
||||
},
|
||||
{
|
||||
title = locale("accessibility.cb_tritanomaly_title"),
|
||||
description = locale("accessibility.cb_tritanomaly_desc"),
|
||||
icon = cbIcon,
|
||||
onSelect = function()
|
||||
colourblind = "tritanomaly"
|
||||
SetResourceKvp('colourblind', colourblind)
|
||||
Notify.SendNotify(locale("accessibility.cb_updated"):format(locale("accessibility.cb_"..colourblind.."_title")), 'success', 3000)
|
||||
end
|
||||
},
|
||||
}},QB)
|
||||
end
|
||||
Accessibility.hexToRgb = function(hex)
|
||||
hex = hex:gsub("#", "")
|
||||
local r,g,b = tonumber("0x" .. hex:sub(1, 2)),tonumber("0x" .. hex:sub(3, 4)),tonumber("0x" .. hex:sub(5, 6))
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
Accessibility.rgbToHex = function(r, g, b)
|
||||
return string.format("#%02x%02x%02x", r, g, b)
|
||||
end
|
||||
|
||||
Accessibility.rgbToHsl = function(r, g, b)
|
||||
r = r / 255
|
||||
g = g / 255
|
||||
b = b / 255
|
||||
local max = math.max(r, g, b)
|
||||
local min = math.min(r, g, b)
|
||||
local h, s, l = 0, 0, (max + min) / 2
|
||||
|
||||
if max == min then
|
||||
h, s = 0, 0 -- achromatic
|
||||
else
|
||||
local d = max - min
|
||||
s = l > 0.5 and d / (2 - max - min) or d / (max + min)
|
||||
if max == r then
|
||||
h = (g - b) / d + (g < b and 6 or 0)
|
||||
elseif max == g then
|
||||
h = (b - r) / d + 2
|
||||
elseif max == b then
|
||||
h = (r - g) / d + 4
|
||||
end
|
||||
h = h / 6
|
||||
end
|
||||
return h, s, l
|
||||
end
|
||||
|
||||
Accessibility.hslToRgb = function(h, s, l)
|
||||
local r, g, b
|
||||
if s == 0 then
|
||||
r, g, b = l, l, l -- achromatic
|
||||
else
|
||||
local function hue2rgb(p, q, t)
|
||||
if t < 0 then t = t + 1 end
|
||||
if t > 1 then t = t - 1 end
|
||||
if t < 1 / 6 then return p + (q - p) * 6 * t end
|
||||
if t < 1 / 2 then return q end
|
||||
if t < 2 / 3 then return p + (q - p) * (2 / 3 - t) * 6 end
|
||||
return p
|
||||
end
|
||||
|
||||
local q = l < 0.5 and l * (1 + s) or l + s - l * s
|
||||
local p = 2 * l - q
|
||||
r = hue2rgb(p, q, h + 1 / 3)
|
||||
g = hue2rgb(p, q, h)
|
||||
b = hue2rgb(p, q, h - 1 / 3)
|
||||
end
|
||||
return math.floor(r * 255), math.floor(g * 255), math.floor(b * 255)
|
||||
end
|
||||
|
||||
Accessibility.adjustColourForColourblindness = function(num, returnAsRGB)
|
||||
local r, g, b
|
||||
if type(num) ~= "table" and num:match("^#%x%x%x%x%x%x$") then
|
||||
r, g, b = Accessibility.hexToRgb(num) -- Convert hex to RGB
|
||||
else
|
||||
r, g, b = num.r, num.g, num.b -- If it's already RGB, use it directly
|
||||
end
|
||||
local h, s, l = Accessibility.rgbToHsl(r, g, b) -- Convert RGB to HSL
|
||||
-- Adjust hue values based on colourblindness type
|
||||
if colourblind == "protanomaly" then -- Red-blind
|
||||
-- Shift towards blue/cyan
|
||||
h = (h + 0.5) % 1 -- Shift by 180 degrees
|
||||
elseif colourblind == "deuteranomaly" then -- Green-blind
|
||||
-- Shift towards blue/magenta
|
||||
h = (h + 0.33) % 1 -- Shift by 120 degrees
|
||||
elseif colourblind == "dual" then -- Protanopia and Deuteranopia (Red-Green blind)
|
||||
-- More significant shift towards blue/yellow
|
||||
-- This is a more drastic shift to maximize contrast
|
||||
if h < 0.166 then -- Reddish hues
|
||||
h = 0.66 -- Shift to blue
|
||||
elseif h < 0.5 then -- Greenish hues
|
||||
h = 0.166 -- Shift to yellow
|
||||
else
|
||||
h = h -- Leave blue/purple hues alone
|
||||
end
|
||||
-- Increase saturation and lightness to make colours more distinct
|
||||
s = math.min(s * 1.5, 1)
|
||||
l = math.min(l * 1.2, 1)
|
||||
elseif colourblind == "tritanopia" then -- Blue-blind
|
||||
-- Shift towards red/yellow
|
||||
h = (h + 0.16) % 1 -- Shift by 60 degrees
|
||||
elseif colourblind == "tritanomaly" then
|
||||
h = (h + 0.08) % 1
|
||||
end
|
||||
|
||||
-- Convert back to RGB
|
||||
r, g, b = Accessibility.hslToRgb(h, s, l)
|
||||
if returnAsRGB then
|
||||
return {r = r, g = g, b = b}
|
||||
else
|
||||
-- Convert back to HEX
|
||||
local newHex = Accessibility.rgbToHex(r, g, b)
|
||||
return newHex
|
||||
end
|
||||
end
|
||||
|
||||
---@returns a colour adjusted for colourblindness in HEX if variable `returnAsRGB` is false
|
||||
---@param colourName string Colour name in HEX format or RGB format
|
||||
-- This is the trigger function for altering colours for colourblindness :D
|
||||
Accessibility.getAdjustedColour = function(colourName, returnAsRGB)
|
||||
local originalHex = colourName
|
||||
if originalHex then
|
||||
if colourblind == "default" then
|
||||
if type(colourName) == "table" and not returnAsRGB then
|
||||
return Accessibility.rgbToHex(colourName.r, colourName.g, colourName.b)
|
||||
else
|
||||
return originalHex
|
||||
end
|
||||
else
|
||||
return Accessibility.adjustColourForColourblindness(originalHex, returnAsRGB)
|
||||
end
|
||||
else
|
||||
Prints.Error("Invalid Colour Name^0] [^3"..colourName.."^0")
|
||||
return "#FFFFFF" -- Default to white if the colour name is invalid
|
||||
end
|
||||
end
|
||||
@@ -1,22 +1,34 @@
|
||||
--[[This module is incomplete]]--
|
||||
|
||||
Clothing = Clothing or {}
|
||||
|
||||
ClothingBackup = {}
|
||||
|
||||
|
||||
---This will set the peds skin data to the specified table. It will also store previous skin in the event it needs returned to original.
|
||||
---@param data table
|
||||
---@return boolean
|
||||
Clothing.SetAppearance = function(data)
|
||||
ClothingBackup = Clothing.GetAppearance()
|
||||
Utility.SetEntitySkinData(cache.ped, data)
|
||||
return true
|
||||
end
|
||||
|
||||
---This will return a table of the players ped appearance
|
||||
---@return table
|
||||
Clothing.GetAppearance = function()
|
||||
return Utility.GetEntitySkinData(cache.ped)
|
||||
end
|
||||
|
||||
---This will return the peds clothing to the previously stored clothing
|
||||
---@return boolean
|
||||
Clothing.RestoreAppearance = function()
|
||||
Utility.SetEntitySkinData(cache.ped, ClothingBackup)
|
||||
return true
|
||||
end
|
||||
|
||||
---This will reload the peds skin data from the backup table. This is used when the skin data is changed and needs to be reloaded.
|
||||
---@return boolean
|
||||
Clothing.ReloadSkin = function()
|
||||
Utility.SetEntitySkinData(cache.ped, ClothingBackup)
|
||||
return true
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
--[[This module is incomplete]]--
|
||||
|
||||
Clothing = Clothing or {}
|
||||
|
||||
Clothing.SetAppearance = function(src, data)
|
||||
@@ -13,8 +15,6 @@ Clothing.ReloadSkin = function(src)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
RegisterNetEvent('community_bridge:client:SetAppearance', function(data)
|
||||
Clothing.SetAppearance(data)
|
||||
end)
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
if GetResourceState('esx_skin') ~= 'started' then return end
|
||||
|
||||
Clothing = Clothing or {}
|
||||
|
||||
local clothingData = {
|
||||
male = {
|
||||
components = {
|
||||
face = {component_id = 0, texture = 0, drawable = 2},
|
||||
mask = {component_id = 1, texture = 0, drawable = 2},
|
||||
hair = {component_id = 2, texture = 0, drawable = 2},
|
||||
arms = {component_id = 3, texture = 0, drawable = 2},
|
||||
pants = {component_id = 4, texture = 0, drawable = 22},
|
||||
bag = {component_id = 5, texture = 1, drawable = 33},
|
||||
shoes = {component_id = 6, texture = 1, drawable = 33},
|
||||
accessory = {component_id = 7, texture = 1, drawable = 33},
|
||||
shirt = {component_id = 8, texture = 1, drawable = 11},
|
||||
bodyarmor = {component_id = 9, texture = 1, drawable = 33},
|
||||
decals = {component_id = 10, texture = 1, drawable = 33},
|
||||
jacket = {component_id = 11, texture = 2, drawable = 4},
|
||||
},
|
||||
props = {
|
||||
hats = {prop_id = 0, texture = 2, drawable = 4},
|
||||
glasses = {prop_id = 1, texture = 2, drawable = 4},
|
||||
ears = {prop_id = 2, texture = 2, drawable = 4},
|
||||
watches = {prop_id = 6, texture = 2, drawable = 4},
|
||||
bracelets = {prop_id = 7, texture = 2, drawable = 4},
|
||||
}
|
||||
},
|
||||
female = {
|
||||
components = {
|
||||
face = {component_id = 0, texture = 0, drawable = 2},
|
||||
mask = {component_id = 1, texture = 0, drawable = 2},
|
||||
hair = {component_id = 2, texture = 0, drawable = 2},
|
||||
arms = {component_id = 3, texture = 0, drawable = 2},
|
||||
pants = {component_id = 4, texture = 0, drawable = 22},
|
||||
bag = {component_id = 5, texture = 1, drawable = 33},
|
||||
shoes = {component_id = 6, texture = 1, drawable = 33},
|
||||
accessory = {component_id = 7, texture = 1, drawable = 33},
|
||||
shirt = {component_id = 8, texture = 1, drawable = 11},
|
||||
bodyarmor = {component_id = 9, texture = 1, drawable = 33},
|
||||
decals = {component_id = 10, texture = 1, drawable = 33},
|
||||
jacket = {component_id = 11, texture = 2, drawable = 4},
|
||||
},
|
||||
props = {
|
||||
hats = {prop_id = 0, texture = 2, drawable = 4},
|
||||
glasses = {prop_id = 1, texture = 2, drawable = 4},
|
||||
ears = {prop_id = 2, texture = 2, drawable = 4},
|
||||
watches = {prop_id = 6, texture = 2, drawable = 4},
|
||||
bracelets = {prop_id = 7, texture = 2, drawable = 4},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
local function convertDataToFormat(characterData)
|
||||
local gender = characterData.sex
|
||||
|
||||
local repackedClothingData = {
|
||||
[gender] = {
|
||||
components = {},
|
||||
props = {}
|
||||
}
|
||||
}
|
||||
|
||||
local componentMap = {
|
||||
tshirt_1 = 8, -- shirt
|
||||
torso_1 = 11, -- jacket
|
||||
decals_1 = 10, -- decals
|
||||
arms = 3, -- arms
|
||||
pants_1 = 4, -- pants
|
||||
shoes_1 = 6, -- shoes
|
||||
mask_1 = 1, -- mask
|
||||
bproof_1 = 9, -- body armor
|
||||
chain_1 = 7, -- accessory (could be a necklace)
|
||||
bags_1 = 5, -- bag
|
||||
}
|
||||
|
||||
for componentName, componentId in pairs(componentMap) do
|
||||
if characterData[componentName] then
|
||||
repackedClothingData[gender].components[componentName] = {
|
||||
component_id = componentId,
|
||||
texture = characterData[componentName.."_2"],
|
||||
drawable = characterData[componentName.."_1"],
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local propMap = {
|
||||
{"helmet_1", 0}, -- helmet
|
||||
{"glasses_1", 1}, -- glasses
|
||||
{"ears_1", 2}, -- ears
|
||||
{"watches_1", 6}, -- watches
|
||||
{"bracelets_1", 7} -- bracelets
|
||||
}
|
||||
|
||||
for _, prop in ipairs(propMap) do
|
||||
local propName = prop[1]
|
||||
local propId = prop[2]
|
||||
|
||||
if characterData[propName] then
|
||||
repackedClothingData[gender].props[propName] = {
|
||||
prop_id = propId,
|
||||
texture = characterData[propName.."_2"],
|
||||
drawable = characterData[propName.."_1"],
|
||||
}
|
||||
end
|
||||
end
|
||||
return repackedClothingData
|
||||
end
|
||||
|
||||
Clothing.SetAppearance = function(clothingData)
|
||||
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
|
||||
clothingData = clothingData.male
|
||||
clothingData.sex = 0
|
||||
else
|
||||
clothingData = clothingData.female
|
||||
clothingData.sex = 1
|
||||
end
|
||||
local repackedClothingData = convertDataToFormat(clothingData)
|
||||
StoredOldClothing = Clothing.GetAppearance
|
||||
TriggerEvent('skinchanger:loadSkin', repackedClothingData)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.GetAppearance = function()
|
||||
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
|
||||
StoredOldClothing = skin
|
||||
end)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.RestoreAppearance = function()
|
||||
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
|
||||
TriggerEvent('skinchanger:loadSkin', skin)
|
||||
end)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.ReloadSkin = function()
|
||||
local tableCheck = Table.TableContains(StoredOldClothing, "sex")
|
||||
if not tableCheck then return Clothing.RestoreAppearance() end
|
||||
return TriggerEvent('skinchanger:loadSkin', StoredOldClothing)
|
||||
end
|
||||
@@ -1,31 +0,0 @@
|
||||
if GetResourceState('fivem-appearance') ~= 'started' then return end
|
||||
Clothing = Clothing or {}
|
||||
|
||||
Clothing.SetAppearance = function(data)
|
||||
local clothing = {}
|
||||
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
|
||||
clothing = data.male
|
||||
else
|
||||
clothing = data.female
|
||||
end
|
||||
ClothingBackup = exports['fivem-appearance']:getPedAppearance(cache.ped)
|
||||
exports['fivem-appearance']:setPedAppearance(cache.ped, clothing)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.GetAppearance = function()
|
||||
return exports['fivem-appearance']:getPedAppearance(cache.ped)
|
||||
end
|
||||
|
||||
Clothing.RestoreAppearance = function()
|
||||
if not next(ClothingBackup) then
|
||||
return false
|
||||
end
|
||||
exports['fivem-appearance']:setPedAppearance(cache.ped, ClothingBackup)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.ReloadSkin = function()
|
||||
TriggerEvent("fivem-appearance:client:reloadSkin", true)
|
||||
return true
|
||||
end
|
||||
@@ -1,42 +0,0 @@
|
||||
if GetResourceState('illenium-appearance') ~= 'started' then return end
|
||||
Clothing = Clothing or {}
|
||||
|
||||
Clothing.SetAppearance = function(clothingData)
|
||||
local clothing = {}
|
||||
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
|
||||
clothingData = clothingData.male
|
||||
else
|
||||
clothingData = clothingData.female
|
||||
end
|
||||
clothing.components = exports['illenium-appearance']:getPedComponents(cache.ped)
|
||||
clothing.props = exports['illenium-appearance']:getPedProps(cache.ped)
|
||||
|
||||
Prints.Debug(json.encode(clothingData, {indent = true}))
|
||||
ClothingBackup = clothing
|
||||
exports['illenium-appearance']:setPedComponents(cache.ped, clothingData.components)
|
||||
exports['illenium-appearance']:setPedProp(cache.ped, clothingData.props)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.GetAppearance = function()
|
||||
local clothing = {}
|
||||
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
|
||||
clothing = clothing.male
|
||||
else
|
||||
clothing = clothing.female
|
||||
end
|
||||
clothing.components = exports['illenium-appearance']:getPedComponents(cache.ped)
|
||||
clothing.props = exports['illenium-appearance']:getPedProps(cache.ped)
|
||||
|
||||
return clothing
|
||||
end
|
||||
|
||||
Clothing.RestoreAppearance = function()
|
||||
exports['illenium-appearance']:setPedComponents(cache.ped, ClothingBackup.components)
|
||||
exports['illenium-appearance']:setPedProp(cache.ped, ClothingBackup.props)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.ReloadSkin = function()
|
||||
TriggerEvent("illenium-appearance:client:reloadSkin", true)
|
||||
end
|
||||
@@ -1,75 +0,0 @@
|
||||
if GetResourceState('qb-clothing') ~= 'started' then return end
|
||||
|
||||
Clothing = Clothing or {}
|
||||
|
||||
Clothing.SetAppearance = function(data)
|
||||
local clothingData = {}
|
||||
local repackedTable = {}
|
||||
if GetEntityModel(cache.ped) == `mp_m_freemode_01` then
|
||||
clothingData = data.male
|
||||
else
|
||||
clothingData = data.female
|
||||
end
|
||||
ClothingBackup = Clothing.GetAppearance
|
||||
local componentMap = {
|
||||
[1] = 'mask',
|
||||
[3] = 'arms',
|
||||
[4] = 'pants',
|
||||
[5] = 'bag',
|
||||
[6] = 'shoes',
|
||||
[7] = 'accessory',
|
||||
[8] = 't-shirt',
|
||||
[9] = 'vest',
|
||||
[10] = 'decals',
|
||||
[11] = 'torso2'
|
||||
}
|
||||
|
||||
local propMap = {
|
||||
[0] = 'hat',
|
||||
[1] = 'glass',
|
||||
[2] = 'ear',
|
||||
[6] = 'watch',
|
||||
[7] = 'bracelet'
|
||||
}
|
||||
|
||||
local specialMap = {
|
||||
eye_color_id = 'eye_color',
|
||||
moles_id = 'moles',
|
||||
ageing_id = 'ageing',
|
||||
hair_id = 'hair',
|
||||
face_id = 'face'
|
||||
}
|
||||
|
||||
for _, v in pairs(clothingData) do
|
||||
if componentMap[v.component_id] then
|
||||
repackedTable[componentMap[v.component_id]] = {drawable = v.drawable, texture = v.texture}
|
||||
elseif propMap[v.prop_id] then
|
||||
repackedTable[propMap[v.prop_id]] = {drawable = v.drawable, texture = v.texture}
|
||||
elseif specialMap[v.eye_color_id] then
|
||||
repackedTable[specialMap[v.eye_color_id]] = {drawable = v.drawable, texture = v.texture}
|
||||
elseif specialMap[v.moles_id] then
|
||||
repackedTable[specialMap[v.moles_id]] = {drawable = v.drawable, texture = v.texture}
|
||||
elseif specialMap[v.ageing_id] then
|
||||
repackedTable[specialMap[v.ageing_id]] = {drawable = v.drawable, texture = v.texture}
|
||||
elseif specialMap[v.hair_id] then
|
||||
repackedTable[specialMap[v.hair_id]] = {drawable = v.drawable, texture = v.texture}
|
||||
elseif specialMap[v.face_id] then
|
||||
repackedTable[specialMap[v.face_id]] = {drawable = v.drawable, texture = v.texture}
|
||||
end
|
||||
end
|
||||
TriggerEvent('qb-clothing:client:loadOutfit', repackedTable)
|
||||
return true
|
||||
end
|
||||
|
||||
Clothing.GetAppearance = function()
|
||||
ClothingBackup = Utility.GetEntitySkinData(cache.ped)
|
||||
return Utility.GetEntitySkinData(cache.ped)
|
||||
end
|
||||
|
||||
Clothing.RestoreAppearance = function()
|
||||
return Utility.SetEntitySkinData(cache.ped, ClothingBackup)
|
||||
end
|
||||
|
||||
Clothing.ReloadSkin = function()
|
||||
return exports['qb-clothing']:reloadSkin(GetEntityHealth(cache.ped))
|
||||
end
|
||||
@@ -1,8 +0,0 @@
|
||||
if GetResourceState('qb-clothing') ~= 'started' then return end
|
||||
|
||||
RegisterNetEvent('qb-clothing:saveSkin', function(model, skin)
|
||||
local src = source
|
||||
if model and skin then
|
||||
TriggerClientEvent('community_bridge:client:updateClothingBackup', src, skin)
|
||||
end
|
||||
end)
|
||||
@@ -1,3 +1,6 @@
|
||||
--[[This module is incomplete]]--
|
||||
|
||||
|
||||
local promises = {}
|
||||
local activeDialogue = nil
|
||||
local pendingCameraDestroy = false
|
||||
@@ -59,7 +62,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)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
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)
|
||||
TriggerServerEvent('community_bridge:Server:DispatchAlert', {
|
||||
sprite = data.blipData.sprite or 161,
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
if GetResourceState('lb-tablet') ~= 'started' then return end
|
||||
Dispatch = Dispatch or {}
|
||||
|
||||
local function getPriorityLevel(priority)
|
||||
if priority == 1 then
|
||||
return 'low'
|
||||
elseif priority == 2 then
|
||||
return 'medium'
|
||||
elseif priority == 3 then
|
||||
return 'high'
|
||||
else
|
||||
return 'medium'
|
||||
end
|
||||
end
|
||||
|
||||
---commentThis will send an alert to the passed jobs
|
||||
---@param data table
|
||||
Dispatch.SendAlert = function(data)
|
||||
local streetName, _ = Utility.GetStreetNameAtCoords(data.coords)
|
||||
local priority = getPriorityLevel(data.priority)
|
||||
if type(data.jobs) == 'table' then
|
||||
data.jobs = data.jobs[1]
|
||||
end
|
||||
if data.time and data.time > 1000 then
|
||||
data.time = math.floor((data.time / 1000) + 0.5)
|
||||
end
|
||||
local alertData = {
|
||||
priority = priority,
|
||||
code = data.code or '10-80',
|
||||
title = 'Dispatch Alert!',
|
||||
description = data.message,
|
||||
location = {
|
||||
label = streetName,
|
||||
coords = vec2(data.coords.x, data.coords.y)
|
||||
},
|
||||
time = data.time or 10000,
|
||||
job = data.jobs,
|
||||
}
|
||||
TriggerServerEvent("community_bridge:server:dispatch:sendAlert", alertData)
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
if GetResourceState('lb-tablet') ~= 'started' then return end
|
||||
Dispatch = Dispatch or {}
|
||||
|
||||
RegisterNetEvent("community_bridge:server:dispatch:sendAlert", function(data)
|
||||
exports["lb-tablet"]:AddDispatch(data) -- this has a return value but we dont really have a use for it atm.
|
||||
end)
|
||||
@@ -1,4 +1,5 @@
|
||||
if GetResourceState('ps-dispatch') ~= 'started' then return end
|
||||
if GetResourceState('lb-tablet') == 'started' then return end
|
||||
Dispatch = Dispatch or {}
|
||||
|
||||
Dispatch.SendAlert = function(data)
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
if GetResourceState('ps-dispatch') ~= 'started' then return end
|
||||
if GetResourceState('lb-tablet') == 'started' then return end
|
||||
Dispatch = Dispatch or {}
|
||||
@@ -0,0 +1,14 @@
|
||||
if GetResourceState('redutzu-mdt') ~= 'started' then return end
|
||||
Dispatch = Dispatch or {}
|
||||
|
||||
Dispatch.SendAlert = function(data)
|
||||
local streetName, _ = Utility.GetStreetNameAtCoords(data.coords)
|
||||
local alertData = {
|
||||
code = data.code or '10-80',
|
||||
message = data.message or "Dispatch Alert",
|
||||
street = streetName,
|
||||
time = data.time or 10000,
|
||||
coords = data.coords,
|
||||
}
|
||||
TriggerServerEvent("community_bridge:server:dispatch:sendAlert", alertData)
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
if GetResourceState('redutzu-mdt') ~= 'started' then return end
|
||||
Dispatch = Dispatch or {}
|
||||
|
||||
RegisterNetEvent("community_bridge:server:dispatch:sendAlert", function(data)
|
||||
TriggerEvent('redutzu-mdt:server:addDispatchToMDT', {
|
||||
code = data.code,
|
||||
title = data.message,
|
||||
street = data.street,
|
||||
duration = data.time,
|
||||
coords = data.coords
|
||||
})
|
||||
end)
|
||||
@@ -2,6 +2,11 @@ if GetResourceState('doors_creator') ~= 'started' then return end
|
||||
|
||||
Doorlock = Doorlock or {}
|
||||
|
||||
|
||||
---This will toggle the lock status of the door.
|
||||
---@param doorID string
|
||||
---@param toggle boolean
|
||||
---@return boolean
|
||||
Doorlock.ToggleDoorLock = function(doorID, toggle)
|
||||
local state = toggle
|
||||
if state then
|
||||
|
||||
@@ -2,6 +2,8 @@ if GetResourceState('ox_doorlock') ~= 'started' then return end
|
||||
|
||||
Doorlock = Doorlock or {}
|
||||
|
||||
---This will get the closest door to the ped
|
||||
---@return string | nil
|
||||
Doorlock.GetClosestDoor = function()
|
||||
return exports.ox_doorlock:getClosestDoor()
|
||||
end
|
||||
@@ -14,6 +14,11 @@ Framework.GetPlayerData = function()
|
||||
return ESX.PlayerData
|
||||
end
|
||||
|
||||
Framework.GetFrameworkJobs = function()
|
||||
local jobs = lib.callback.await('community_bridge:Callback:GetFrameworkJobs', false)
|
||||
return jobs
|
||||
end
|
||||
|
||||
---comment
|
||||
---@return string
|
||||
Framework.GetPlayerDob = function()
|
||||
@@ -75,6 +80,15 @@ Framework.GetPlayerInventory = function()
|
||||
return playerData.inventory
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return number
|
||||
Framework.GetItemCount = function(item)
|
||||
local inventory = Framework.GetPlayerInventory()
|
||||
if not inventory then return 0 end
|
||||
return inventory[item].count or 0
|
||||
end
|
||||
|
||||
---comment
|
||||
---@return boolean
|
||||
Framework.GetIsPlayerDead = function()
|
||||
|
||||
@@ -23,6 +23,10 @@ Framework.GetPlayerIdentifier = function(src)
|
||||
return xPlayer.getIdentifier()
|
||||
end
|
||||
|
||||
Framework.GetFrameworkJobs = function()
|
||||
return ESX.GetJobs()
|
||||
end
|
||||
|
||||
-- Framework.GetPlayerName(src)
|
||||
-- Returns the first and last name of the player.
|
||||
Framework.GetPlayerName = function(src)
|
||||
@@ -259,6 +263,11 @@ Framework.RegisterUsableItem = function(itemName, cb)
|
||||
ESX.RegisterUsableItem(itemName, func)
|
||||
end
|
||||
|
||||
RegisterNetEvent("esx:playerLoaded", function()
|
||||
local src = source
|
||||
TriggerEvent("community_bridge:Server:OnPlayerLoaded", src)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("esx:playerLogout", function()
|
||||
local src = source
|
||||
TriggerEvent("community_bridge:Server:OnPlayerUnload", src)
|
||||
@@ -269,6 +278,10 @@ AddEventHandler("playerDropped", function()
|
||||
TriggerEvent("community_bridge:Server:OnPlayerUnload", src)
|
||||
end)
|
||||
|
||||
lib.callback.register('community_bridge:Callback:GetFrameworkJobs', function(source)
|
||||
return Framework.GetFrameworkJobs() or {}
|
||||
end)
|
||||
|
||||
Framework.Commands = {}
|
||||
Framework.Commands.Add = function(name, help, arguments, argsrequired, callback, permission, ...)
|
||||
ESX.RegisterCommand(name, permission, function(xPlayer, args, showError)
|
||||
|
||||
@@ -5,6 +5,8 @@ QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
Framework = {}
|
||||
|
||||
---This will get the name of the framework being used (if a supported framework).
|
||||
---@return string
|
||||
Framework.GetFrameworkName = function()
|
||||
return 'qb-core'
|
||||
end
|
||||
@@ -13,12 +15,31 @@ Framework.GetPlayerData = function()
|
||||
return QBCore.Functions.GetPlayerData()
|
||||
end
|
||||
|
||||
---This will return a table of all the jobs in the framework.
|
||||
---@return table
|
||||
Framework.GetFrameworkJobs = function()
|
||||
local jobs = {}
|
||||
for k, v in pairs(QBCore.Shared.Jobs) do
|
||||
table.insert(jobs, {
|
||||
name = k,
|
||||
label = v.label,
|
||||
grade = v.grades
|
||||
})
|
||||
end
|
||||
return jobs
|
||||
end
|
||||
|
||||
---This will get the players birth date
|
||||
---@return string
|
||||
Framework.GetPlayerDob = function()
|
||||
local player = QBCore.Functions.GetPlayerData()
|
||||
local playerData = player.PlayerData
|
||||
return playerData.charinfo.birthdate
|
||||
end
|
||||
|
||||
---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 QBCore.Functions.GetPlayerData().metadata[metadata]
|
||||
end
|
||||
@@ -49,15 +70,25 @@ Framework.GetItemInfo = function(item)
|
||||
return repackedTable
|
||||
end
|
||||
|
||||
---This will get the players identifier (citizenid) etc.
|
||||
---@return string
|
||||
Framework.GetPlayerIdentifier = function()
|
||||
return QBCore.Functions.GetPlayerData().citizenid
|
||||
end
|
||||
|
||||
---This will get the players name (first and last).
|
||||
---@return string
|
||||
---@return string
|
||||
Framework.GetPlayerName = function()
|
||||
local playerData = QBCore.Functions.GetPlayerData()
|
||||
return playerData.charinfo.firstname, playerData.charinfo.lastname
|
||||
end
|
||||
|
||||
---This will return the players job name, job label, job grade name and job grade level.
|
||||
---@return string
|
||||
---@return string
|
||||
---@return string
|
||||
---@return string
|
||||
Framework.GetPlayerJob = function()
|
||||
local playerData = QBCore.Functions.GetPlayerData()
|
||||
return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level
|
||||
@@ -67,6 +98,20 @@ Framework.HasItem = function(item)
|
||||
return QBCore.Functions.HasItem(item)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return number
|
||||
Framework.GetItemCount = function(item)
|
||||
local frameworkInv = QBCore.Functions.GetPlayerData().items
|
||||
local count = 0
|
||||
for _, v in pairs(frameworkInv) do
|
||||
if v.name == item then
|
||||
count = count + v.amount
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
Framework.GetPlayerInventory = function()
|
||||
local items = {}
|
||||
local frameworkInv = QBCore.Functions.GetPlayerData().items
|
||||
@@ -85,6 +130,8 @@ Framework.GetPlayerInventory = function()
|
||||
return items
|
||||
end
|
||||
|
||||
---This will get a players dead status.
|
||||
---@return boolean
|
||||
Framework.GetIsPlayerDead = function()
|
||||
local playerData = QBCore.Functions.GetPlayerData()
|
||||
return playerData.metadata["isdead"] or playerData.metadata["inlaststand"]
|
||||
|
||||
@@ -18,8 +18,21 @@ Framework.GetPlayerIdentifier = function(src)
|
||||
return playerData.citizenid
|
||||
end
|
||||
|
||||
Framework.GetFrameworkJobs = function()
|
||||
local jobs = {}
|
||||
for k, v in pairs(QBCore.Shared.Jobs) do
|
||||
table.insert(jobs, {
|
||||
name = k,
|
||||
label = v.label,
|
||||
grade = v.grades
|
||||
})
|
||||
end
|
||||
return jobs
|
||||
end
|
||||
|
||||
-- Framework.GetPlayerName(src)
|
||||
-- Returns the first and last name of the player.
|
||||
---@return string, string
|
||||
Framework.GetPlayerName = function(src)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -27,6 +40,8 @@ Framework.GetPlayerName = function(src)
|
||||
return playerData.charinfo.firstname, playerData.charinfo.lastname
|
||||
end
|
||||
|
||||
---This will get the players birth date
|
||||
---@return string
|
||||
Framework.GetPlayerDob = function(src)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -126,6 +141,7 @@ end
|
||||
|
||||
-- Framework.SetMetadata(src, metadata, value)
|
||||
-- Adds the specified metadata key and number value to the player's data.
|
||||
---@return boolean | nil
|
||||
Framework.SetPlayerMetadata = function(src, metadata, value)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -144,6 +160,7 @@ end
|
||||
|
||||
-- Framework.AddStress(src, value)
|
||||
-- Adds the specified value to the player's stress level and updates the client HUD.
|
||||
---@return number | nil
|
||||
Framework.AddStress = function(src, value)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -156,6 +173,7 @@ end
|
||||
|
||||
-- Framework.RemoveStress(src, value)
|
||||
-- Removes the specified value from the player's stress level and updates the client HUD.
|
||||
---@return number | nil
|
||||
Framework.RemoveStress = function(src, value)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -168,6 +186,7 @@ end
|
||||
|
||||
-- Framework.AddHunger(src, value)
|
||||
-- Adds the specified value from the player's hunger level.
|
||||
---@return number | nil
|
||||
Framework.AddHunger = function(src, value)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -180,6 +199,7 @@ end
|
||||
|
||||
-- Framework.AddThirst(src, value)
|
||||
-- Adds the specified value from the player's thirst level.
|
||||
---@return number | nil
|
||||
Framework.AddThirst = function(src, value)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -190,6 +210,9 @@ Framework.AddThirst = function(src, value)
|
||||
return newThirst
|
||||
end
|
||||
|
||||
---This will get the hunger of a player
|
||||
---@param src any
|
||||
---@return number | nil
|
||||
Framework.GetHunger = function(src)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -198,6 +221,10 @@ Framework.GetHunger = function(src)
|
||||
return newHunger
|
||||
end
|
||||
|
||||
|
||||
---This will get the thirst of a player
|
||||
---@param src any
|
||||
---@return number | nil
|
||||
Framework.GetThirst = function(src)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -224,8 +251,9 @@ Framework.GetPlayerGang = function(src)
|
||||
return playerData.gang.name
|
||||
end
|
||||
|
||||
-- Framework.GetPlayersByJob(jobname)
|
||||
-- returns a table of player sources that have the specified job name.
|
||||
---This will get a table of player sources that have the specified job name.
|
||||
---@param job any
|
||||
---@return table
|
||||
Framework.GetPlayersByJob = function(job)
|
||||
local players = QBCore.Functions.GetPlayers()
|
||||
local playerList = {}
|
||||
@@ -238,8 +266,12 @@ Framework.GetPlayersByJob = function(job)
|
||||
return playerList
|
||||
end
|
||||
|
||||
-- Framework.GetPlayerJob(src)
|
||||
-- Returns the job name, label, grade name, and grade level of the player.
|
||||
---This will get the players job info
|
||||
---@param src number
|
||||
---@return string
|
||||
---@return string
|
||||
---@return string
|
||||
---@return string
|
||||
Framework.GetPlayerJob = function(src)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -247,14 +279,21 @@ Framework.GetPlayerJob = function(src)
|
||||
return playerData.job.name, playerData.job.label, playerData.job.grade.name, playerData.job.grade.level
|
||||
end
|
||||
|
||||
-- Framework.SetPlayerJob(src, name, grade)
|
||||
-- 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 = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
return player.Functions.SetJob(name, grade)
|
||||
end
|
||||
|
||||
---This will toggle a players duty status
|
||||
---@param src number
|
||||
---@param status boolean
|
||||
---@return nil
|
||||
Framework.ToggleDuty = function(src, status)
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -262,8 +301,12 @@ Framework.ToggleDuty = function(src, status)
|
||||
TriggerEvent('QBCore:Server:SetDuty', src, player.PlayerData.job.onduty)
|
||||
end
|
||||
|
||||
-- Framework.AddAccountBalance(src, _type, amount)
|
||||
-- Adds the specified amount to the player's account balance of the specified type.
|
||||
|
||||
---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 = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -271,8 +314,11 @@ Framework.AddAccountBalance = function(src, _type, amount)
|
||||
return player.Functions.AddMoney(_type, amount)
|
||||
end
|
||||
|
||||
-- Framework.RemoveAccountBalance(src, _type, amount)
|
||||
-- Removes the specified amount from the player's account balance of the specified type.
|
||||
---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 = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -280,8 +326,10 @@ Framework.RemoveAccountBalance = function(src, _type, amount)
|
||||
return player.Functions.RemoveMoney(_type, amount)
|
||||
end
|
||||
|
||||
-- Framework.GetAccountBalance(src, _type)
|
||||
-- Returns the player's account balance of the specified type.
|
||||
---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 = QBCore.Functions.GetPlayer(src)
|
||||
if not player then return end
|
||||
@@ -329,6 +377,9 @@ Framework.SetMetadata = function(src, item, slot, metadata)
|
||||
return player.Functions.AddItem(item, 1, freeSlot, metadata)
|
||||
end
|
||||
|
||||
---This will get all owned vehicles for the player
|
||||
---@param src number
|
||||
---@return table
|
||||
Framework.GetOwnedVehicles = function(src)
|
||||
local citizenId = Framework.GetPlayerIdentifier(src)
|
||||
local result = MySQL.Sync.fetchAll("SELECT vehicle, plate FROM player_vehicles WHERE citizenid = '" .. citizenId .. "'")
|
||||
@@ -352,7 +403,12 @@ Framework.RegisterUsableItem = function(itemName, cb)
|
||||
QBCore.Functions.CreateUseableItem(itemName, func)
|
||||
end
|
||||
|
||||
RegisterNetEvent("QBCore:Server:OnPlayerUnload", function()
|
||||
RegisterNetEvent("QBCore:Server:OnPlayerLoaded", function()
|
||||
local src = source
|
||||
TriggerEvent("community_bridge:Server:OnPlayerLoaded", src)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("QBCore:Server:OnPlayerUnload", function(source)
|
||||
local src = source
|
||||
TriggerEvent("community_bridge:Server:OnPlayerUnload", src)
|
||||
end)
|
||||
|
||||
@@ -12,6 +12,10 @@ Framework.GetPlayerData = function()
|
||||
return QBox.GetPlayerData()
|
||||
end
|
||||
|
||||
Framework.GetFrameworkJobs = function()
|
||||
return QBox.GetJobs()
|
||||
end
|
||||
|
||||
Framework.GetPlayerDob = function()
|
||||
local playerData = QBox.GetPlayerData()
|
||||
return playerData.charinfo.birthdate
|
||||
@@ -40,6 +44,14 @@ Framework.GetPlayerInventory = function()
|
||||
return QBox.GetPlayerData().items
|
||||
end
|
||||
|
||||
---comment
|
||||
---@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.")
|
||||
end
|
||||
|
||||
Framework.GetIsPlayerDead = function()
|
||||
local platerData = QBox.GetPlayerData()
|
||||
return platerData.metadata["isdead"] or platerData.metadata["inlaststand"]
|
||||
|
||||
@@ -15,6 +15,10 @@ Framework.GetPlayerDob = function(src)
|
||||
return playerData.charinfo.birthdate
|
||||
end
|
||||
|
||||
Framework.GetFrameworkJobs = function()
|
||||
return QBox.GetJobs()
|
||||
end
|
||||
|
||||
-- Framework.GetPlayerIdentifier(src)
|
||||
-- Returns the citizen ID of the player.
|
||||
Framework.GetPlayerIdentifier = function(src)
|
||||
@@ -297,6 +301,11 @@ Framework.GetOwnedVehicles = function(src)
|
||||
return vehicles
|
||||
end
|
||||
|
||||
RegisterNetEvent("QBCore:Server:OnPlayerLoaded", function()
|
||||
local src = source
|
||||
TriggerEvent("community_bridge:Server:OnPlayerLoaded", src)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("QBCore:Server:OnPlayerUnload", function()
|
||||
local src = source
|
||||
TriggerEvent("community_bridge:Server:OnPlayerUnload", src)
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
Fuel = Fuel or {}
|
||||
----print("Fuel: Loading Defualt")
|
||||
|
||||
---This will get the fuel level of the vehicle.
|
||||
---@param vehicle number The vehicle entity ID.
|
||||
---@return number fuel The fuel level of the vehicle.
|
||||
Fuel.GetFuel = function(vehicle)
|
||||
if not DoesEntityExist(vehicle) then return 0.0 end
|
||||
return GetVehicleFuelLevel(vehicle)
|
||||
end
|
||||
|
||||
Fuel.SetFuel = function(vehicle, fuel, type)
|
||||
---This will set the fuel level of the vehicle.
|
||||
---@param vehicle number The vehicle entity ID.
|
||||
---@param fuel number The fuel level to set.
|
||||
---@return nil
|
||||
Fuel.SetFuel = function(vehicle, fuel)
|
||||
if not DoesEntityExist(vehicle) then return end
|
||||
return SetVehicleFuelLevel(vehicle, fuel)
|
||||
end
|
||||
@@ -2,6 +2,7 @@ local resourceName = "lc_fuel"
|
||||
local configValue = BridgeClientConfig.Fuel
|
||||
if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end
|
||||
--print("Fuel: Loading lc_fuel")
|
||||
if GetResourceState('lc_fuel') ~= 'started' then return end
|
||||
Fuel = Fuel or {}
|
||||
|
||||
Fuel.GetFuel = function(vehicle)
|
||||
@@ -9,7 +10,8 @@ Fuel.GetFuel = function(vehicle)
|
||||
return exports["lc_fuel"]:GetFuel(vehicle)
|
||||
end
|
||||
|
||||
Fuel.SetFuel = function(vehicle, fuel)
|
||||
|
||||
Fuel.SetFuel = function(vehicle, fuel, type)
|
||||
if not DoesEntityExist(vehicle) then return end
|
||||
return exports["lc_fuel"]:SetFuel(vehicle, fuel)
|
||||
end
|
||||
end
|
||||
@@ -14,6 +14,10 @@ Inventory.HasItem = function(item)
|
||||
return Framework.HasItem(item)
|
||||
end
|
||||
|
||||
Inventory.GetItemCount = function(item)
|
||||
return Framework.GetItemCount(item)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return string
|
||||
|
||||
@@ -83,4 +83,4 @@ end
|
||||
---@return string
|
||||
Inventory.GetImagePath = function(item)
|
||||
return "https://avatars.githubusercontent.com/u/47620135"
|
||||
end
|
||||
end
|
||||
@@ -27,6 +27,18 @@ Inventory.HasItem = function(item)
|
||||
return origin:HasItem(item)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return number
|
||||
Inventory.GetItemCount = function(item)
|
||||
local searchItem = origin:Search('slots', item)
|
||||
local count = 0
|
||||
for _, v in pairs(searchItem) do
|
||||
count = count + v.count
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return string
|
||||
|
||||
@@ -29,6 +29,13 @@ Inventory.HasItem = function(item)
|
||||
return hasItem
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return number
|
||||
Inventory.GetItemCount = function(item)
|
||||
return ox_inventory:GetItemCount(item, nil, false)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return string
|
||||
|
||||
@@ -37,7 +37,7 @@ Inventory.GetItem = function(src, item, metadata)
|
||||
return ox_inventory:GetItem(src, item, metadata, false)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will get the item from the specified slot.
|
||||
---@param src number
|
||||
---@param slot number
|
||||
---@return table
|
||||
@@ -63,14 +63,14 @@ Inventory.HasItem = function(src, item)
|
||||
return count > 0
|
||||
end
|
||||
|
||||
---comment
|
||||
---This wil return the players inventory.
|
||||
---@param src number
|
||||
---@return table
|
||||
Inventory.GetPlayerInventory = function(src)
|
||||
return ox_inventory:GetInventoryItems(src, false)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This is to get if there is available space in the inventory.
|
||||
---@param src number
|
||||
---@param item string
|
||||
---@param count number
|
||||
@@ -79,7 +79,7 @@ Inventory.CanCarryItem = function(src, item, count)
|
||||
return ox_inventory:CanCarryItem(src, item, count)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will register a stash
|
||||
---@param id number||string
|
||||
---@param label string
|
||||
---@param slots number
|
||||
@@ -106,7 +106,7 @@ Inventory.OpenStash = function(src, id, label, slots, weight, owner, groups, coo
|
||||
TriggerClientEvent('ox_inventory:openInventory', src, 'stash', 'stash_' .. id)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will get the data about an item such as name, label, stack, weight, description and image.
|
||||
---@param item string
|
||||
---@return table
|
||||
Inventory.GetItemInfo = function(item)
|
||||
@@ -123,7 +123,7 @@ Inventory.GetItemInfo = function(item)
|
||||
return repackedTable
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will set the metadata of an item in the inventory.
|
||||
---@param src number
|
||||
---@param item string
|
||||
---@param slot number
|
||||
@@ -133,7 +133,7 @@ Inventory.SetMetadata = function(src, item, slot, metadata)
|
||||
ox_inventory:SetMetadata(src, slot, metadata)
|
||||
end
|
||||
|
||||
---comment
|
||||
---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
|
||||
@@ -144,7 +144,7 @@ Inventory.UpdatePlate = function(oldplate, newplate)
|
||||
return true
|
||||
end
|
||||
|
||||
---comment
|
||||
---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)
|
||||
|
||||
@@ -44,6 +44,14 @@ Inventory.GetImagePath = function(item)
|
||||
return imagePath or "https://avatars.githubusercontent.com/u/47620135"
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return number
|
||||
Inventory.GetItemCount = function(item)
|
||||
local searchItem = quasar:Search(item)
|
||||
return searchItem or 0
|
||||
end
|
||||
|
||||
---comment
|
||||
---@return table
|
||||
Inventory.GetPlayerInventory = function()
|
||||
|
||||
@@ -25,6 +25,14 @@ Inventory.GetItemInfo = function(item)
|
||||
return repackedTable
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param item string
|
||||
---@return number
|
||||
Inventory.GetItemCount = function(item)
|
||||
local searchItem = tgiann:GetItemCount(item, nil, false)
|
||||
return searchItem or 0
|
||||
end
|
||||
|
||||
---This will return a boolean if the player has the item in the inventory
|
||||
---@param item string
|
||||
---@return boolean
|
||||
|
||||
@@ -47,29 +47,4 @@ function Language.Locale(str, ...)
|
||||
return current
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
if BridgeSharedConfig.DebugLevel == 2 then
|
||||
-- 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("locale-unit-test"))
|
||||
|
||||
-- Example outside community bridge resource:
|
||||
|
||||
-- local Language = Require('modules/locales/shared.lua')
|
||||
-- print("Language: ", Lang)
|
||||
-- print("Locale: ", Language.Locale("locale-unit-test"))
|
||||
RegisterCommand("lang", function(source, args, raw)
|
||||
print(Language.Locale("UNITTEST.UNITTEST.UNITTESTA"))
|
||||
print(Language.Locale("UNITTEST.UNITTESTA", "Devil", "GERRRRRRR!"))
|
||||
|
||||
print( "Oh also this works", Language.Locale("place_object_scroll_down"))
|
||||
end)
|
||||
end
|
||||
|
||||
return Language
|
||||
@@ -1,14 +1,25 @@
|
||||
if GetResourceState('Renewed-Banking') ~= 'started' then return end
|
||||
Managment = Managment or {}
|
||||
|
||||
---This will return a table with account details
|
||||
---@param account string
|
||||
---@return table
|
||||
Managment.GetAccountMoney = function(account)
|
||||
return exports['Renewed-Banking']:getAccountMoney(account)
|
||||
end
|
||||
|
||||
---This will add money to the specified account of the passed amount
|
||||
---@param account string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
Managment.AddAccountMoney = function(account, amount)
|
||||
return exports['Renewed-Banking']:addAccountMoney(account, amount)
|
||||
end
|
||||
|
||||
---This will remove money from the specified account of the passed amount
|
||||
---@param account string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
Managment.RemoveAccountMoney = function(account, amount)
|
||||
return exports['Renewed-Banking']:removeAccountMoney(account, amount)
|
||||
end
|
||||
@@ -1,14 +1,25 @@
|
||||
if GetResourceState('okokBanking') ~= 'started' then return end
|
||||
Managment = Managment or {}
|
||||
|
||||
---This will return a table with account details
|
||||
---@param account string
|
||||
---@return table
|
||||
Managment.GetAccountMoney = function(account)
|
||||
return exports['okokBanking']:GetAccount(account)
|
||||
end
|
||||
|
||||
---This will add money to the specified account of the passed amount
|
||||
---@param account string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
Managment.AddAccountMoney = function(account, amount)
|
||||
return exports['okokBanking']:AddMoney(account, amount)
|
||||
end
|
||||
|
||||
---This will remove money from the specified account of the passed amount
|
||||
---@param account string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
Managment.RemoveAccountMoney = function(account, amount)
|
||||
return exports['okokBanking']:RemoveMoney(account, amount)
|
||||
end
|
||||
@@ -1,14 +1,25 @@
|
||||
if GetResourceState('qb-banking') ~= 'started' then return end
|
||||
Managment = Managment or {}
|
||||
|
||||
---This will return a table with account details
|
||||
---@param account string
|
||||
---@return table
|
||||
Managment.GetAccountMoney = function(account)
|
||||
return exports['qb-banking']:GetAccountBalance(account)
|
||||
end
|
||||
|
||||
---This will add money to the specified account of the passed amount
|
||||
---@param account string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
Managment.AddAccountMoney = function(account, amount)
|
||||
return exports['qb-banking']:AddMoney(account, amount)
|
||||
end
|
||||
|
||||
---This will remove money from the specified account of the passed amount
|
||||
---@param account string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
Managment.RemoveAccountMoney = function(account, amount)
|
||||
return exports['qb-banking']:RemoveMoney(account, amount)
|
||||
end
|
||||
@@ -18,6 +18,7 @@ function OxToQBMenu(id, menu)
|
||||
header = v.title,
|
||||
txt = v.description,
|
||||
icon = v.icon,
|
||||
disabled = v.disabled,
|
||||
}
|
||||
|
||||
if v.onSelect then
|
||||
|
||||
@@ -2,7 +2,7 @@ Notify = Notify or {}
|
||||
local notifyType = BridgeClientConfig.NotifySystem
|
||||
local helptextType = BridgeClientConfig.ShowHelpText
|
||||
|
||||
---comment
|
||||
---This will send a notify message of the type and time passed
|
||||
---@param message string
|
||||
---@param _type string
|
||||
---@param time number
|
||||
@@ -34,7 +34,7 @@ Notify.SendNotify = function(message, _type, time)
|
||||
end
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will show a help text message at the screen position passed
|
||||
---@param message string
|
||||
---@param _position string
|
||||
---@return nil
|
||||
@@ -61,6 +61,8 @@ Notify.ShowHelpText = function(message, _position)
|
||||
end
|
||||
end
|
||||
|
||||
---This will hide the help text message on the screen
|
||||
---@return nil
|
||||
Notify.HideHelpText = function()
|
||||
if helptextType == 'ox' then
|
||||
return exports.ox_lib:hideTextUI()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Notify = Notify or {}
|
||||
|
||||
---comment
|
||||
---This will send a notification to the specified player of the passed message and type
|
||||
---@param src number
|
||||
---@param message string
|
||||
---@param _type string
|
||||
@@ -9,7 +9,7 @@ Notify.SendNotify = function(src, message, _type, time)
|
||||
TriggerClientEvent('community_bridge:Client:Notify', src, message, _type, time)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will show a help text message to the specified player at the screen position passed
|
||||
---@param src number
|
||||
---@param message string
|
||||
---@param position string
|
||||
@@ -17,6 +17,8 @@ Notify.ShowHelpText = function(src, message, position)
|
||||
TriggerClientEvent('community_bridge:Client:ShowHelpText', src, message, position)
|
||||
end
|
||||
|
||||
---This will hide the help text message on the screen for the specified player
|
||||
---@param src number
|
||||
Notify.HideHelpText = function(src)
|
||||
TriggerClientEvent('community_bridge:Client:HideHelpText', src)
|
||||
end
|
||||
@@ -7,30 +7,7 @@ RegisterNetEvent('community_bridge:openShop', function(_type, _title, shopData)
|
||||
Shops.OpenShop(_title, shopData.inventory)
|
||||
end)
|
||||
|
||||
Shops.FinalizeCheckOut = function(shopName, item, itemLabel, price)
|
||||
if not shopName and not item and not itemLabel and not price then return end
|
||||
local generatedID = Ids.CreateUniqueId()
|
||||
local buildMenu = {
|
||||
{
|
||||
title = locale('Shops.PayByCash')..tostring(price),
|
||||
description = locale('Shops.AreYouSure') .. itemLabel,
|
||||
icon = "fa-solid fa-money-bill-wave",
|
||||
onSelect = function(_, __, ___)
|
||||
TriggerServerEvent('community_bridge:completeCheckout', shopName, item, "cash")
|
||||
end
|
||||
},
|
||||
{
|
||||
title = locale('Shops.PayByCard')..tostring(price),
|
||||
description = locale('Shops.AreYouSure') .. itemLabel,
|
||||
icon = "fa-solid fa-building-column",
|
||||
onSelect = function(_, __, ___)
|
||||
TriggerServerEvent('community_bridge:completeCheckout', shopName, item, "bank")
|
||||
end
|
||||
}
|
||||
}
|
||||
Bridge.Menu.Open({ id = generatedID, title = locale("Shops.Confirm"), options = buildMenu }, false)
|
||||
end
|
||||
|
||||
---This is an internal event that is used to complete a transaction and offer cash/card pay
|
||||
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)
|
||||
@@ -56,6 +33,11 @@ Shops.FinalizeCheckOut = function(shopName, item, itemLabel, price, amount)
|
||||
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
|
||||
---@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
|
||||
local numberOptions = {}
|
||||
@@ -71,6 +53,11 @@ 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 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
|
||||
---@return nil
|
||||
Shops.OpenShop = function(title, shopData)
|
||||
if not title and not shopData and not title then return print("No Title Passed") end
|
||||
local generatedID = Ids.CreateUniqueId()
|
||||
|
||||
@@ -2,20 +2,37 @@ Shops = Shops or {}
|
||||
|
||||
local registeredShops = {}
|
||||
|
||||
---commentThis can open a shop for the client
|
||||
---@param src number
|
||||
---@param shopTitle 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])
|
||||
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 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 end
|
||||
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}
|
||||
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.
|
||||
---@param src number
|
||||
---@param shopName string
|
||||
---@param item string
|
||||
---@param amount number
|
||||
---@param paymentType 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
|
||||
local shopData = registeredShops[shopName]
|
||||
|
||||
@@ -4,6 +4,20 @@ local function warnUser()
|
||||
print("Currently Only Targeting Is Supported By Community Bridge, You Are Using A Resource That Requires The Target Module To Be Used.")
|
||||
end
|
||||
|
||||
Target.FixOptions = function(options)
|
||||
for k, v in pairs(options) do
|
||||
local action = v.onSelect or v.action
|
||||
local select = function(entityOrData)
|
||||
if type(entityOrData) == 'table' then
|
||||
return action(entityOrData.entity)
|
||||
end
|
||||
return action(entityOrData)
|
||||
end
|
||||
options[k].onSelect = select
|
||||
end
|
||||
return options
|
||||
end
|
||||
|
||||
Target.AddGlobalPlayer = function(options)
|
||||
warnUser()
|
||||
end
|
||||
@@ -17,15 +31,94 @@ Target.RemoveGlobalVehicle = function(options)
|
||||
end
|
||||
|
||||
Target.AddLocalEntity = function(entities, _options)
|
||||
warnUser()
|
||||
local fixedOptions = Target.FixOptions(_options)
|
||||
if type(entities) == "string" or type(entities) == "number" then
|
||||
entities = { entities }
|
||||
end
|
||||
for _, entity in pairs(entities) do
|
||||
local id = Ids.RandomString()
|
||||
local menuData = { id = id, title = "Options", 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 = {},
|
||||
onSelect = function(selected, secondary, args)
|
||||
if v.onSelect then
|
||||
v.onSelect(selected, secondary, args)
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
Point.Register(id, entity, 5, args,
|
||||
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)
|
||||
end
|
||||
else
|
||||
sleep = 3000
|
||||
end
|
||||
end
|
||||
end,
|
||||
function()
|
||||
Point.Remove(id)
|
||||
end, function()
|
||||
--No need for this in this one
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Target.AddModel = function(models, options)
|
||||
warnUser()
|
||||
end
|
||||
|
||||
Target.AddBoxZone = function(name, coords, size, heading, options)
|
||||
warnUser()
|
||||
local fixedOptions = Target.FixOptions(_options)
|
||||
local id = Ids.RandomString()
|
||||
local menuData = { id = id, title = "Options", options = {} }
|
||||
for k, v in pairs(fixedOptions) do
|
||||
table.insert(menuData.options, {
|
||||
title = ("Option " .. k),
|
||||
description = "No Description",
|
||||
onSelect = function(selected, secondary, args)
|
||||
if v.onSelect then
|
||||
v.onSelect(selected, secondary, args)
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
Point.Register(id, coords, 5, args,
|
||||
function()
|
||||
local sleep = 3000
|
||||
while true 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)
|
||||
end
|
||||
else
|
||||
sleep = 3000
|
||||
end
|
||||
end
|
||||
end,
|
||||
function()
|
||||
Point.Remove(id)
|
||||
end, function()
|
||||
--No need for this in this one
|
||||
end)
|
||||
end
|
||||
|
||||
Target.RemoveGlobalPlayer = function()
|
||||
|
||||
@@ -17,6 +17,9 @@ local targetZones = {}
|
||||
|
||||
Target = Target or {}
|
||||
|
||||
---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
|
||||
local action = v.onSelect or v.action
|
||||
@@ -31,25 +34,34 @@ Target.FixOptions = function(options)
|
||||
return options
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will add target options to players.
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddGlobalPlayer = function(options)
|
||||
options = Target.FixOptions(options)
|
||||
ox_target:addGlobalPlayer(options)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will remove target options from all players.
|
||||
Target.RemoveGlobalPlayer = function()
|
||||
---@diagnostic disable-next-line: missing-parameter
|
||||
ox_target:removeGlobalPlayer()
|
||||
end
|
||||
|
||||
---This will toggle the targeting system on or off. This is useful for when you want to disable the targeting system for a specific player entirely.
|
||||
---@param bool boolean
|
||||
Target.DisableTargeting = function(bool)
|
||||
ox_target:disableTargeting(bool)
|
||||
end
|
||||
|
||||
---This will add taget options to all vehicles.
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddGlobalVehicle = function(options)
|
||||
options = Target.FixOptions(options)
|
||||
ox_target:addGlobalVehicle(options)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will remove target options from all vehicles.
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.RemoveGlobalVehicle = function(options)
|
||||
local assembledLables = {}
|
||||
for k, v in pairs(options) do
|
||||
@@ -58,31 +70,40 @@ Target.RemoveGlobalVehicle = function(options)
|
||||
ox_target:removeGlobalVehicle(assembledLables)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param entities table
|
||||
---This will generate targets on non networked entites with the passed options.
|
||||
---@param entities number | table
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddLocalEntity = function(entities, options)
|
||||
options = Target.FixOptions(options)
|
||||
ox_target:addLocalEntity(entities, options)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param models table
|
||||
---This will remove the target options from a local entity. This is useful for when you want to remove target options from a specific entity.
|
||||
---@param entity any
|
||||
Target.RemoveLocalEntity = function(entity)
|
||||
ox_target:removeLocalEntity(entity)
|
||||
end
|
||||
|
||||
---This will add target options to all specified models. This is useful for when you want to add target options to all models of a specific type.
|
||||
---@param models number | table
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddModel = function(models, options)
|
||||
options = Target.FixOptions(options)
|
||||
ox_target:addModel(models, options)
|
||||
end
|
||||
|
||||
---comment
|
||||
---This will remove target options from all specified models.
|
||||
---@param model number
|
||||
Target.RemoveModel = function(model)
|
||||
ox_target:removeModel(model)
|
||||
end
|
||||
|
||||
---This will add a box zone to the target system. This is useful for when you want to add target options to a specific area.
|
||||
---@param name string
|
||||
---@param coords table
|
||||
---@param size table
|
||||
---@param heading number
|
||||
---@param options table
|
||||
---@return number
|
||||
Target.AddBoxZone = function(name, coords, size, heading, options)
|
||||
options = Target.FixOptions(options)
|
||||
local target = ox_target:addBoxZone({
|
||||
@@ -96,28 +117,28 @@ Target.AddBoxZone = function(name, coords, size, heading, options)
|
||||
return target
|
||||
end
|
||||
|
||||
Target.RemoveGlobalPlayer = function()
|
||||
ox_target:removeGlobalPlayer()
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param entity number
|
||||
---@return nil
|
||||
Target.RemoveLocalEntity = function(entity)
|
||||
ox_target:removeLocalEntity(entity)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param model string
|
||||
---@return nil
|
||||
Target.RemoveModel = function(model)
|
||||
ox_target:removeModel(model)
|
||||
end
|
||||
|
||||
---comment
|
||||
---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.
|
||||
---@param name string
|
||||
---@param coords table
|
||||
---@param radius number
|
||||
---@param options table
|
||||
Target.AddSphereZone = function(name, coords, radius, heading, options)
|
||||
options = Target.FixOptions(options)
|
||||
local target = ox_target:addSphereZone({
|
||||
coords = coords,
|
||||
radius = radius,
|
||||
name = name,
|
||||
debug = targetDebug,
|
||||
options = options
|
||||
})
|
||||
table.insert(targetZones, { name = name, id = target, creator = GetInvokingResource() })
|
||||
return target
|
||||
end
|
||||
|
||||
---This will remove target options from a specific zone.
|
||||
---@param name string
|
||||
---@return nil
|
||||
Target.RemoveZone = function(name)
|
||||
if not name then return end
|
||||
for _, data in pairs(targetZones) do
|
||||
if data.name == name then
|
||||
ox_target:removeZone(data.id)
|
||||
@@ -128,12 +149,11 @@ Target.RemoveZone = function(name)
|
||||
end
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
if resource == GetCurrentResourceName() then
|
||||
for _, target in pairs(targetZones) do
|
||||
if target.creator == resource then
|
||||
ox_target:removeZone(target.id)
|
||||
end
|
||||
if resource ~= GetCurrentResourceName() then return end
|
||||
for _, target in pairs(targetZones) do
|
||||
if target.creator == resource then
|
||||
ox_target:removeZone(target.id)
|
||||
end
|
||||
targetZones = {}
|
||||
end
|
||||
targetZones = {}
|
||||
end)
|
||||
@@ -15,7 +15,12 @@ detectDebugEnabled()
|
||||
local targetZones = {}
|
||||
|
||||
Target = Target or {}
|
||||
local qb_target = exports['qb-target']
|
||||
|
||||
|
||||
---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
|
||||
local action = v.onSelect or v.action
|
||||
@@ -23,7 +28,7 @@ Target.FixOptions = function(options)
|
||||
if type(entityOrData) == 'table' then
|
||||
return action(entityOrData.entity)
|
||||
end
|
||||
return action(entityOrData)
|
||||
return action(entityOrData)
|
||||
end
|
||||
options[k].action = select
|
||||
options[k].job = v.job or v.groups
|
||||
@@ -31,50 +36,90 @@ Target.FixOptions = function(options)
|
||||
return options
|
||||
end
|
||||
|
||||
---This will toggle the targeting system on or off. This is useful for when you want to disable the targeting system for a specific player entirely.
|
||||
---@param bool boolean
|
||||
Target.DisableTargeting = function(bool)
|
||||
qb_target:AllowTargeting(not bool)
|
||||
end
|
||||
|
||||
---This will add target options to players.
|
||||
---@param options table
|
||||
Target.AddGlobalPlayer = function(options)
|
||||
options = Target.FixOptions(options)
|
||||
exports['qb-target']:AddGlobalPlayer({
|
||||
qb_target:AddGlobalPlayer({
|
||||
options = options,
|
||||
distance = options.distance or 1.5
|
||||
})
|
||||
end
|
||||
|
||||
---This will remove target options from all players.
|
||||
Target.RemoveGlobalPlayer = function()
|
||||
qb_target:RemoveGlobalPlayer()
|
||||
end
|
||||
|
||||
---This will add taget options to all vehicles.
|
||||
---@param options table
|
||||
Target.AddGlobalVehicle = function(options)
|
||||
options = Target.FixOptions(options)
|
||||
exports['qb-target']:AddGlobalVehicle({
|
||||
qb_target:AddGlobalVehicle({
|
||||
options = options,
|
||||
distance = options.distance or 1.5
|
||||
})
|
||||
end
|
||||
|
||||
---This will remove target options from all vehicles.
|
||||
---@param options table
|
||||
Target.RemoveGlobalVehicle = function(options)
|
||||
local assembledLables = {}
|
||||
for k, v in pairs(options) do
|
||||
table.insert(assembledLables, v.label)
|
||||
end
|
||||
exports['qb-target']:RemoveGlobalVehicle(assembledLables)
|
||||
qb_target:RemoveGlobalVehicle(assembledLables)
|
||||
end
|
||||
|
||||
---This will generate targets on non networked entites with the passed options.
|
||||
---@param entities number | table
|
||||
---@param options table
|
||||
Target.AddLocalEntity = function(entities, options)
|
||||
options = Target.FixOptions(options)
|
||||
exports['qb-target']:AddTargetEntity(entities, {
|
||||
qb_target:AddTargetEntity(entities, {
|
||||
options = options,
|
||||
distance = options.distance or 1.5
|
||||
})
|
||||
end
|
||||
|
||||
---This will remove the target options from a local entity. This is useful for when you want to remove target options from a specific entity.
|
||||
---@param entity any
|
||||
Target.RemoveLocalEntity = function(entity)
|
||||
qb_target:RemoveTargetEntity(entity)
|
||||
end
|
||||
|
||||
---This will add target options to all specified models. This is useful for when you want to add target options to all models of a specific type.
|
||||
---@param models number | table
|
||||
---@param options table
|
||||
Target.AddModel = function(models, options)
|
||||
options = Target.FixOptions(options)
|
||||
exports['qb-target']:AddTargetModel(models, {
|
||||
qb_target:AddTargetModel(models, {
|
||||
options = options,
|
||||
distance = options.distance or 1.5,
|
||||
})
|
||||
end
|
||||
|
||||
---This will remove target options from all specified models.
|
||||
---@param model number
|
||||
Target.RemoveModel = function(model)
|
||||
qb_target:RemoveTargetModel(model)
|
||||
end
|
||||
|
||||
---This will add a box zone to the target system. This is useful for when you want to add target options to a specific area.
|
||||
---@param name string
|
||||
---@param coords table
|
||||
---@param size table
|
||||
---@param heading number
|
||||
---@param options table
|
||||
Target.AddBoxZone = function(name, coords, size, heading, options)
|
||||
options = Target.FixOptions(options)
|
||||
exports['qb-target']:AddBoxZone(name, coords, size.x, size.y, {
|
||||
qb_target:AddBoxZone(name, coords, size.x, size.y, {
|
||||
name = name,
|
||||
debugPoly = targetDebug,
|
||||
heading = heading,
|
||||
@@ -87,22 +132,30 @@ Target.AddBoxZone = function(name, coords, size, heading, options)
|
||||
table.insert(targetZones, { name = name, creator = GetInvokingResource() })
|
||||
end
|
||||
|
||||
Target.RemoveGlobalPlayer = function()
|
||||
exports['qb-target']:RemoveGlobalPlayer()
|
||||
end
|
||||
|
||||
Target.RemoveLocalEntity = function(entity)
|
||||
exports['qb-target']:RemoveTargetEntity(entity)
|
||||
end
|
||||
|
||||
Target.RemoveModel = function(model)
|
||||
exports['qb-target']:RemoveTargetModel(model)
|
||||
---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.
|
||||
---@param name string
|
||||
---@param coords table
|
||||
---@param radius number
|
||||
---@param options table
|
||||
Target.AddSphereZone = function(name, coords, radius, options)
|
||||
options = Target.FixOptions(options)
|
||||
qb_target:AddCircleZone(name, coords, radius, {
|
||||
name = name,
|
||||
debugPoly = targetDebug,
|
||||
}, {
|
||||
options = options,
|
||||
distance = options.distance or 1.5,
|
||||
})
|
||||
table.insert(targetZones, { name = name, creator = GetInvokingResource() })
|
||||
end
|
||||
|
||||
---This will remove target options from a specific zone.
|
||||
---@param name string
|
||||
Target.RemoveZone = function(name)
|
||||
if not name then return end
|
||||
for _, data in pairs(targetZones) do
|
||||
if data.name == name then
|
||||
exports['qb-target']:RemoveZone(name)
|
||||
qb_target:RemoveZone(name)
|
||||
table.remove(targetZones, _)
|
||||
break
|
||||
end
|
||||
@@ -110,12 +163,11 @@ Target.RemoveZone = function(name)
|
||||
end
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
if resource == GetCurrentResourceName() then
|
||||
for _, target in pairs(targetZones) do
|
||||
if target.creator == resource then
|
||||
exports['qb-target']:RemoveZone(target.name)
|
||||
end
|
||||
if resource ~= GetCurrentResourceName() then return end
|
||||
for _, target in pairs(targetZones) do
|
||||
if target.creator == resource then
|
||||
qb_target:RemoveZone(target.name)
|
||||
end
|
||||
targetZones = {}
|
||||
end
|
||||
targetZones = {}
|
||||
end)
|
||||
@@ -2,10 +2,18 @@ local resourceName = "sleepless_interact"
|
||||
local configValue = BridgeClientConfig.TargetSystem
|
||||
if (configValue == "auto" and GetResourceState(resourceName) ~= "started") or (configValue ~= "auto" and configValue ~= resourceName) then return end
|
||||
|
||||
--if GetResourceState('sleepless_interact') ~= 'started' then return end
|
||||
-- This is only partially supported
|
||||
|
||||
local sleepless = exports.sleepless_interact
|
||||
local targetDebug = false
|
||||
local function detectDebugEnabled()
|
||||
if BridgeClientConfig.DebugLevel == 2 then
|
||||
targetDebug = true
|
||||
end
|
||||
end
|
||||
|
||||
detectDebugEnabled()
|
||||
|
||||
local sleepless_interact = exports.sleepless_interact
|
||||
local targetZones = {}
|
||||
|
||||
Target = Target or {}
|
||||
|
||||
@@ -23,18 +31,111 @@ Target.FixOptions = function(options)
|
||||
return options
|
||||
end
|
||||
|
||||
Target.AddLocalEntity = function(entity, _options)
|
||||
local options = Target.FixOptions(_options)
|
||||
sleepless:addLocalEntity({
|
||||
id = entity,
|
||||
entity = entity,
|
||||
options = options,
|
||||
renderDistance = 10.0,
|
||||
activeDistance = 2.0,
|
||||
cooldown = 1500
|
||||
})
|
||||
---comment
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddGlobalPlayer = function(options)
|
||||
options = Target.FixOptions(options)
|
||||
sleepless_interact:addGlobalPlayer(options)
|
||||
end
|
||||
|
||||
Target.DisableTargeting = function(bool)
|
||||
--sleepless_interact:disableTargeting(bool)
|
||||
sleepless_interact:disableInteract(bool)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddGlobalVehicle = function(options)
|
||||
options = Target.FixOptions(options)
|
||||
sleepless_interact:addGlobalVehicle(options)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.RemoveGlobalVehicle = function(options)
|
||||
local assembledLables = {}
|
||||
for k, v in pairs(options) do
|
||||
table.insert(assembledLables, v.name)
|
||||
end
|
||||
sleepless_interact:removeGlobalVehicle(assembledLables)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param entities table
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddLocalEntity = function(entities, options)
|
||||
options = Target.FixOptions(options)
|
||||
sleepless_interact:addLocalEntity(entities, options)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param models table
|
||||
---@param options table
|
||||
---@return nil
|
||||
Target.AddModel = function(models, options)
|
||||
options = Target.FixOptions(options)
|
||||
sleepless_interact:addModel(models, options)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param name string
|
||||
---@param coords table
|
||||
---@param size table
|
||||
---@param heading number
|
||||
---@param options table
|
||||
---@return number
|
||||
Target.AddBoxZone = function(name, coords, size, heading, options)
|
||||
options = Target.FixOptions(options)
|
||||
local target = sleepless_interact:addCoords({
|
||||
coords = coords,
|
||||
options = options,
|
||||
})
|
||||
table.insert(targetZones, { name = name, id = target, creator = GetInvokingResource() })
|
||||
return target
|
||||
end
|
||||
|
||||
Target.RemoveGlobalPlayer = function()
|
||||
sleepless_interact:removeGlobalPlayer()
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param entity number
|
||||
---@return nil
|
||||
Target.RemoveLocalEntity = function(entity)
|
||||
sleepless:removeLocalEntity(entity)
|
||||
end
|
||||
sleepless_interact:removeLocalEntity(entity)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param model string
|
||||
---@return nil
|
||||
Target.RemoveModel = function(model)
|
||||
sleepless_interact:removeModel(model)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param name string
|
||||
---@return nil
|
||||
Target.RemoveZone = function(name)
|
||||
for _, data in pairs(targetZones) do
|
||||
if data.name == name then
|
||||
sleepless_interact:removeCoords(data.id)
|
||||
table.remove(targetZones, _)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
if resource == GetCurrentResourceName() then
|
||||
for _, target in pairs(targetZones) do
|
||||
if target.creator == resource then
|
||||
sleepless_interact:removeZone(target.id)
|
||||
end
|
||||
end
|
||||
targetZones = {}
|
||||
end
|
||||
end)
|
||||
@@ -1,9 +1,16 @@
|
||||
VehicleKey = VehicleKey or {}
|
||||
|
||||
---This will give keys to the specifed vehicle/plate.
|
||||
---@param vehicle number The vehicle entity ID.
|
||||
---@param plate string The plate of the vehicle.
|
||||
VehicleKey.GiveKeys = function(vehicle, plate)
|
||||
return true, print("There Is No Vehicle Key System Installed")
|
||||
end
|
||||
|
||||
---This will remove keys from the specifed vehicle/plate.
|
||||
---@param vehicle number The vehicle entity ID.
|
||||
---@param plate string The plate of the vehicle.
|
||||
---@return boolean | nil
|
||||
VehicleKey.RemoveKeys = function(vehicle, plate)
|
||||
return true, print("There Is No Vehicle Key System Installed")
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
Weather = Weather or {}
|
||||
|
||||
---This will toggle the players weather/time sync
|
||||
---@param toggle boolean
|
||||
---@return nil
|
||||
Weather.ToggleSync = function(toggle)
|
||||
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
if GetResourceState('cd_easytime') ~= 'started' then return end
|
||||
Weather = Weather or {}
|
||||
|
||||
---comment
|
||||
---@param toggle boolean
|
||||
Weather.ToggleSync = function(toggle)
|
||||
TriggerEvent('cd_easytime:PauseSync', toggle)
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
if GetResourceState('qb-weathersync') ~= 'started' then return end
|
||||
Weather = {}
|
||||
Weather = Weather or {}
|
||||
|
||||
---comment
|
||||
---@param toggle boolean
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
if GetResourceState('Renewed-Weathersync') ~= 'started' then return end
|
||||
Weather = {}
|
||||
Weather = Weather or {}
|
||||
|
||||
---comment
|
||||
---@param toggle boolean
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
if GetResourceState('qb-weathersync') ~= 'started' then return end
|
||||
Weather = {}
|
||||
|
||||
---comment
|
||||
---@param toggle boolean
|
||||
Weather.ToggleSync = function(toggle)
|
||||
if toggle then
|
||||
TriggerEvent("qb-weathersync:client:EnableSync")
|
||||
else
|
||||
TriggerEvent("qb-weathersync:client:DisableSync")
|
||||
end
|
||||
end
|
||||
@@ -6,20 +6,19 @@
|
||||
-- ▄█▀ █▄▄ █▀▄ ▀▄▀ █▄▄ █▀▄
|
||||
-- -- -- -- -- -- -- -- -- --
|
||||
if not IsDuplicityVersion() then goto client end
|
||||
exports.community_bridge:RegisterCallback('ClientToServerToClient', function(src, cb, ftpcsftug)
|
||||
cb(ftpcsftug, 'some random string')
|
||||
|
||||
exports.community_bridge:RegisterCallback('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('cb_server_test', function(source)
|
||||
local someData = exports.community_bridge:TriggerCallback('ServerToClientToServer', source, function(ftpcsftug, derpa)
|
||||
print(ftpcsftug, derpa)
|
||||
return "This data gets passed up the chain"
|
||||
end,"herpaderpa")
|
||||
print("print", someData)
|
||||
RegisterCommand('callback_test2', function(source)
|
||||
local someData, other = exports.community_bridge:TriggerCallback('callback_test2_name_here', source, "herpaderpa")
|
||||
print("Data From Client: ", someData, other)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
-- -- -- -- -- -- -- -- -- --
|
||||
-- ▄▀▀ █ █ ██▀ █▄ █ ▀█▀
|
||||
-- ▀▄▄ █▄▄ █ █▄▄ █ ▀█ █
|
||||
@@ -27,18 +26,15 @@ end)
|
||||
if IsDuplicityVersion() then return end
|
||||
::client::
|
||||
|
||||
|
||||
RegisterCommand('cb_client_test', function()
|
||||
local someData = exports.community_bridge:TriggerCallback('ClientToServerToClient', function(ftpcsftug, derpa)
|
||||
print(ftpcsftug, derpa, "This will fire on the player who triggered the event")
|
||||
end,"herpaderpa")
|
||||
print(someData)
|
||||
RegisterCommand('callback_test1', function()
|
||||
local somerandomstring, someotherrandomstring = exports.community_bridge:TriggerCallback('callback_test1_name_here', "herpaderpa")
|
||||
print("Data From Server: ", somerandomstring, someotherrandomstring)
|
||||
end)
|
||||
|
||||
exports.community_bridge:RegisterRebound('ClientToServerToClient', function(src, cb, ftpcsftug)
|
||||
print("this is a rebound from another player or himself")
|
||||
end)
|
||||
-- exports.community_bridge:RegisterRebound('callback_test1', function(src, cb, ftpcsftug)
|
||||
-- print("this is a rebound to all players")
|
||||
-- end)
|
||||
|
||||
exports.community_bridge:RegisterCallback('ServerToClientToServer', function(cb, ftpcsftug)
|
||||
cb(ftpcsftug, 'TestyMcTesterton')
|
||||
exports.community_bridge:RegisterCallback('callback_test2_name_here', function(ftpcsftug)
|
||||
return ftpcsftug, 'TestyMcTesterton'
|
||||
end)
|
||||
@@ -0,0 +1,19 @@
|
||||
-- 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("locale-unit-test"))
|
||||
|
||||
-- Example outside community bridge resource:
|
||||
|
||||
-- local Language = Require('modules/locales/shared.lua')
|
||||
-- print("Language: ", Lang)
|
||||
-- print("Locale: ", Language.Locale("locale-unit-test"))
|
||||
RegisterCommand("lang", function(source, args, raw)
|
||||
print(Language.Locale("UNITTEST.UNITTEST.UNITTESTA"))
|
||||
print(Language.Locale("UNITTEST.UNITTESTA", "Devil", "GERRRRRRR!"))
|
||||
|
||||
print( "Oh also this works", Language.Locale("place_object_scroll_down"))
|
||||
end, false)
|
||||
Reference in new issue
Block a user