Files
community_bridge/lib/points/client/pointsv2.lua
T
Mr.Crowley bdde5124ff Simplified Points
Reduced code and calculations should hopefully be more performant
2025-08-15 23:54:55 -05:00

152 lines
4.6 KiB
Lua

local GRIDE_SIZE_X = 8968.83 / 2
local GRIDE_SIZE_Y = 126200.40 / 2
local CELL_SIZE = 500
local Grid = {}
Grid.Generated = false
local Grids = {}
Point = {}
Point.All = {}
function Grid.Generate()
if Grid.Generated then return end
Grid.Generated = true
local numOfCellsX = math.ceil(GRIDE_SIZE_X / CELL_SIZE)
local numOfCellsY = math.ceil(GRIDE_SIZE_Y / CELL_SIZE)
for x = -numOfCellsX, numOfCellsX do
Grids[x] = {}
for y = -numOfCellsY, numOfCellsY do
Grids[x][y] = {}
end
end
end
function Grid.GetCellId(coords)
local cellX = math.floor(coords.x / CELL_SIZE) + 1
local cellY = math.floor(coords.y / CELL_SIZE) + 1
return string.format("%d_%d", cellX, cellY)
end
function Grid.GetCellByCoords(coords)
local cellX = math.floor(coords.x / CELL_SIZE) + 1
local cellY = math.floor(coords.y / CELL_SIZE) + 1
if Grids[cellX] and Grids[cellX][cellY] then
return Grids[cellX][cellY]
end
return nil
end
local Points = {}
Points.Started = false
function Point.StartLoop()
if Points.Started then return end
Points.Started = true
CreateThread(function()
while Points.Started do
local playerPed = PlayerPedId()
if playerPed ~= -1 then
local coords = GetEntityCoords(playerPed)
local cell = Grid.GetCellByCoords(coords)
for _, point in pairs(cell or {}) do
if point.isEntity then
local entity = point.target
if DoesEntityExist(entity) then
local entityCoords = GetEntityCoords(entity)
local distance = #(coords - entityCoords)
if distance < point.distance then
if not point.inside then
point.inside = true
point.args = point?.onEnter(point, point.args) or point.args
end
elseif point.inside then
point.inside = false
point.args = point?.onExit(point, point.args) or point.args
end
end
else
local distance = #(coords.xyz - point.coords.xyz)
if distance < point.distance then
if not point.inside then
point.inside = true
point.args = point?.onEnter(point, point.args) or point.args
end
elseif point.inside then
point.inside = false
point.args = point?.onExit(point, point.args) or point.args
end
end
end
end
Wait(1000)
end
end)
end
function Point.Register(id, target, distance, args, _onEnter, _onExit)
local isEntity = type(target) == "number"
local coords = isEntity and GetEntityCoords(target) or target
print(target)
Grid.Generate()
local self = {}
self.id = id
self.target = target -- Store entity ID or Vector3
self.isEntity = isEntity
self.coords = coords
self.distance = distance
self.onEnter = _onEnter or function() end
self.onExit = _onExit or function() end
self.inside = false -- Track if player is inside
self.args = args or {}
local grid = Grid.GetCellByCoords(coords)
self.cellKey = Grid.GetCellId(coords)
grid[self.cellKey] = self
Point.All[id] = self
Point.StartLoop()
return self
end
function Point.Remove(id)
local point = Point.All[id]
if not point then return false end
-- Remove from grid
local grid = Grid.GetCellByCoords(point.coords)
if grid then
grid[point.cellKey] = nil
end
Point.All[id] = nil
return true
end
function Point.Get(id)
return Point.All[id]
end
function Point.UpdateCoords(id, coords)
local point = Point.All[id]
if not point then return end
local newGrid = Grid.GetCellByCoords(coords)
if not newGrid or newGrid[point.cellKey] then return end
local oldGrid = Grid.GetCellByCoords(point.coords)
if oldGrid then
oldGrid[point.cellKey] = nil
end
-- Add to new grid
point.coords = coords
point.cellKey = string.format("%d_%d", newGrid.x, newGrid.y)
newGrid[point.cellKey] = point
return true
end
function Point.GetAll()
return Point.All
end
return Point