From 9135e65009a0b4a2ebcbaf3ea643a3db7bc48322 Mon Sep 17 00:00:00 2001 From: Linden <65407488+thelindat@users.noreply.github.com> Date: Mon, 10 Mar 2025 11:52:20 +1100 Subject: [PATCH] refactor(zones): move to shared module --- imports/zones/server.lua | 110 ---------- imports/zones/{client.lua => shared.lua} | 248 +++++++++++------------ 2 files changed, 120 insertions(+), 238 deletions(-) delete mode 100644 imports/zones/server.lua rename imports/zones/{client.lua => shared.lua} (73%) diff --git a/imports/zones/server.lua b/imports/zones/server.lua deleted file mode 100644 index fec4784..0000000 --- a/imports/zones/server.lua +++ /dev/null @@ -1,110 +0,0 @@ -local glm = require 'glm' - ----@type table -local Zones = {} -_ENV.Zones = Zones - -local function removeZone(self) - Zones[self.id] = nil -end - -local glm_polygon_contains = glm.polygon.contains - -local function contains(self, coords) - return glm_polygon_contains(self.polygon, coords, self.thickness / 4) -end - -local function insideSphere(self, coords) - return #(self.coords - coords) < self.radius -end - -local function convertToVector(coords) - local _type = type(coords) - - if _type ~= 'vector3' then - if _type == 'table' or _type == 'vector4' then - return vec3(coords[1] or coords.x, coords[2] or coords.y, coords[3] or coords.z) - end - - error(("expected type 'vector3' or 'table' (received %s)"):format(_type)) - end - - return coords -end - -lib.zones = { - ---@return CZone - poly = function(data) - data.id = #Zones + 1 - data.thickness = data.thickness or 4 - - local pointN = #data.points - local points = table.create(pointN, 0) - - for i = 1, pointN do - points[i] = convertToVector(data.points[i]) - end - - data.polygon = glm.polygon.new(points) - data.coords = data.polygon:centroid() - data.type = 'poly' - data.remove = removeZone - data.contains = contains - data.debug = nil - data.debugColour = nil - data.inside = nil - data.onEnter = nil - data.onExit = nil - - Zones[data.id] = data - return data - end, - - ---@return CZone - box = function(data) - data.id = #Zones + 1 - data.coords = convertToVector(data.coords) - data.size = data.size and convertToVector(data.size) / 2 or vec3(2) - data.thickness = data.size.z * 2 or 4 - data.rotation = quat(data.rotation or 0, vec3(0, 0, 1)) - data.polygon = (data.rotation * glm.polygon.new({ - vec3(data.size.x, data.size.y, 0), - vec3(-data.size.x, data.size.y, 0), - vec3(-data.size.x, -data.size.y, 0), - vec3(data.size.x, -data.size.y, 0), - }) + data.coords) - data.type = 'box' - data.remove = removeZone - data.contains = contains - data.debug = nil - data.debugColour = nil - data.inside = nil - data.onEnter = nil - data.onExit = nil - - Zones[data.id] = data - return data - end, - - ---@return CZone - sphere = function(data) - data.id = #Zones + 1 - data.coords = convertToVector(data.coords) - data.radius = (data.radius or 2) + 0.0 - data.type = 'sphere' - data.remove = removeZone - data.contains = insideSphere - data.debug = nil - data.debugColour = nil - data.inside = nil - data.onEnter = nil - data.onExit = nil - - Zones[data.id] = data - return data - end, - - getAllZones = function() return Zones end, -} - -return lib.zones diff --git a/imports/zones/client.lua b/imports/zones/shared.lua similarity index 73% rename from imports/zones/client.lua rename to imports/zones/shared.lua index 87e8e5c..5dcc7db 100644 --- a/imports/zones/client.lua +++ b/imports/zones/shared.lua @@ -96,20 +96,17 @@ local function getTriangles(polygon) return triangles end ----@type table -local insideZones = {} - ----@type CZone[] | Array -local exitingZones = lib.array:new() - ----@type CZone[] | Array -local enteringZones = lib.array:new() - -local tick +local insideZones = lib.context == 'client' and {} --[[@as table]] +local exitingZones = lib.context == 'client' and lib.array:new() --[[@as Array]] +local enteringZones = lib.context == 'client' and lib.array:new() --[[@as Array]] local glm_polygon_contains = glm.polygon.contains +local tick local function removeZone(zone) Zones[zone.id] = nil + + if lib.context == 'server' then return end + insideZones[zone.id] = nil table.remove(exitingZones, exitingZones:indexOf(zone)) @@ -117,6 +114,8 @@ local function removeZone(zone) end CreateThread(function() + if lib.context == 'server' then return end + while true do local coords = GetEntityCoords(cache.ped) cache.coords = coords @@ -292,137 +291,130 @@ local function setDebug(self, bool, colour) self.debug = self.__type == 'sphere' and debugSphere or debugPoly or nil end -lib.zones = { - ---@return CZone - poly = function(data) - data.id = #Zones + 1 - data.thickness = data.thickness or 4 +---@param data CZone +---@return CZone +local function setZone(data) + data.remove = removeZone + data.contains = data.contains or contains - local pointN = #data.points - local points = table.create(pointN, 0) + if lib.context == 'client' then + data.setDebug = setDebug + + if data.debug then + data.debug = nil + + data:setDebug(true, data.debugColour) + end + else + data.debug = nil + end + + Zones[data.id] = data + + return data +end + +lib.zones = {} + +function lib.zones.poly(data) + data.id = #Zones + 1 + data.thickness = data.thickness or 4 + + local pointN = #data.points + local points = table.create(pointN, 0) + + for i = 1, pointN do + points[i] = convertToVector(data.points[i]) + end + + data.polygon = glm.polygon.new(points) + + if not data.polygon:isPlanar() then + local zCoords = {} for i = 1, pointN do - points[i] = convertToVector(data.points[i]) + local zCoord = points[i].z + + if zCoords[zCoord] then + zCoords[zCoord] += 1 + else + zCoords[zCoord] = 1 + end + end + + local coordsArray = {} + + for coord, count in pairs(zCoords) do + coordsArray[#coordsArray + 1] = { + coord = coord, + count = count + } + end + + table.sort(coordsArray, function(a, b) + return a.count > b.count + end) + + local zCoord = coordsArray[1].coord + local averageTo = 1 + + for i = 1, #coordsArray do + if coordsArray[i].count < coordsArray[1].count then + averageTo = i - 1 + break + end + end + + if averageTo > 1 then + for i = 2, averageTo do + zCoord += coordsArray[i].coord + end + + zCoord /= averageTo + end + + for i = 1, pointN do + points[i] = vec3(data.points[i].xy, zCoord) end data.polygon = glm.polygon.new(points) + end - if not data.polygon:isPlanar() then - local zCoords = {} + data.coords = data.polygon:centroid() + data.__type = 'poly' - for i = 1, pointN do - local zCoord = points[i].z + return setZone(data) +end - if zCoords[zCoord] then - zCoords[zCoord] += 1 - else - zCoords[zCoord] = 1 - end - end +function lib.zones.box(data) + data.id = #Zones + 1 + data.coords = convertToVector(data.coords) + data.size = data.size and convertToVector(data.size) / 2 or vec3(2) + data.thickness = data.size.z * 2 or 4 + data.rotation = quat(data.rotation or 0, vec3(0, 0, 1)) + data.__type = 'box' + data.polygon = (data.rotation * glm.polygon.new({ + vec3(data.size.x, data.size.y, 0), + vec3(-data.size.x, data.size.y, 0), + vec3(-data.size.x, -data.size.y, 0), + vec3(data.size.x, -data.size.y, 0), + }) + data.coords) - local coordsArray = {} + return setZone(data) +end - for coord, count in pairs(zCoords) do - coordsArray[#coordsArray + 1] = { - coord = coord, - count = count - } - end +function lib.zones.sphere(data) + data.id = #Zones + 1 + data.coords = convertToVector(data.coords) + data.radius = (data.radius or 2) + 0.0 + data.__type = 'sphere' + data.contains = insideSphere - table.sort(coordsArray, function(a, b) - return a.count > b.count - end) + return setZone(data) +end - local zCoord = coordsArray[1].coord - local averageTo = 1 +function lib.zones.getAllZones() return Zones end - for i = 1, #coordsArray do - if coordsArray[i].count < coordsArray[1].count then - averageTo = i - 1 - break - end - end - - if averageTo > 1 then - for i = 2, averageTo do - zCoord += coordsArray[i].coord - end - - zCoord /= averageTo - end - - for i = 1, pointN do - points[i] = vec3(data.points[i].xy, zCoord) - end - - data.polygon = glm.polygon.new(points) - end - - data.coords = data.polygon:centroid() - data.__type = 'poly' - data.remove = removeZone - data.contains = contains - data.setDebug = setDebug - - if data.debug then - data.debug = nil - - data:setDebug(true, data.debugColour) - end - - Zones[data.id] = data - return data - end, - - ---@return CZone - box = function(data) - data.id = #Zones + 1 - data.coords = convertToVector(data.coords) - data.size = data.size and convertToVector(data.size) / 2 or vec3(2) - data.thickness = data.size.z * 2 or 4 - data.rotation = quat(data.rotation or 0, vec3(0, 0, 1)) - data.polygon = (data.rotation * glm.polygon.new({ - vec3(data.size.x, data.size.y, 0), - vec3(-data.size.x, data.size.y, 0), - vec3(-data.size.x, -data.size.y, 0), - vec3(data.size.x, -data.size.y, 0), - }) + data.coords) - data.__type = 'box' - data.remove = removeZone - data.contains = contains - data.setDebug = setDebug - - if data.debug then - data.debug = nil - - data:setDebug(true, data.debugColour) - end - - Zones[data.id] = data - return data - end, - - ---@return CZone - sphere = function(data) - data.id = #Zones + 1 - data.coords = convertToVector(data.coords) - data.radius = (data.radius or 2) + 0.0 - data.__type = 'sphere' - data.remove = removeZone - data.contains = insideSphere - data.setDebug = setDebug - - if data.debug then - data:setDebug(true, data.debugColour) - end - - Zones[data.id] = data - return data - end, - - getAllZones = function() return Zones end, - - getCurrentZones = function() return insideZones end, -} +function lib.zones.getCurrentZones() return insideZones end return lib.zones