diff --git a/imports/points/client.lua b/imports/points/client.lua index 9395c62..c8608d4 100644 --- a/imports/points/client.lua +++ b/imports/points/client.lua @@ -26,74 +26,93 @@ local function removePoint(self) closestPoint = nil end - points[self.id] = nil + lib.grid.removeEntry(self) + + points[self.id] = nil end CreateThread(function() - while true do + while true do if nearbyCount ~= 0 then - table.wipe(nearbyPoints) - nearbyCount = 0 - end - - local coords = GetEntityCoords(cache.ped) - cache.coords = coords - - if closestPoint and #(coords - closestPoint.coords) > closestPoint.distance then - closestPoint = nil + table.wipe(nearbyPoints) + nearbyCount = 0 end - for _, point in pairs(points) do - local distance = #(coords - point.coords) + local coords = GetEntityCoords(cache.ped) + 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 - point.currentDistance = distance + if cellX ~= cache.lastCellX or cellY ~= cache.lastCellY then + for i = 1, #nearbyPoints do + local point = nearbyPoints[i] - if closestPoint then - if distance < closestPoint.currentDistance then - closestPoint.isClosest = nil - point.isClosest = true - closestPoint = point + if point.inside then + local distance = #(coords - point.coords) + + if distance > point.radius then + if point.onExit then point:onExit() end + + point.inside = nil + point.currentDistance = nil 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 closestPoint = point end - if point.nearby then + if point.nearby then nearbyCount += 1 nearbyPoints[nearbyCount] = point end - if point.onEnter and not point.inside then - point.inside = true - point:onEnter() - end - elseif point.currentDistance then - if point.onExit then point:onExit() end - point.inside = nil - point.currentDistance = nil - end - end + if point.onEnter and not point.inside then + point.inside = true + point:onEnter() + end + elseif point.currentDistance then + if point.onExit then point:onExit() end - if not tick then - if nearbyCount ~= 0 then - tick = SetInterval(function() - for i = 1, nearbyCount do + point.inside = nil + point.currentDistance = nil + end + end + + if not tick then + if nearbyCount ~= 0 then + tick = SetInterval(function() + for i = nearbyCount, 1, -1 do local point = nearbyPoints[i] - if point then + if point and point.nearby then point:nearby() end - end - end) - end - elseif nearbyCount == 0 then - tick = ClearInterval(tick) - end + end + end) + end + elseif nearbyCount == 0 then + tick = ClearInterval(tick) + end - Wait(300) - end + Wait(300) + end end) local function toVector(coords) @@ -110,50 +129,52 @@ local function toVector(coords) return coords end -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 +lib.points = {} - -- Support sending a single argument containing point data - 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 +---@return CPoint +---@overload fun(data: PointProperties): CPoint +---@overload fun(coords: vector3, distance: number, data?: PointProperties): CPoint +function lib.points.new(...) + local args = { ... } + local id = #points + 1 + local self - self.coords = toVector(self.coords) - self.distance = self.distance or args[2] + -- Support sending a single argument containing point data + 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 - for k, v in pairs(args[3]) do - self[k] = v - end - end + self.coords = toVector(self.coords) + self.distance = self.distance or args[2] + self.radius = self.distance - points[id] = self + if args[3] then + for k, v in pairs(args[3]) do + self[k] = v + end + end - return self - end, + lib.grid.addEntry(self) + 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? - getClosestPoint = function() return closestPoint end, -} +function lib.points.getNearbyPoints() return nearbyPoints end + +---@return CPoint? +function lib.points.getClosestPoint() return closestPoint end ---@deprecated lib.points.closest = lib.points.getClosestPoint