refactor(client/zones): re-order zones and call onExit before onEnter

insideZones will be stored as a map rather than an array for simplicity.
Store zones the player is entering and exiting, then sort based on distance;
always triggering onExit for all zones before onEnter.
See #179.
This commit is contained in:
Linden
2022-12-24 15:48:40 +11:00
parent b688b98bba
commit 6a704c40fe

View File

@@ -196,19 +196,17 @@ local function removeZone(self)
Zones[self.id] = nil Zones[self.id] = nil
end end
local inside = {} local insideZones = {}
local insideCount = 0 local enteringZones = {}
local exitingZones = {}
local enteringSize = 0
local exitingSize = 0
local tick local tick
local glm_polygon_contains = glm.polygon.contains local glm_polygon_contains = glm.polygon.contains
CreateThread(function() CreateThread(function()
while true do while true do
if insideCount ~= 0 then
table.wipe(inside)
insideCount = 0
end
local coords = GetEntityCoords(cache.ped) local coords = GetEntityCoords(cache.ped)
cache.coords = coords cache.coords = coords
@@ -227,36 +225,61 @@ CreateThread(function()
zone.insideZone = true zone.insideZone = true
if zone.onEnter then if zone.onEnter then
zone:onEnter() enteringSize += 1
enteringZones[enteringSize] = zone
end end
end
if zone.inside or zone.debug then if zone.inside or zone.debug then
insideCount += 1 insideZones[zone.id] = zone
inside[insideCount] = zone end
end end
else else
if zone.insideZone then if zone.insideZone then
zone.insideZone = false zone.insideZone = false
insideZones[zone.id] = nil
if zone.onExit then if zone.onExit then
zone:onExit() exitingSize += 1
exitingZones[exitingSize] = zone
end end
end end
if zone.debug then if zone.debug then
insideCount += 1 insideZones[zone.id] = zone
inside[insideCount] = zone
end end
end end
end end
if not tick then if exitingSize > 0 then
if insideCount ~= 0 then table.sort(exitingZones, function(a, b)
tick = SetInterval(function() return a.distance > b.distance
for i = 1, insideCount do end)
local zone = inside[i]
for i = 1, exitingSize do
exitingZones[i]:onExit()
end
exitingSize = 0
table.wipe(exitingZones)
end
if enteringSize > 0 then
table.sort(enteringZones, function(a, b)
return a.distance < b.distance
end)
for i = 1, enteringSize do
enteringZones[i]:onEnter()
end
enteringSize = 0
table.wipe(enteringZones)
end
if not tick then
if next(insideZones) then
tick = SetInterval(function()
for _, zone in pairs(insideZones) do
if zone.debug then if zone.debug then
zone:debug() zone:debug()
@@ -269,7 +292,7 @@ CreateThread(function()
end end
end) end)
end end
elseif insideCount == 0 then elseif not next(insideZones) then
tick = ClearInterval(tick) tick = ClearInterval(tick)
end end