feat(points): utilise the grid system

This commit is contained in:
Linden
2025-03-10 16:28:44 +11:00
parent 5a18b7e2d5
commit 39ec1d3df5

View File

@@ -26,74 +26,93 @@ local function removePoint(self)
closestPoint = nil closestPoint = nil
end end
points[self.id] = nil lib.grid.removeEntry(self)
points[self.id] = nil
end end
CreateThread(function() CreateThread(function()
while true do while true do
if nearbyCount ~= 0 then if nearbyCount ~= 0 then
table.wipe(nearbyPoints) table.wipe(nearbyPoints)
nearbyCount = 0 nearbyCount = 0
end
local coords = GetEntityCoords(cache.ped)
cache.coords = coords
if closestPoint and #(coords - closestPoint.coords) > closestPoint.distance then
closestPoint = nil
end end
for _, point in pairs(points) do local coords = GetEntityCoords(cache.ped)
local distance = #(coords - point.coords) local newPoints = lib.grid.getNearbyEntries(coords, function(entry) return entry.remove == removePoint end) --[[@as CPoint[] ]]
local cellX, cellY = lib.grid.getCellPosition(coords)
cache.coords = coords
closestPoint = nil
if distance <= point.distance then if cellX ~= cache.lastCellX or cellY ~= cache.lastCellY then
point.currentDistance = distance for i = 1, #nearbyPoints do
local point = nearbyPoints[i]
if closestPoint then if point.inside then
if distance < closestPoint.currentDistance then local distance = #(coords - point.coords)
closestPoint.isClosest = nil
point.isClosest = true if distance > point.radius then
closestPoint = point if point.onExit then point:onExit() end
point.inside = nil
point.currentDistance = nil
end end
elseif distance < point.distance then end
end
cache.lastCellX = cellX
cache.lastCellY = cellY
end
for i = 1, #newPoints do
local point = newPoints[i]
local distance = #(coords - point.coords)
if distance <= point.radius then
point.currentDistance = distance
if not closestPoint or distance < (closestPoint.currentDistance or point.radius) then
if closestPoint then closestPoint.isClosest = nil end
point.isClosest = true point.isClosest = true
closestPoint = point closestPoint = point
end end
if point.nearby then if point.nearby then
nearbyCount += 1 nearbyCount += 1
nearbyPoints[nearbyCount] = point nearbyPoints[nearbyCount] = point
end end
if point.onEnter and not point.inside then if point.onEnter and not point.inside then
point.inside = true point.inside = true
point:onEnter() point:onEnter()
end end
elseif point.currentDistance then elseif point.currentDistance then
if point.onExit then point:onExit() end if point.onExit then point:onExit() end
point.inside = nil
point.currentDistance = nil
end
end
if not tick then point.inside = nil
if nearbyCount ~= 0 then point.currentDistance = nil
tick = SetInterval(function() end
for i = 1, nearbyCount do end
if not tick then
if nearbyCount ~= 0 then
tick = SetInterval(function()
for i = nearbyCount, 1, -1 do
local point = nearbyPoints[i] local point = nearbyPoints[i]
if point then if point and point.nearby then
point:nearby() point:nearby()
end end
end end
end) end)
end end
elseif nearbyCount == 0 then elseif nearbyCount == 0 then
tick = ClearInterval(tick) tick = ClearInterval(tick)
end end
Wait(300) Wait(300)
end end
end) end)
local function toVector(coords) local function toVector(coords)
@@ -110,50 +129,52 @@ local function toVector(coords)
return coords return coords
end end
lib.points = { lib.points = {}
---@return CPoint
---@overload fun(data: PointProperties): CPoint
---@overload fun(coords: vector3, distance: number, data?: PointProperties): CPoint
new = function(...)
local args = {...}
local id = #points + 1
local self
-- Support sending a single argument containing point data ---@return CPoint
if type(args[1]) == 'table' then ---@overload fun(data: PointProperties): CPoint
self = args[1] ---@overload fun(coords: vector3, distance: number, data?: PointProperties): CPoint
self.id = id function lib.points.new(...)
self.remove = removePoint local args = { ... }
else local id = #points + 1
-- Backwards compatibility for original implementation (args: coords, distance, data) local self
self = {
id = id,
coords = args[1],
remove = removePoint,
}
end
self.coords = toVector(self.coords) -- Support sending a single argument containing point data
self.distance = self.distance or args[2] if type(args[1]) == 'table' then
self = args[1]
self.id = id
self.remove = removePoint
else
-- Backwards compatibility for original implementation (args: coords, distance, data)
self = {
id = id,
coords = args[1],
remove = removePoint,
}
end
if args[3] then self.coords = toVector(self.coords)
for k, v in pairs(args[3]) do self.distance = self.distance or args[2]
self[k] = v self.radius = self.distance
end
end
points[id] = self if args[3] then
for k, v in pairs(args[3]) do
self[k] = v
end
end
return self lib.grid.addEntry(self)
end, points[id] = self
getAllPoints = function() return points end, return self
end
getNearbyPoints = function() return nearbyPoints end, function lib.points.getAllPoints() return points end
---@return CPoint? function lib.points.getNearbyPoints() return nearbyPoints end
getClosestPoint = function() return closestPoint end,
} ---@return CPoint?
function lib.points.getClosestPoint() return closestPoint end
---@deprecated ---@deprecated
lib.points.closest = lib.points.getClosestPoint lib.points.closest = lib.points.getClosestPoint