[mcl_maps] Center, slightly optimize, use position to calculate ID

This commit is contained in:
kay27 2021-05-10 05:01:02 +04:00
parent f054eb1ce6
commit 4d5af781e8
1 changed files with 70 additions and 60 deletions

View File

@ -1,11 +1,12 @@
mcl_maps = {} mcl_maps = {}
local S = minetest.get_translator("mcl_maps") local S = minetest.get_translator("mcl_maps")
local storage = minetest.get_mod_storage()
local modpath = minetest.get_modpath("mcl_maps") local modpath = minetest.get_modpath("mcl_maps")
local worldpath = minetest.get_worldpath() local worldpath = minetest.get_worldpath()
local map_textures_path = worldpath .. "/mcl_maps/" local map_textures_path = worldpath .. "/mcl_maps/"
local last_finished_id = storage:get_int("next_id") - 1
local math_min = math.min
local math_max = math.max
minetest.mkdir(map_textures_path) minetest.mkdir(map_textures_path)
@ -27,14 +28,12 @@ local loaded_maps = {}
local c_air = minetest.get_content_id("air") local c_air = minetest.get_content_id("air")
function mcl_maps.create_map(pos) function mcl_maps.create_map(pos)
local minp = vector.multiply(vector.floor(vector.divide(pos, 128)), 128) local minp = vector.subtract(vector.floor(pos), 64)
local maxp = vector.add(minp, vector.new(127, 127, 127)) local maxp = vector.add(minp, 127)
local itemstack = ItemStack("mcl_maps:filled_map") local itemstack = ItemStack("mcl_maps:filled_map")
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
local next_id = storage:get_int("next_id") local id = string.format(".0f", minetest.hash_node_position(pos))
storage:set_int("next_id", next_id + 1)
local id = tostring(next_id)
meta:set_string("mcl_maps:id", id) meta:set_string("mcl_maps:id", id)
meta:set_string("mcl_maps:minp", minetest.pos_to_string(minp)) meta:set_string("mcl_maps:minp", minetest.pos_to_string(minp))
meta:set_string("mcl_maps:maxp", minetest.pos_to_string(maxp)) meta:set_string("mcl_maps:maxp", minetest.pos_to_string(maxp))
@ -49,19 +48,31 @@ function mcl_maps.create_map(pos)
local emin, emax = vm:read_from_map(minp, maxp) local emin, emax = vm:read_from_map(minp, maxp)
local data = vm:get_data() local data = vm:get_data()
local param2data = vm:get_param2_data() local param2data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local offset_x, offset_y, offset_z = minp.x - emin.x, minp.y - emin.y, minp.z - emin.z
local dx = emax.x - emin.x + 1
local dy = (emax.y - emin.y + 1) * dx
local offset = offset_z * dy + offset_y * dx + offset_x
local map_y_start = 64 * dx
local map_y_limit = 127 * dx
local pixels = {} local pixels = {}
local last_heightmap local last_heightmap
for x = 1, 128 do for x = 1, 128 do
local map_x = minp.x - 1 + x local map_x = x + offset
local heightmap = {} local heightmap = {}
for z = 1, 128 do for z = 1, 128 do
local map_z = minp.z - 1 + z local map_z = (z-1) * dy + map_x
local color, height local color, height
for map_y = maxp.y, minp.y, -1 do
local index = area:index(map_x, map_y, map_z) local map_y = map_z + map_y_start
local c_id = data[index] local map_y_limit = map_z + map_y_limit
if c_id ~= c_air then while data[map_y] ~= c_air and map_y < map_y_limit do
map_y = map_y + dx
end
while data[map_y] == c_air and map_y > map_z do
map_y = map_y - dx
end
local c_id = data[map_y]
color = color_cache[c_id] color = color_cache[c_id]
if color == nil then if color == nil then
local nodename = minetest.get_name_from_content_id(c_id) local nodename = minetest.get_name_from_content_id(c_id)
@ -89,31 +100,30 @@ function mcl_maps.create_map(pos)
end end
if color and color.palette then if color and color.palette then
color = color.palette[param2data[index] + 1] color = color.palette[param2data[map_y] + 1]
else else
color_cache[c_id] = color or false color_cache[c_id] = color or false
end end
if color and last_heightmap then if color and last_heightmap then
local last_height = last_heightmap[z] local last_height = last_heightmap[z]
if last_height < map_y then local y = map_y - map_z
if last_height < y then
color = { color = {
math.min(255, color[1] + 16), math_min(255, color[1] + 16),
math.min(255, color[2] + 16), math_min(255, color[2] + 16),
math.min(255, color[3] + 16), math_min(255, color[3] + 16),
} }
elseif last_height > map_y then elseif last_height > y then
color = { color = {
math.max(0, color[1] - 16), math_max(0, color[1] - 16),
math.max(0, color[2] - 16), math_max(0, color[2] - 16),
math.max(0, color[3] - 16), math_max(0, color[3] - 16),
} }
end end
end end
height = map_y height = map_y - map_z
break
end
end
heightmap[z] = height or minp.y heightmap[z] = height or minp.y
pixels[z] = pixels[z] or {} pixels[z] = pixels[z] or {}
pixels[z][x] = color or {0, 0, 0} pixels[z][x] = color or {0, 0, 0}