feat(zones): utilise the grid system

This probably works, even.
This commit is contained in:
Linden
2025-03-10 12:30:00 +11:00
parent 534b1ab435
commit 105a079c09

View File

@@ -12,7 +12,7 @@ local glm = require 'glm'
---@class CZone : PolyZone, BoxZone, SphereZone ---@class CZone : PolyZone, BoxZone, SphereZone
---@field id number ---@field id number
---@field __type 'poly' | 'sphere' | 'box' ---@field __type 'poly' | 'sphere' | 'box'
---@field remove fun() ---@field remove fun(self: self)
---@field setDebug fun(self: CZone, enable?: boolean, colour?: vector) ---@field setDebug fun(self: CZone, enable?: boolean, colour?: vector)
---@field contains fun(self: CZone, coords?: vector3): boolean ---@field contains fun(self: CZone, coords?: vector3): boolean
@@ -104,9 +104,12 @@ local enteringZones = lib.context == 'client' and lib.array:new() --[[@as Array<
local glm_polygon_contains = glm.polygon.contains local glm_polygon_contains = glm.polygon.contains
local tick local tick
---@param zone CZone
local function removeZone(zone) local function removeZone(zone)
Zones[zone.id] = nil Zones[zone.id] = nil
lib.grid.removeEntry(zone)
if lib.context == 'server' then return end if lib.context == 'server' then return end
insideZones[zone.id] = nil insideZones[zone.id] = nil
@@ -118,13 +121,31 @@ end
CreateThread(function() CreateThread(function()
if lib.context == 'server' then return end if lib.context == 'server' then return end
local lastZones = {}
while true do while true do
local coords = GetEntityCoords(cache.ped) local coords = GetEntityCoords(cache.ped)
local zones = lib.grid.getNearbyEntries(coords) --[[@as CZone[] ]]
local cellX, cellY = lib.grid.getCellPosition(coords)
cache.coords = coords cache.coords = coords
for _, zone in pairs(Zones) do if cellX ~= cache.lastCellX or cellY ~= cache.lastCellY then
zone.distance = #(zone.coords - coords) for i = 1, #lastZones do
local zone = lastZones[i]
zone.insideZone = false
insideZones[zone.id] = nil
end
lastZones = zones
cache.lastCellX = cellX
cache.lastCellY = cellY
end
for i = 1, #zones do
local zone = zones[i]
local radius, contains = zone.radius, nil local radius, contains = zone.radius, nil
zone.distance = #(zone.coords - coords)
if radius then if radius then
contains = zone.distance < radius contains = zone.distance < radius
@@ -165,7 +186,7 @@ CreateThread(function()
if exitingSize > 0 then if exitingSize > 0 then
table.sort(exitingZones, function(a, b) table.sort(exitingZones, function(a, b)
return a.distance > b.distance return a.distance < b.distance
end) end)
for i = exitingSize, 1, -1 do for i = exitingSize, 1, -1 do
@@ -313,6 +334,7 @@ local function setZone(data)
end end
Zones[data.id] = data Zones[data.id] = data
lib.grid.addEntry(data)
return data return data
end end
@@ -391,6 +413,10 @@ function lib.zones.poly(data)
data.coords = data.polygon:centroid() data.coords = data.polygon:centroid()
data.__type = 'poly' data.__type = 'poly'
data.radius = lib.array.reduce(data.polygon, function(acc, point)
local distance = #(point - data.coords)
return distance > acc and distance or acc
end, 0)
return setZone(data) return setZone(data)
end end
@@ -409,6 +435,8 @@ function lib.zones.box(data)
data.thickness = data.size.z * 2 or 4 data.thickness = data.size.z * 2 or 4
data.rotation = quat(data.rotation or 0, vec3(0, 0, 1)) data.rotation = quat(data.rotation or 0, vec3(0, 0, 1))
data.__type = 'box' data.__type = 'box'
data.width = data.size.x * 2
data.length = data.size.y * 2
data.polygon = (data.rotation * glm.polygon.new({ 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),