Merge pull request 'Add Real Maps' (#1700) from real_maps into master

Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/1700
This commit is contained in:
Elias Fleckenstein 2021-05-05 06:21:36 +00:00
commit 52ebc3343f
24 changed files with 528 additions and 137 deletions

@ -0,0 +1,4 @@
# tga_encoder
A TGA Encoder written in Lua without the use of external Libraries.
May be used as a Minetest mod.

@ -0,0 +1,78 @@
tga_encoder = {}
local image = setmetatable({}, {
__call = function(self, ...)
local t = setmetatable({}, {__index = self})
t:constructor(...)
return t
end,
})
function image:constructor(pixels)
self.data = ""
self.pixels = pixels
self.width = #pixels[1]
self.height = #pixels
self:encode()
end
function image:encode_colormap_spec()
self.data = self.data
.. string.char(0, 0) -- first entry index
.. string.char(0, 0) -- number of entries
.. string.char(0) -- bits per pixel
end
function image:encode_image_spec()
self.data = self.data
.. string.char(0, 0) -- X-origin
.. string.char(0, 0) -- Y-origin
.. string.char(self.width % 256, math.floor(self.width / 256)) -- width
.. string.char(self.height % 256, math.floor(self.height / 256)) -- height
.. string.char(24) -- pixel depth (RGB = 3 bytes = 24 bits)
.. string.char(0) -- image descriptor
end
function image:encode_header()
self.data = self.data
.. string.char(0) -- image id
.. string.char(0) -- color map type
.. string.char(2) -- image type (uncompressed true-color image = 2)
self:encode_colormap_spec() -- color map specification
self:encode_image_spec() -- image specification
end
function image:encode_data()
for _, row in ipairs(self.pixels) do
for _, pixel in ipairs(row) do
self.data = self.data
.. string.char(pixel[3], pixel[2], pixel[1])
end
end
end
function image:encode_footer()
self.data = self.data
.. string.char(0, 0, 0, 0) -- extension area offset
.. string.char(0, 0, 0, 0) -- developer area offset
.. "TRUEVISION-XFILE"
.. "."
.. string.char(0)
end
function image:encode()
self:encode_header() -- header
-- no color map and image id data
self:encode_data() -- encode data
-- no extension or developer area
self:encode_footer() -- footer
end
function image:save(filename)
local f = assert(io.open(filename, "w"))
f:write(self.data)
f:close()
end
tga_encoder.image = image

@ -0,0 +1,3 @@
name = tga_encoder
author = Fleckenstein
description = A TGA Encoder written in Lua without the use of external Libraries.

@ -195,7 +195,7 @@ local professions = {
{
-- TODO: replace with empty map
{ { "mcl_core:emerald", 7, 11}, { "mcl_maps:filled_map", 1, 1 } },
{ { "mcl_core:emerald", 7, 11}, { "mcl_maps:empty_map", 1, 1 } },
},
-- TODO: special maps

@ -11,6 +11,10 @@ tt.register_snippet = function(func)
table.insert(tt.registered_snippets, func)
end
tt.register_priority_snippet = function(func)
table.insert(tt.registered_snippets, 1, func)
end
dofile(minetest.get_modpath(minetest.get_current_modname()).."/snippets.lua")
-- Apply item description updates
@ -22,8 +26,6 @@ local function apply_snippets(desc, itemstring, toolcaps, itemstack)
local str, snippet_color = tt.registered_snippets[s](itemstring, toolcaps, itemstack)
if snippet_color == nil then
snippet_color = tt.COLOR_DEFAULT
elseif snippet_color == false then
snippet_color = false
end
if str then
if first then

@ -361,4 +361,4 @@ minetest.register_on_joinplayer(mcl_enchanting.initialize_player)
minetest.register_on_player_receive_fields(mcl_enchanting.handle_formspec_fields)
minetest.register_allow_player_inventory_action(mcl_enchanting.allow_inventory_action)
minetest.register_on_player_inventory_action(mcl_enchanting.on_inventory_action)
table.insert(tt.registered_snippets, 1, mcl_enchanting.enchantments_snippet)
tt.register_priority_snippet(mcl_enchanting.enchantments_snippet)

@ -53,6 +53,24 @@ minetest.register_entity("mcl_itemframes:item",{
end,
})
minetest.register_entity("mcl_itemframes:map", {
initial_properties = {
visual = "upright_sprite",
visual_size = {x = 1, y = 1},
pointable = false,
physical = false,
collide_with_objects = false,
textures = {"blank.png"},
},
on_activate = function(self, staticdata)
self.id = staticdata
self.object:set_properties({textures = {mcl_maps.load_map(self.id)}})
end,
get_staticdata = function(self)
return self.id
end,
})
local facedir = {}
facedir[0] = {x=0,y=0,z=1}
@ -61,13 +79,10 @@ facedir[2] = {x=0,y=0,z=-1}
facedir[3] = {x=-1,y=0,z=0}
local remove_item_entity = function(pos, node)
local objs = nil
if node.name == "mcl_itemframes:item_frame" then
objs = minetest.get_objects_inside_radius(pos, .5)
end
if objs then
for _, obj in ipairs(objs) do
if obj and obj:get_luaentity() and obj:get_luaentity().name == "mcl_itemframes:item" then
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do
local entity = obj:get_luaentity()
if entity and (entity.name == "mcl_itemframes:item" or entity.name == "mcl_itemframes:map") then
obj:remove()
end
end
@ -89,6 +104,9 @@ local update_item_entity = function(pos, node, param2)
pos.y = pos.y + posad.y*6.5/16
pos.z = pos.z + posad.z*6.5/16
end
local yaw = math.pi*2 - param2 * math.pi/2
local map_id = item:get_meta():get_string("mcl_maps:id")
if map_id == "" then
local e = minetest.add_entity(pos, "mcl_itemframes:item")
local lua = e:get_luaentity()
lua._nodename = node.name
@ -99,15 +117,14 @@ local update_item_entity = function(pos, node, param2)
else
lua._texture = itemname
local def = minetest.registered_items[itemname]
if def and def.wield_scale then
lua._scale = def.wield_scale.x
else
lua._scale = 1
end
lua._scale = def and def.wield_scale and def.wield_scale.x or 1
end
lua:_update_texture()
if node.name == "mcl_itemframes:item_frame" then
local yaw = math.pi*2 - param2 * math.pi/2
e:set_yaw(yaw)
end
else
local e = minetest.add_entity(pos, "mcl_itemframes:map", map_id)
e:set_yaw(yaw)
end
end

@ -1,3 +1,3 @@
name = mcl_itemframes
depends = mcl_core, mcl_sounds, mcl_compass
depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps
optional_depends = screwdriver

File diff suppressed because one or more lines are too long

@ -1,8 +1,158 @@
local S = minetest.get_translator("mcl_maps")
mcl_maps = {}
-- 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")
local S = minetest.get_translator("mcl_maps")
local storage = minetest.get_mod_storage()
local modpath = minetest.get_modpath("mcl_maps")
local worldpath = minetest.get_worldpath()
local map_textures_path = worldpath .. "/mcl_maps/"
local last_finished_id = storage:get_int("next_id") - 1
minetest.mkdir(map_textures_path)
local function load_json_file(name)
local file = assert(io.open(modpath .. "/" .. name .. ".json", "r"))
local data = minetest.parse_json(file:read())
file:close()
return data
end
local texture_colors = load_json_file("colors")
local palettes = load_json_file("palettes")
local color_cache = {}
local creating_maps = {}
local loaded_maps = {}
local c_air = minetest.get_content_id("air")
function mcl_maps.create_map(pos)
local minp = vector.multiply(vector.floor(vector.divide(pos, 128)), 128)
local maxp = vector.add(minp, vector.new(127, 127, 127))
local itemstack = ItemStack("mcl_maps:filled_map")
local meta = itemstack:get_meta()
local next_id = storage:get_int("next_id")
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:minp", minetest.pos_to_string(minp))
meta:set_string("mcl_maps:maxp", minetest.pos_to_string(maxp))
tt.reload_itemstack_description(itemstack)
creating_maps[id] = true
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, height
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
end
end
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
end
heightmap[z] = height or minp.y
pixels[z] = pixels[z] or {}
pixels[z][x] = color or {0, 0, 0}
end
last_heightmap = heightmap
end
tga_encoder.image(pixels):save(map_textures_path .. "mcl_maps_map_texture_" .. id .. ".tga")
creating_maps[id] = nil
end)
return itemstack
end
function mcl_maps.load_map(id)
if id == "" or creating_maps[id] then
return
end
local texture = "mcl_maps_map_texture_" .. id .. ".tga"
if not loaded_maps[id] then
loaded_maps[id] = true
minetest.dynamic_add_media(map_textures_path .. texture, function() end)
end
return texture
end
function mcl_maps.load_map_item(itemstack)
return mcl_maps.load_map(itemstack:get_meta():get_string("mcl_maps:id"))
end
local function fill_map(itemstack, placer, pointed_thing)
local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing)
if new_stack then
return new_stack
end
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
@ -15,75 +165,74 @@ local make_filled_map = function(itemstack, placer, pointed_thing)
end
return itemstack
end
end
end
minetest.register_craftitem("mcl_maps:empty_map", {
description = S("Empty Map"),
_doc_items_longdesc = S("Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used."),
_doc_items_usagehelp = S("Rightclick to start using the map (which can't be stacked anymore)."),
_doc_items_usagehelp = S("Rightclick to create a filled map (which can't be stacked anymore)."),
inventory_image = "mcl_maps_map_empty.png",
groups = { not_in_creative_inventory = 1 },
on_place = make_filled_map,
on_secondary_use = make_filled_map,
on_place = fill_map,
on_secondary_use = fill_map,
stack_max = 64,
})
mcl_wip.register_wip_item("mcl_maps:empty_map")
local function has_item_in_hotbar(player, item)
-- Requirement: player carries the tool in the hotbar
local inv = player:get_inventory()
local hotbar = player:hud_get_hotbar_itemcount()
for i=1, hotbar do
if inv:get_stack("main", i):get_name() == item then
return true
end
end
return false
end
-- Checks if player is still allowed to display the minimap
local function update_minimap(player)
local creative = minetest.is_creative_enabled(player:get_player_name())
if creative then
player:hud_set_flags({minimap=true, minimap_radar = true})
else
if has_item_in_hotbar(player, "mcl_maps:filled_map") then
player:hud_set_flags({minimap = true, minimap_radar = false})
else
player:hud_set_flags({minimap = false, minimap_radar = false})
end
end
end
-- Remind player how to use the minimap correctly
local function use_minimap(itemstack, player, pointed_thing)
if player and player:is_player() then
update_minimap(player)
minetest.chat_send_player(player:get_player_name(), S("Use the minimap key to show the map."))
end
end
-- Enables minimap if carried in hotbar.
-- If this item is NOT in the hotbar, the minimap is unavailable
-- Note: This is not at all like Minecraft right now. Minetest's minimap is pretty overpowered, it
-- has a very greatly zoomed-out version and even a radar mode
minetest.register_craftitem("mcl_maps:filled_map", {
local filled_def = {
description = S("Map"),
_tt_help = S("Enables minimap"),
_doc_items_longdesc = S("Maps show your surroundings as you explore the world."),
_doc_items_usagehelp = S("Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).").."\n"..
S("In Creative Mode, you don't need this item; the minimap is always available."),
groups = { tool = 1 },
_tt_help = S("Shows a map image."),
_doc_items_longdesc = S("When created, the map saves the nearby area as an image that can be viewed any time by holding the map."),
_doc_items_usagehelp = S("Hold the map in your hand. This will display a map on your screen."),
inventory_image = "mcl_maps_map_filled.png^(mcl_maps_map_filled_markings.png^[colorize:#000000)",
stack_max = 1,
stack_max = 64,
groups = {not_in_creative_inventory = 1, filled_map = 1, tool = 1},
}
on_use = use_minimap,
on_secondary_use = use_minimap,
})
minetest.register_craftitem("mcl_maps:filled_map", filled_def)
local filled_wield_def = table.copy(filled_def)
filled_wield_def.use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false
filled_wield_def.visual_scale = 1
filled_wield_def.wield_scale = {x = 1, y = 1, z = 1}
filled_wield_def.paramtype = "light"
filled_wield_def.drawtype = "mesh"
filled_wield_def.node_placement_prediction = ""
filled_wield_def.range = minetest.registered_items[""].range
filled_wield_def.on_place = mcl_util.call_on_rightclick
for _, texture in pairs(mcl_skins.list) do
local def = table.copy(filled_wield_def)
def.tiles = {texture .. ".png"}
def.mesh = "mcl_meshhand.b3d"
def._mcl_hand_id = texture
minetest.register_node("mcl_maps:filled_map_" .. texture, def)
local female_def = table.copy(def)
female_def.mesh = "mcl_meshhand_female.b3d"
female_def._mcl_hand_id = texture .. "_female"
minetest.register_node("mcl_maps:filled_map_" .. texture .. "_female", female_def)
end
local old_add_item = minetest.add_item
function minetest.add_item(pos, stack)
stack = ItemStack(stack)
if minetest.get_item_group(stack:get_name(), "filled_map") > 0 then
stack:set_name("mcl_maps:filled_map")
end
return old_add_item(pos, stack)
end
tt.register_priority_snippet(function(itemstring, _, itemstack)
if itemstack and minetest.get_item_group(itemstring, "filled_map") > 0 then
local id = itemstack:get_meta():get_string("mcl_maps:id")
if id ~= "" then
return "#" .. id, mcl_colors.GRAY
end
end
end)
minetest.register_craft({
output = "mcl_maps:filled_map",
output = "mcl_maps:empty_map",
recipe = {
{ "mcl_core:paper", "mcl_core:paper", "mcl_core:paper" },
{ "mcl_core:paper", "group:compass", "mcl_core:paper" },
@ -91,20 +240,104 @@ minetest.register_craft({
}
})
minetest.register_craft({
type = "shapeless",
output = "mcl_maps:filled_map 2",
recipe = {"group:filled_map", "mcl_maps:empty_map"},
})
local function on_craft(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() == "mcl_maps:filled_map" then
for _, stack in pairs(old_craft_grid) do
if minetest.get_item_group(stack:get_name(), "filled_map") > 0 then
itemstack:get_meta():from_table(stack:get_meta():to_table())
return itemstack
end
end
end
end
minetest.register_on_craft(on_craft)
minetest.register_craft_predict(on_craft)
local maps = {}
local huds = {}
minetest.register_on_joinplayer(function(player)
update_minimap(player)
local map_def = {
hud_elem_type = "image",
text = "blank.png",
position = {x = 0.75, y = 0.8},
alignment = {x = 0, y = -1},
offset = {x = 0, y = 0},
scale = {x = 2, y = 2},
}
local marker_def = table.copy(map_def)
marker_def.alignment = {x = 0, y = 0}
huds[player] = {
map = player:hud_add(map_def),
marker = player:hud_add(marker_def),
}
end)
local updatetimer = 0
if not minetest.is_creative_enabled("") then
minetest.register_globalstep(function(dtime)
updatetimer = updatetimer + dtime
if updatetimer > 0.1 then
local players = minetest.get_connected_players()
for i=1, #players do
update_minimap(players[i])
minetest.register_on_leaveplayer(function(player)
maps[player] = nil
huds[player] = nil
end)
minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do
local wield = player:get_wielded_item()
local texture = mcl_maps.load_map_item(wield)
local hud = huds[player]
if texture then
local wield_def = wield:get_definition()
local hand_def = player:get_inventory():get_stack("hand", 1):get_definition()
if hand_def and wield_def and hand_def._mcl_hand_id ~= wield_def._mcl_hand_id then
wield:set_name("mcl_maps:filled_map_" .. hand_def._mcl_hand_id)
player:set_wielded_item(wield)
end
updatetimer = updatetimer - dtime
if texture ~= maps[player] then
player:hud_change(hud.map, "text", "[combine:140x140:0,0=mcl_maps_map_background.png:6,6=" .. texture)
maps[player] = texture
end
end)
end
local pos = vector.round(player:get_pos())
local meta = wield:get_meta()
local minp = minetest.string_to_pos(meta:get_string("mcl_maps:minp"))
local maxp = minetest.string_to_pos(meta:get_string("mcl_maps:maxp"))
local marker = "mcl_maps_player_arrow.png"
if pos.x < minp.x then
marker = "mcl_maps_player_dot.png"
pos.x = minp.x
elseif pos.x > maxp.x then
marker = "mcl_maps_player_dot.png"
pos.x = maxp.x
end
if pos.z < minp.z then
marker = "mcl_maps_player_dot.png"
pos.z = minp.z
elseif pos.z > maxp.z then
marker = "mcl_maps_player_dot.png"
pos.z = maxp.z
end
if marker == "mcl_maps_player_arrow.png" then
local yaw = (math.floor(player:get_look_horizontal() * 180 / math.pi / 90 + 0.5) % 4) * 90
marker = marker .. "^[transformR" .. yaw
end
player:hud_change(hud.marker, "text", marker)
player:hud_change(hud.marker, "offset", {x = (6 - 140 / 2 + pos.x - minp.x) * 2, y = (6 - 140 + maxp.z - pos.z) * 2})
elseif maps[player] then
player:hud_change(hud.map, "text", "blank.png")
player:hud_change(hud.marker, "text", "blank.png")
maps[player] = nil
end
end
end)

@ -1,10 +1,8 @@
# textdomain: mcl_maps
Empty Map=Leere Karte
Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Leere Karten sind als Karten nicht nützlich, aber sie können gestapelt werden und zu benutzbaren Karten umgewandelt werden.
Rightclick to start using the map (which can't be stacked anymore).=Rechtsklick, um zu beginnen, die Karte zu benutzen. Sie kann dann nicht mehr gestapelt werden.
Rightclick to create a filled map (which can't be stacked anymore).=Rechtsklick, um die Karte zu füllen. Sie kann dann nicht mehr gestapelt werden.
Map=Karte
Maps show your surroundings as you explore the world.=Karten zeigen Ihre Umgebung, während Sie die Welt erkunden.
Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Halten Sie die Karte in einen beliebigen Platz in der Schnellleiste. Damit können Sie jetzt die Übersichtskarte aktivieren, indem Sie die Taste zum Umschalten der Karte drücken (siehe Tastenbelegung).
In Creative Mode, you don't need this item; the minimap is always available.=Im Kreativmodus brauchen Sie diesen Gegenstand nicht; die Übersichtskarte ist immer verfügbar.
Enables minimap=Aktiviert Übersichtskarte
Use the minimap key to show the map.=Taste „Karte an/aus“ benutzen, um die Karte zu betrachten.
Shows a map image.=Zeigt ein Kartenbild.
When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=Beim Erstellen speichert die Karte die Gegend in der Nähe als ein Bild, dass jederzeit durch halten der Karte angesehen werden kann.
Hold the map in your hand. This will display a map on your screen.=Halten Sie die Karte in Ihrer Hand. Eine Karte wird auf Ihrem Bildschirm angezeigt werden.

@ -3,6 +3,3 @@ Empty Map=Mapa vacio
Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Los mapas vacíos no son útiles como mapas, pero se pueden apilar y convertir en mapas que se pueden usar.
Rightclick to start using the map (which can't be stacked anymore).=Haga clic derecho para comenzar a usar el mapa (que ya no se puede apilar).
Map=Mapa
Maps show your surroundings as you explore the world.=Los mapas muestran tu entorno mientras exploras el mundo.
Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Mantenga el mapa en cualquiera de las ranuras de la barra de acceso directo. Esto le permite acceder al minimapa presionando la tecla del minimapa (consulte la configuración de los controles).
In Creative Mode, you don't need this item; the minimap is always available.=En el modo creativo, no necesita este elemento; El minimapa siempre está disponible.

@ -3,8 +3,3 @@ Empty Map=Carte Vierge
Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Les cartes vierges ne sont pas utiles en tant que cartes, mais elles peuvent être empilées et transformées en cartes utilisables.
Rightclick to start using the map (which can't be stacked anymore).=Clic droit pour commencer à utiliser la carte (qui ne peut plus être empilée).
Map=Carte
Maps show your surroundings as you explore the world.=Les cartes montrent votre environnement lorsque vous explorez le monde.
Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Tenez la carte dans l'un des emplacements de la barre de raccourci. Cela vous permet d'accéder à la mini-carte en appuyant sur la touche de la mini-carte (voir les paramètres des commandes).
In Creative Mode, you don't need this item; the minimap is always available.=En mode créatif, vous n'avez pas besoin de cet élément; la minicarte est toujours disponible.
Enables minimap=Active la minicarte
Use the minimap key to show the map.=Utilisez la touche mini-carte pour afficher la carte.

@ -3,8 +3,3 @@ Empty Map=Пустая карта
Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Пустые карты не могут использоваться в качестве карт, но могут складываться в стопки, а также могут быть превращены в полноценные карты.
Rightclick to start using the map (which can't be stacked anymore).=Кликните правой, чтобы начать использовать карту (её больше нельзя будет уложить в стопку).
Map=Карта
Maps show your surroundings as you explore the world.=Карты показывают ваше окружение, когда вы изучаете мир.
Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Поместите карту в один из отсеков панели быстрого доступа. Это позволит вам вызывать миникарту нажатием клавиши [Миникарта] (см. настройки управления).
In Creative Mode, you don't need this item; the minimap is always available.=Этот предмет не нужен в творческом режиме; там миникарта всегда доступна и так.
Enables minimap=Включает миникарту
Use the minimap key to show the map.=Используйте клавишу [Миникарта] для отображения карты.

@ -1,10 +1,8 @@
# textdomain: mcl_maps
Empty Map=
Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=
Rightclick to start using the map (which can't be stacked anymore).=
Rightclick to create a filled map (which can't be stacked anymore).=
Map=
Maps show your surroundings as you explore the world.=
Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=
In Creative Mode, you don't need this item; the minimap is always available.=
Enables minimap=
Use the minimap key to show the map.=
Shows a map image.=
When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=
Hold the map in your hand. This will display a map on your screen.=

@ -1,2 +1,2 @@
name = mcl_maps
depends = mcl_wip
depends = mcl_core, mcl_flowers, tga_encoder, tt, mcl_colors, mcl_skins, mcl_util

@ -0,0 +1 @@
{"mcl_core_palette_grass.png": [[109, 196, 117], [159, 193, 114], [118, 177, 120], [118, 177, 120], [107, 186, 107], [118, 177, 120], [92, 182, 119], [92, 182, 119], [92, 182, 119], [92, 182, 119], [118, 177, 120], [109, 196, 117], [35, 175, 105], [94, 190, 107], [94, 190, 107], [94, 190, 107], [94, 190, 107], [159, 193, 114], [76, 176, 84], [164, 150, 110], [164, 150, 110], [164, 150, 110], [164, 150, 110], [159, 193, 114], [93, 181, 76], [93, 181, 76], [93, 181, 76], [93, 181, 76], [76, 118, 60], [94, 190, 107], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117], [109, 196, 117]]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -34,6 +34,7 @@ for _,texture in pairs(list) do
end,
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
range = def.range,
_mcl_hand_id = texture,
})
minetest.register_node("mcl_meshhand:"..texture.. "_female", {
@ -57,6 +58,7 @@ for _,texture in pairs(list) do
end,
groups = { dig_immediate = 3, not_in_creative_inventory = 1 },
range = def.range,
_mcl_hand_id = texture .. "_female",
})
end

@ -150,3 +150,6 @@ basic_pseudobiome_villages (Enables very basic, and experimental "pseudobiome-ba
# If enabled, will run an LBM to fix the top 1/2 of double plants in mcimported worlds; defaults to true.
fix_doubleplants (Mcimport double plant fixes) bool true
# Allow players to create Minecraft-like maps.
enable_real_maps (Enable Real Maps) bool true

@ -196,6 +196,11 @@ def convert_textures():
if verbose:
print(src_file + "" + dst_file)
# Convert map background
map_background_file = tex_dir + "/map/map_background.png"
if os.path.isfile(map_background_file):
os.system("convert " + map_background_file + " -interpolate Integer -filter point -resize \"140x140\" " + target_dir("/mods/ITEMS/mcl_maps/textures") + "/mcl_maps_map_background.png")
# Convert armor textures (requires ImageMagick)
armor_files = [
[ tex_dir + "/models/armor/leather_layer_1.png", tex_dir + "/models/armor/leather_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_leather.png", "mcl_armor_chestplate_leather.png", "mcl_armor_leggings_leather.png", "mcl_armor_boots_leather.png" ],

@ -0,0 +1,59 @@
import json, os
from PIL import Image
colors = {}
palettes = {}
for root, directories, files in os.walk(".."):
if root.endswith("/textures"):
for name in files:
try:
img = Image.open(os.path.join(root, name)).convert("RGBA")
pixels = img.load()
if "palette" in name:
palette = []
for y in range(0, img.size[1]):
for x in range(0, img.size[0]):
r, g, b, a = pixels[x, y]
palette.append((r, g, b))
palettes[name] = palette
else:
r_total = 0
g_total = 0
b_total = 0
count = 0
for x in range(0, img.size[0]):
for y in range(0, img.size[1]):
r, g, b, a = pixels[x, y]
if a > 0:
r_total += r / 255 * a
g_total += g / 255 * a
b_total += b / 255 * a
count += a / 255
average_color = None
if count > 0:
average_color = (int(r_total / count), int(g_total / count), int(b_total / count))
else:
average_color = (255, 255, 255)
colors[name] = average_color
img.close()
except IOError:
pass
path = "../mods/ITEMS/mcl_maps/"
with open(path + "colors.json", "w") as colorfile:
colorfile.write(json.dumps(colors))
with open(path + "palettes.json", "w") as palettefile:
palettefile.write(json.dumps(palettes))