126 lines
3.2 KiB
Lua
126 lines
3.2 KiB
Lua
|
|
-- Copyright (C) 2017-2020 DBotThePony
|
|
|
|
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
-- of this software and associated documentation files (the "Software"), to deal
|
|
-- in the Software without restriction, including without limitation the rights
|
|
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
-- of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
-- subject to the following conditions:
|
|
|
|
-- The above copyright notice and this permission notice shall be included in all copies
|
|
-- or substantial portions of the Software.
|
|
|
|
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
-- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
-- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
-- FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
-- DEALINGS IN THE SOFTWARE.
|
|
|
|
-- TODO: Consider removal or rewrite
|
|
return function()
|
|
local export = {}
|
|
local usedSlots = {}
|
|
|
|
export.slotUsagePriority = {
|
|
{0, 0},
|
|
{1, 0},
|
|
{-1, 0},
|
|
{0, 1},
|
|
{0, -1},
|
|
{-1, 1},
|
|
{1, 1},
|
|
{1, -1},
|
|
{-1, -1},
|
|
}
|
|
|
|
local slotUsagePriority = export.slotUsagePriority
|
|
|
|
function export.findNearest(x, y, size)
|
|
usedSlots[size] = usedSlots[size] or {}
|
|
local div = size * 24
|
|
local ctab = usedSlots[size]
|
|
local slotX, slotY = math.floor(x / div), math.floor(y / div)
|
|
|
|
if ctab[slotX] == nil then
|
|
ctab[slotX] = {}
|
|
ctab[slotX][slotY] = true
|
|
return x, y
|
|
else
|
|
local findFreeSlotX, findFreeSlotY = 0, 0
|
|
|
|
for radius = 1, 10 do
|
|
local success = false
|
|
|
|
for i, priorityData in ipairs(slotUsagePriority) do
|
|
local sx, sy = priorityData[1] * radius + slotX, priorityData[2] * radius + slotY
|
|
|
|
if not ctab[sx] or not ctab[sx][sy] then
|
|
findFreeSlotX, findFreeSlotY = sx, sy
|
|
success = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if success then
|
|
break
|
|
end
|
|
end
|
|
|
|
ctab[findFreeSlotX] = ctab[findFreeSlotX] or {}
|
|
ctab[findFreeSlotX][findFreeSlotY] = true
|
|
|
|
return findFreeSlotX * div, findFreeSlotY * div
|
|
end
|
|
end
|
|
|
|
function export.findNearestAlt(x, y, size, sizeH)
|
|
size = size or 16
|
|
sizeH = sizeH or size
|
|
usedSlots[size] = usedSlots[size] or {}
|
|
local div = size * 24
|
|
local divY = sizeH * 24
|
|
local ctab = usedSlots[size]
|
|
local slotX, slotY = math.floor(x / div), math.floor(y / divY)
|
|
|
|
if ctab[slotX] == nil then
|
|
ctab[slotX] = {}
|
|
ctab[slotX][slotY] = true
|
|
return x, y
|
|
else
|
|
local findFreeSlotX, findFreeSlotY = 0, 0
|
|
|
|
for radius = 1, 10 do
|
|
local success = false
|
|
|
|
for x = radius, -radius, -1 do
|
|
for y = radius, -radius, -1 do
|
|
local sx, sy = x + slotX, y + slotY
|
|
|
|
if not ctab[sx] or not ctab[sx][sy] then
|
|
findFreeSlotX, findFreeSlotY = sx, sy
|
|
success = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
if success then
|
|
break
|
|
end
|
|
end
|
|
|
|
ctab[findFreeSlotX] = ctab[findFreeSlotX] or {}
|
|
ctab[findFreeSlotX][findFreeSlotY] = true
|
|
|
|
return findFreeSlotX * div, findFreeSlotY * divY
|
|
end
|
|
end
|
|
|
|
function export.clear()
|
|
usedSlots = {}
|
|
end
|
|
|
|
return export
|
|
end
|