From 2228b306588c107dc4d88a4212fbf2c6c719f4da Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 1 May 2021 17:36:51 +0200 Subject: [PATCH] Add API to create filled map --- mods/ITEMS/mcl_maps/init.lua | 219 +++++++++++++++++------------------ 1 file changed, 108 insertions(+), 111 deletions(-) diff --git a/mods/ITEMS/mcl_maps/init.lua b/mods/ITEMS/mcl_maps/init.lua index df550f537..43a23f8f7 100644 --- a/mods/ITEMS/mcl_maps/init.lua +++ b/mods/ITEMS/mcl_maps/init.lua @@ -1,3 +1,5 @@ +mcl_maps = {} + local S = minetest.get_translator("mcl_maps") local storage = minetest.get_mod_storage() local modpath = minetest.get_modpath("mcl_maps") @@ -25,127 +27,122 @@ local loaded_maps = {} local c_air = minetest.get_content_id("air") --- Turn empty map into filled map by rightclick -local make_filled_map = function(itemstack, placer, pointed_thing) - local new_map = ItemStack("mcl_maps:filled_map") - if minetest.settings:get_bool("enable_real_maps", true) then - local meta = new_map:get_meta() - local id = storage:get_int("next_id") - storage:set_int("next_id", id + 1) - local texture_file = "mcl_maps_map_texture_" .. id .. ".tga" - local texture_path = map_textures_path .. texture_file - local texture = "[combine:140x140:0,0=mcl_maps_map_background.png:6,6=" .. texture_file - meta:set_int("mcl_maps:id", id) - meta:set_string("mcl_maps:texture", texture) - meta:set_string("mcl_maps:texture_path", texture_path) - tt.reload_itemstack_description(new_map) - creating_maps[texture] = true - local pos = placer:get_pos() - local minp = vector.multiply(vector.floor(vector.divide(pos, 128)), 128) - local maxp = vector.add(minp, vector.new(127, 127, 127)) - minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining) - if calls_remaining < 1 then - local vm = minetest.get_voxel_manip() - local emin, emax = vm:read_from_map(minp, maxp) - local data = vm:get_data() - local param2data = vm:get_param2_data() - local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) - local pixels = {} - local last_heightmap - for x = 1, 128 do - local map_x = minp.x - 1 + x - local heightmap = {} - for z = 1, 128 do - local map_z = minp.z - 1 + z - local color - for map_y = maxp.y, minp.y, -1 do - local index = area:index(map_x, map_y, map_z) - local c_id = data[index] - - if c_id ~= c_air then - color = color_cache[c_id] - - if color == nil then - local nodename = minetest.get_name_from_content_id(c_id) - local def = minetest.registered_nodes[nodename] - - if def then - local texture - - if def.palette then - texture = def.palette - elseif def.tiles then - texture = def.tiles[1] - - if type(texture) == "table" then - texture = texture.name - end - end - - if texture then - texture = texture:match("([^=^%^]-([^.]+))$"):split("^")[1] - end - - if def.palette then - local palette = palettes[texture] - color = palette and {palette = palette} - else - color = texture_colors[texture] - end +function mcl_maps.create_map(pos) + local itemstack = ItemStack("mcl_maps:filled_map") + local meta = itemstack:get_meta() + local id = storage:get_int("next_id") + storage:set_int("next_id", id + 1) + local texture_file = "mcl_maps_map_texture_" .. id .. ".tga" + local texture_path = map_textures_path .. texture_file + local texture = "[combine:140x140:0,0=mcl_maps_map_background.png:6,6=" .. texture_file + meta:set_int("mcl_maps:id", id) + meta:set_string("mcl_maps:texture", texture) + meta:set_string("mcl_maps:texture_path", texture_path) + tt.reload_itemstack_description(itemstack) + creating_maps[texture] = true + local minp = vector.multiply(vector.floor(vector.divide(pos, 128)), 128) + local maxp = vector.add(minp, vector.new(127, 127, 127)) + minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining) + if calls_remaining > 0 then + return + end + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local data = vm:get_data() + local param2data = vm:get_param2_data() + local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + local pixels = {} + local last_heightmap + for x = 1, 128 do + local map_x = minp.x - 1 + x + local heightmap = {} + for z = 1, 128 do + local map_z = minp.z - 1 + z + local color + for map_y = maxp.y, minp.y, -1 do + local index = area:index(map_x, map_y, map_z) + local c_id = data[index] + if c_id ~= c_air then + color = color_cache[c_id] + if color == nil then + local nodename = minetest.get_name_from_content_id(c_id) + local def = minetest.registered_nodes[nodename] + if def then + local texture + if def.palette then + texture = def.palette + elseif def.tiles then + texture = def.tiles[1] + if type(texture) == "table" then + texture = texture.name end end - - if color and color.palette then - color = color.palette[param2data[index] + 1] + if texture then + texture = texture:match("([^=^%^]-([^.]+))$"):split("^")[1] + end + if def.palette then + local palette = palettes[texture] + color = palette and {palette = palette} else - color_cache[c_id] = color or false + color = texture_colors[texture] end - - if color and last_heightmap then - local last_height = last_heightmap[z] - if last_height < map_y then - color = { - math.min(255, color[1] + 16), - math.min(255, color[2] + 16), - math.min(255, color[3] + 16), - } - elseif last_height > map_y then - color = { - math.max(0, color[1] - 16), - math.max(0, color[2] - 16), - math.max(0, color[3] - 16), - } - end - end - - height = map_y - break end end - heightmap[z] = height - pixels[z] = pixels[z] or {} - pixels[z][x] = color or {0, 0, 0} + + if color and color.palette then + color = color.palette[param2data[index] + 1] + else + color_cache[c_id] = color or false + end + + if color and last_heightmap then + local last_height = last_heightmap[z] + if last_height < map_y then + color = { + math.min(255, color[1] + 16), + math.min(255, color[2] + 16), + math.min(255, color[3] + 16), + } + elseif last_height > map_y then + color = { + math.max(0, color[1] - 16), + math.max(0, color[2] - 16), + math.max(0, color[3] - 16), + } + end + end + height = map_y + break end - last_heightmap = heightmap end - - tga_encoder.image(pixels):save(texture_path) - - creating_maps[texture] = false + heightmap[z] = height + pixels[z] = pixels[z] or {} + pixels[z][x] = color or {0, 0, 0} end - end) - end - itemstack:take_item() - if itemstack:is_empty() then - return new_map - else - local inv = placer:get_inventory() - if inv:room_for_item("main", new_map) then - inv:add_item("main", new_map) - else - minetest.add_item(placer:get_pos(), new_map) + last_heightmap = heightmap + end + tga_encoder.image(pixels):save(texture_path) + creating_maps[texture] = false + end) + return itemstack +end + +-- Turn empty map into filled map by rightclick +local make_filled_map = function(itemstack, placer, pointed_thing) + if minetest.settings:get_bool("enable_real_maps", true) then + local new_map = mcl_maps.create_map(placer:get_pos()) + itemstack:take_item() + if itemstack:is_empty() then + return new_map + else + local inv = placer:get_inventory() + if inv:room_for_item("main", new_map) then + inv:add_item("main", new_map) + else + minetest.add_item(placer:get_pos(), new_map) + end + return itemstack end - return itemstack end end