1
0
Fork 0
forked from Simnation/Main
Main/resources/[standalone]/utility_lib/server/functions/utilityNet.lua

252 lines
7.5 KiB
Lua
Raw Normal View History

2025-06-07 08:51:21 +02:00
local NextId = 1
2025-08-12 16:56:50 +02:00
local Entities = {}
2025-06-07 08:51:21 +02:00
UtilityNet = UtilityNet or {}
-- options = {
-- resource = string (used internally)
-- replace = boolean (replace an already existing object, without creating a new one)
-- searchDistance = number (default 5.0, replace search distance)
-- door = boolean (if true will spawn the entity with door flag)
-- }
UtilityNet.CreateEntity = function(model, coords, options, callId)
2025-08-12 16:56:50 +02:00
options = options or {}
local hashmodel = nil
2025-06-07 08:51:21 +02:00
--#region Checks
if not model or (type(model) ~= "string" and type(model) ~= "number") then
error("Invalid model, got "..type(model).." expected string or number", 0)
else
if type(model) == "string" then
2025-08-12 16:56:50 +02:00
hashmodel = GetHashKey(model)
else
hashmodel = model
2025-06-07 08:51:21 +02:00
end
end
if not coords or type(coords) ~= "vector3" then
error("Invalid coords, got "..type(coords).." expected vector3", 0)
end
--#endregion
--#region Event
2025-08-12 16:56:50 +02:00
TriggerEvent("Utility:Net:EntityCreating", hashmodel, coords, options)
2025-06-07 08:51:21 +02:00
-- EntityCreating event can be canceled, in that case we dont create the entity
if WasEventCanceled() then
return -1
end
--#endregion
local slice = GetSliceFromCoords(coords)
local object = {
id = NextId,
2025-08-12 16:56:50 +02:00
model = options.abstract and model or hashmodel,
2025-06-07 08:51:21 +02:00
coords = coords,
slice = slice,
options = options,
2025-08-12 16:56:50 +02:00
createdBy = options.createdBy or GetInvokingResource(),
2025-06-07 08:51:21 +02:00
}
2025-08-12 16:56:50 +02:00
if not Entities[slice] then
Entities[slice] = {}
2025-06-07 08:51:21 +02:00
end
2025-08-12 16:56:50 +02:00
Entities[slice][object.id] = object
2025-06-07 08:51:21 +02:00
RegisterEntityState(object.id)
NextId = NextId + 1
2025-08-12 16:56:50 +02:00
TriggerLatentClientEvent("Utility:Net:EntityCreated", -1, 5120, callId, object)
2025-06-07 08:51:21 +02:00
return object.id
end
UtilityNet.DeleteEntity = function(uNetId)
--#region Checks
if type(uNetId) ~= "number" then
error("Invalid uNetId, got "..type(uNetId).." expected number", 2)
return
end
-- Invalid Id
if uNetId == -1 then
error("Invalid uNetId, got -1", 2)
return
end
--#endregion
--#region Event
TriggerEvent("Utility:Net:EntityDeleting", uNetId)
-- EntityDeleting event can be canceled, in that case we dont create the entity
if WasEventCanceled() then
return
end
--#endregion
local entity = UtilityNet.InternalFindFromNetId(uNetId)
if entity then
2025-08-12 16:56:50 +02:00
Entities[entity.slice][entity.id] = nil
2025-06-07 08:51:21 +02:00
end
2025-08-12 16:56:50 +02:00
TriggerLatentClientEvent("Utility:Net:RequestDeletion", -1, 5120, uNetId)
2025-06-07 08:51:21 +02:00
ClearEntityStates(uNetId) -- Clear states after trigger
end
2025-08-12 16:56:50 +02:00
UtilityNet.InternalFindFromNetId = function(uNetId)
for sliceI, slice in pairs(Entities) do
if slice[uNetId] then
return slice[uNetId], sliceI
2025-06-07 08:51:21 +02:00
end
2025-08-12 16:56:50 +02:00
end
2025-06-07 08:51:21 +02:00
end
2025-08-12 16:56:50 +02:00
UtilityNet.GetEntities = function(slice)
if slice then
return Entities[slice]
2025-06-07 08:51:21 +02:00
else
2025-08-12 16:56:50 +02:00
return Entities
2025-06-07 08:51:21 +02:00
end
end
UtilityNet.SetModelRenderDistance = function(model, distance)
if type(model) == "string" then
model = GetHashKey(model)
end
local _ = GlobalState.ModelsRenderDistance
_[model] = distance
GlobalState.ModelsRenderDistance = _
end
2025-08-12 16:56:50 +02:00
UtilityNet.SetEntityRotation = function(uNetId, newRotation, skipRotationUpdate)
2025-06-07 08:51:21 +02:00
local source = source
if type(newRotation) ~= "vector3" then
error("Invalid rotation, got "..type(newRotation).." expected vector3", 2)
end
2025-08-12 16:56:50 +02:00
if newRotation.x ~= newRotation.x or newRotation.y ~= newRotation.y or newRotation.z ~= newRotation.z then
error("Invalid rotation, got "..type(newRotation).." (with NaN) expected vector3", 2)
end
local entity, slice = UtilityNet.InternalFindFromNetId(uNetId)
Entities[slice][uNetId].options.rotation = newRotation
2025-06-07 08:51:21 +02:00
-- Except caller since it will be already updated
2025-08-12 16:56:50 +02:00
TriggerLatentClientEvent("Utility:Net:RefreshRotation", -1, 5120, uNetId, newRotation, skipRotationUpdate)
2025-06-07 08:51:21 +02:00
end
2025-08-12 16:56:50 +02:00
UtilityNet.SetEntityCoords = function(uNetId, newCoords, skipPositionUpdate)
2025-06-07 08:51:21 +02:00
local source = source
if type(newCoords) ~= "vector3" then
error("Invalid coords, got "..type(newCoords).." expected vector3", 2)
end
2025-08-12 16:56:50 +02:00
if newCoords.x ~= newCoords.x or newCoords.y ~= newCoords.y or newCoords.z ~= newCoords.z then
error("Invalid coords, got "..type(newCoords).." (with NaN) expected vector3", 2)
end
local entity, slice = UtilityNet.InternalFindFromNetId(uNetId)
local newSlice = GetSliceFromCoords(newCoords)
if newSlice ~= slice then
local old = Entities[slice][uNetId]
if not Entities[newSlice] then
Entities[newSlice] = {}
end
Entities[slice][uNetId] = nil
Entities[newSlice][uNetId] = old
slice = newSlice
end
Entities[slice][uNetId].coords = newCoords
Entities[slice][uNetId].slice = GetSliceFromCoords(newCoords)
2025-06-07 08:51:21 +02:00
-- Except caller since it will be already updated
2025-08-12 16:56:50 +02:00
TriggerLatentClientEvent("Utility:Net:RefreshCoords", -1, 5120, uNetId, newCoords, skipPositionUpdate)
2025-06-07 08:51:21 +02:00
end
UtilityNet.SetEntityModel = function(uNetId, model)
local source = source
if type(model) ~= "number" and type(model) ~= "string" then
error("Invalid model, got "..type(model).." expected string or number", 2)
end
if type(model) == "string" then
model = GetHashKey(model)
end
2025-08-12 16:56:50 +02:00
local entity, slice = UtilityNet.InternalFindFromNetId(uNetId)
Entities[slice][uNetId].model = model
2025-06-07 08:51:21 +02:00
-- Except caller since it will be already updated
2025-08-12 16:56:50 +02:00
TriggerLatentClientEvent("Utility:Net:RefreshModel", -1, 5120, uNetId, model)
2025-06-07 08:51:21 +02:00
end
--#region Events
UtilityNet.RegisterEvents = function()
RegisterNetEvent("Utility:Net:CreateEntity", function(callId, model, coords, options)
UtilityNet.CreateEntity(model, coords, options, callId)
end)
RegisterNetEvent("Utility:Net:DeleteEntity", function(uNetId)
UtilityNet.DeleteEntity(uNetId)
end)
2025-08-12 16:56:50 +02:00
2025-06-07 08:51:21 +02:00
RegisterNetEvent("Utility:Net:SetModelRenderDistance", function(model, distance)
UtilityNet.SetModelRenderDistance(model, distance)
end)
RegisterNetEvent("Utility:Net:AttachToEntity", function(uNetId, object, params)
local state = UtilityNet.State(uNetId)
state.__attached = {
object = object,
params = params
}
end)
RegisterNetEvent("Utility:Net:DetachEntity", function(uNetId, newCoords)
local state = UtilityNet.State(uNetId)
if state.__attached then
-- Update entity coords
if newCoords then
UtilityNet.SetEntityCoords(uNetId, newCoords)
end
state.__attached = nil
end
end)
RegisterNetEvent("Utility:Net:SetEntityCoords", UtilityNet.SetEntityCoords)
RegisterNetEvent("Utility:Net:SetEntityModel", UtilityNet.SetEntityModel)
RegisterNetEvent("Utility:Net:SetEntityRotation", UtilityNet.SetEntityRotation)
2025-08-12 16:56:50 +02:00
RegisterNetEvent("Utility:Net:GetEntities", function()
TriggerClientEvent("Utility:Net:GetEntities", source, UtilityNet.GetEntities())
2025-06-07 08:51:21 +02:00
end)
end
--#endregion
-- Exports for server native.lua
exports("CreateEntity", UtilityNet.CreateEntity)
exports("DeleteEntity", UtilityNet.DeleteEntity)
exports("SetModelRenderDistance", UtilityNet.SetModelRenderDistance)
2025-08-12 16:56:50 +02:00
exports("GetEntities", UtilityNet.GetEntities)
exports("InternalFindFromNetId", UtilityNet.InternalFindFromNetId)
2025-06-07 08:51:21 +02:00
exports("SetEntityModel", UtilityNet.SetEntityModel)
exports("SetEntityCoords", UtilityNet.SetEntityCoords)
exports("SetEntityRotation", UtilityNet.SetEntityRotation)