nodecore-cd2025/mods/nc_api/mapgen_limits.lua

85 lines
2.4 KiB
Lua
Raw Normal View History

2020-03-22 10:59:06 -04:00
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, string, tonumber, vector
= math, minetest, nodecore, string, tonumber, vector
2020-03-22 11:07:20 -04:00
local math_floor, string_format
= math.floor, string.format
2020-03-22 10:59:06 -04:00
-- LUALOCALS > ---------------------------------------------------------
local limit = tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000
local chunksize = tonumber(minetest.get_mapgen_setting("chunksize")) or 5
chunksize = chunksize * 16
2020-03-22 11:07:20 -04:00
local limitchunks = math_floor(limit / chunksize)
2020-03-22 10:59:06 -04:00
local min = (-limitchunks + 0.5) * chunksize + 7.5
nodecore.map_limit_min = min
local max = (limitchunks - 0.5) * chunksize + 7.5
nodecore.map_limit_max = max
2020-03-22 11:07:20 -04:00
nodecore.log("info", string_format("mapgen limit: %d, chunk: %d, bounds: %0.1f to %0.1f",
2020-03-22 11:07:20 -04:00
limit, chunksize, nodecore.map_limit_min, nodecore.map_limit_max))
function nodecore.within_map_limits(pos)
return pos.x >= min
and pos.y >= min
and pos.z >= min
and pos.x <= max
and pos.y <= max
and pos.z <= max
end
function nodecore.near_unloaded(pos, node, dist)
pos = vector.floor(pos)
if not (node or minetest.get_node_or_nil(pos)) then return true end
if (not dist) or (dist < 1) then return end
dist = math_floor(dist)
-- Clamp area to check to map bounds; areas outside the map
-- are always considered "loaded" and their ignores are
-- treated as canonical.
local zmin = pos.z - dist
if zmin < min then zmin = min end
local zmax = pos.z + dist
if zmax > max then zmax = max end
local ymin = pos.y - dist
if ymin < min then ymin = min end
local ymax = pos.y + dist
if ymax > max then ymax = max end
local xmin = pos.x - dist
if xmin < min then xmin = min end
local xmax = pos.x + dist
if xmax > max then xmax = max end
-- Check corners of area
local step = dist * 2
for z = zmin, zmax, step do
pos.z = z
for y = ymin, ymax, step do
pos.y = y
for x = xmin, xmax, step do
pos.x = x
if not minetest.get_node_or_nil(pos) then return true end
end
end
end
-- If area is wide enough to have entire mapblocks not
-- covered by the center and corners, then check each
-- mapblock in case internal ones are unloaded.
if dist <= 16 then return end
for z = zmin, zmax, 16 do
pos.z = z
for y = ymin, ymax, 16 do
pos.y = y
for x = xmin, xmax, 16 do
pos.x = x
if not minetest.get_node_or_nil(pos) then return true end
end
end
end
end