This commit is contained in:
root 2021-12-11 12:24:24 +01:00
parent 8796c019db
commit 8069e4cffd
1116 changed files with 7887 additions and 454 deletions

View file

@ -0,0 +1,18 @@
unused_args = false
globals = {
"biome_lib"
}
read_globals = {
-- Stdlib
string = {fields = {"split", "trim"}},
table = {fields = {"copy"}},
-- Minetest
"minetest", "vector",
"dump", "PerlinNoise",
-- mods
"default",
}

View file

@ -14,10 +14,10 @@ biome_lib.fertile_perlin_octaves = 3
biome_lib.fertile_perlin_persistence = 0.6 biome_lib.fertile_perlin_persistence = 0.6
biome_lib.fertile_perlin_scale = 100 biome_lib.fertile_perlin_scale = 100
local temperature_seeddiff = 112 local temp_seeddiff = 112
local temperature_octaves = 3 local temp_octaves = 3
local temperature_persistence = 0.5 local temp_persistence = 0.5
local temperature_scale = 150 local temp_scale = 150
local humidity_seeddiff = 9130 local humidity_seeddiff = 9130
local humidity_octaves = 3 local humidity_octaves = 3
@ -35,19 +35,15 @@ biome_lib.air = {name = "air"}
-- the mapgen rarely creates useful surfaces outside this range, but mods can -- the mapgen rarely creates useful surfaces outside this range, but mods can
-- still specify a wider range if needed. -- still specify a wider range if needed.
biome_lib.mapgen_elevation_limit = { ["min"] = -16, ["max"] = 48 } biome_lib.mapgen_elevation_limit = { ["min"] = -16, ["max"] = 48 }
--PerlinNoise(seed, octaves, persistence, scale) --PerlinNoise(seed, octaves, persistence, scale)
biome_lib.perlin_temperature = PerlinNoise(temperature_seeddiff, temperature_octaves, temperature_persistence, temperature_scale) biome_lib.perlin_temperature = PerlinNoise(temp_seeddiff, temp_octaves, temp_persistence, temp_scale)
biome_lib.perlin_humidity = PerlinNoise(humidity_seeddiff, humidity_octaves, humidity_persistence, humidity_scale) biome_lib.perlin_humidity = PerlinNoise(humidity_seeddiff, humidity_octaves, humidity_persistence, humidity_scale)
-- Local functions -- Local functions
local function tableize(s)
return string.split(string.trim(string.gsub(s, " ", "")))
end
function biome_lib.dbg(msg, level) function biome_lib.dbg(msg, level)
local l = tonumber(level) or 0 local l = tonumber(level) or 0
if biome_lib.debug_log_level >= l then if biome_lib.debug_log_level >= l then
@ -122,19 +118,21 @@ end
function biome_lib.register_on_generate(biomedef, nodes_or_function_or_model) function biome_lib.register_on_generate(biomedef, nodes_or_function_or_model)
-- if calling code passes an undefined node for a surface or -- if calling code passes an undefined node for a surface or
-- as a node to be spawned, don't register an action for it. -- as a node to be spawned, don't register an action for it.
if type(nodes_or_function_or_model) == "string" if type(nodes_or_function_or_model) == "string"
and string.find(nodes_or_function_or_model, ":") and string.find(nodes_or_function_or_model, ":")
and not minetest.registered_nodes[nodes_or_function_or_model] then and not minetest.registered_nodes[nodes_or_function_or_model] then
biome_lib.dbg("Warning: Ignored registration for undefined spawn node: "..dump(nodes_or_function_or_model), 2) biome_lib.dbg("Warning: Ignored registration for undefined spawn node: "..
dump(nodes_or_function_or_model), 2)
return return
end end
if type(nodes_or_function_or_model) == "string" if type(nodes_or_function_or_model) == "string"
and not string.find(nodes_or_function_or_model, ":") then and not string.find(nodes_or_function_or_model, ":") then
biome_lib.dbg("Warning: Registered function call using deprecated string method: "..dump(nodes_or_function_or_model), 2) biome_lib.dbg("Warning: Registered function call using deprecated string method: "..
dump(nodes_or_function_or_model), 2)
end end
biome_lib.mapgen_elevation_limit.min = math.min(biomedef.min_elevation or 0, biome_lib.mapgen_elevation_limit.min) biome_lib.mapgen_elevation_limit.min = math.min(biomedef.min_elevation or 0, biome_lib.mapgen_elevation_limit.min)
@ -143,13 +141,14 @@ function biome_lib.register_on_generate(biomedef, nodes_or_function_or_model)
local decor_def = biome_lib.can_use_decorations(biomedef, nodes_or_function_or_model) local decor_def = biome_lib.can_use_decorations(biomedef, nodes_or_function_or_model)
if decor_def then if decor_def then
biome_lib.dbg("Using engine decorations instead of biome_lib functions for node(s): "..dump(nodes_or_function_or_model), 3) biome_lib.dbg("Using engine decorations instead of biome_lib functions for node(s): "..
dump(nodes_or_function_or_model), 3)
biome_lib.registered_decorations[#biome_lib.registered_decorations + 1] = nodes_or_function_or_model biome_lib.registered_decorations[#biome_lib.registered_decorations + 1] = nodes_or_function_or_model
minetest.register_decoration(decor_def) minetest.register_decoration(decor_def)
return return
elseif biomedef.check_air == false then elseif biomedef.check_air == false then
biome_lib.dbg("Register no-air-check mapgen hook: "..dump(nodes_or_function_or_model), 3) biome_lib.dbg("Register no-air-check mapgen hook: "..dump(nodes_or_function_or_model), 3)
biome_lib.actionslist_no_aircheck[#biome_lib.actionslist_no_aircheck + 1] = { biomedef, nodes_or_function_or_model } biome_lib.actionslist_no_aircheck[#biome_lib.actionslist_no_aircheck + 1] = {biomedef, nodes_or_function_or_model}
local s = biomedef.surface local s = biomedef.surface
if type(s) == "string" then if type(s) == "string" then
if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then
@ -161,7 +160,7 @@ function biome_lib.register_on_generate(biomedef, nodes_or_function_or_model)
end end
else else
for i = 1, #biomedef.surface do for i = 1, #biomedef.surface do
local s = biomedef.surface[i] s = biomedef.surface[i]
if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then
if not search_table(biome_lib.surfaceslist_no_aircheck, s) then if not search_table(biome_lib.surfaceslist_no_aircheck, s) then
biome_lib.surfaceslist_no_aircheck[#biome_lib.surfaceslist_no_aircheck + 1] = s biome_lib.surfaceslist_no_aircheck[#biome_lib.surfaceslist_no_aircheck + 1] = s
@ -185,7 +184,7 @@ function biome_lib.register_on_generate(biomedef, nodes_or_function_or_model)
end end
else else
for i = 1, #biomedef.surface do for i = 1, #biomedef.surface do
local s = biomedef.surface[i] s = biomedef.surface[i]
if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then
if not search_table(biome_lib.surfaceslist_aircheck, s) then if not search_table(biome_lib.surfaceslist_aircheck, s) then
biome_lib.surfaceslist_aircheck[#biome_lib.surfaceslist_aircheck + 1] = s biome_lib.surfaceslist_aircheck[#biome_lib.surfaceslist_aircheck + 1] = s
@ -214,7 +213,7 @@ local function populate_single_surface(biome, pos, perlin_fertile_area, checkair
and fertility > biome.plantlife_limit and fertility > biome.plantlife_limit
and temperature <= biome.temp_min and temperature >= biome.temp_max and temperature <= biome.temp_min and temperature >= biome.temp_max
and humidity <= biome.humidity_min and humidity >= biome.humidity_max and humidity <= biome.humidity_min and humidity >= biome.humidity_max
if not pos_biome_ok then if not pos_biome_ok then
return -- Y position mismatch, outside of biome return -- Y position mismatch, outside of biome
end end
@ -229,7 +228,7 @@ local function populate_single_surface(biome, pos, perlin_fertile_area, checkair
else else
if string.find(biome_surfaces_string, "group:") then if string.find(biome_surfaces_string, "group:") then
for j = 1, #biome.surface do for j = 1, #biome.surface do
if string.find(biome.surface[j], "^group:") if string.find(biome.surface[j], "^group:")
and minetest.get_item_group(dest_node.name, biome.surface[j]) then and minetest.get_item_group(dest_node.name, biome.surface[j]) then
surface_ok = true surface_ok = true
break break
@ -241,7 +240,7 @@ local function populate_single_surface(biome, pos, perlin_fertile_area, checkair
minetest.get_node({ x = pos.x, y = pos.y-biome.depth-1, z = pos.z }).name) then minetest.get_node({ x = pos.x, y = pos.y-biome.depth-1, z = pos.z }).name) then
surface_ok = true surface_ok = true
end end
if not surface_ok then if not surface_ok then
return -- Surface does not match the given node group/name return -- Surface does not match the given node group/name
end end
@ -269,7 +268,7 @@ local function populate_single_surface(biome, pos, perlin_fertile_area, checkair
if biome.near_nodes and if biome.near_nodes and
#minetest.find_nodes_in_area( #minetest.find_nodes_in_area(
{x=pos.x-biome.near_nodes_size, y=pos.y-biome.near_nodes_vertical, z=pos.z-biome.near_nodes_size}, {x=pos.x-biome.near_nodes_size, y=pos.y-biome.near_nodes_vertical, z=pos.z-biome.near_nodes_size},
{x=pos.x+biome.near_nodes_size, y=pos.y+biome.near_nodes_vertical, z=pos.z+biome.near_nodes_size}, {x=pos.x+biome.near_nodes_size, y=pos.y+biome.near_nodes_vertical, z=pos.z+biome.near_nodes_size},
biome.near_nodes biome.near_nodes
) < biome.near_nodes_count then ) < biome.near_nodes_count then
return -- Long distance neighbours do not match return -- Long distance neighbours do not match
@ -287,7 +286,8 @@ function biome_lib.populate_surfaces(b, nodes_or_function_or_model, snodes, chec
-- filter stage 1 - find nodes from the supplied surfaces that are within the current biome. -- filter stage 1 - find nodes from the supplied surfaces that are within the current biome.
local in_biome_nodes = {} local in_biome_nodes = {}
local perlin_fertile_area = minetest.get_perlin(biome.seed_diff, biome_lib.fertile_perlin_octaves, biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale) local perlin_fertile_area = minetest.get_perlin(biome.seed_diff, biome_lib.fertile_perlin_octaves,
biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale)
for i = 1, #snodes do for i = 1, #snodes do
local pos = vector.new(snodes[i]) local pos = vector.new(snodes[i])
@ -309,12 +309,34 @@ function biome_lib.populate_surfaces(b, nodes_or_function_or_model, snodes, chec
local spawned = false local spawned = false
while tries < 2 and not spawned do while tries < 2 and not spawned do
local pos = in_biome_nodes[math.random(1, num_in_biome_nodes)] local pos = in_biome_nodes[math.random(1, num_in_biome_nodes)]
if biome.spawn_replace_node then
local will_place = true
local fdir = nil
if biome.random_facedir then
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
end
if biome.spawn_on_side then
local onside = biome_lib.find_open_side(pos)
if onside then
pos = onside.newpos
fdir = onside.facedir
else
will_place = false
end
elseif biome.spawn_on_bottom then
if minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
pos.y = pos.y - 1
else
will_place = false
end
elseif biome.spawn_replace_node then
pos.y = pos.y-1 pos.y = pos.y-1
end end
local p_top = { x = pos.x, y = pos.y + 1, z = pos.z } local p_top = { x = pos.x, y = pos.y + 1, z = pos.z }
if not (biome.avoid_nodes and biome.avoid_radius if will_place and not (biome.avoid_nodes and biome.avoid_radius
and minetest.find_node_near(p_top, biome.avoid_radius and minetest.find_node_near(p_top, biome.avoid_radius
+ math.random(-1.5,2), biome.avoid_nodes)) then + math.random(-1.5,2), biome.avoid_nodes)) then
if biome.delete_above then if biome.delete_above then
@ -346,34 +368,30 @@ function biome_lib.populate_surfaces(b, nodes_or_function_or_model, snodes, chec
biome_lib.dbg("An L-tree was spawned at "..minetest.pos_to_string(p_top), 4) biome_lib.dbg("An L-tree was spawned at "..minetest.pos_to_string(p_top), 4)
spawned = true spawned = true
else else
local fdir = nil
if biome.random_facedir then
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
end
local n=nodes_or_function_or_model[math.random(#nodes_or_function_or_model)] local n=nodes_or_function_or_model[math.random(#nodes_or_function_or_model)]
minetest.swap_node(p_top, { name = n, param2 = fdir }) minetest.swap_node(p_top, { name = n, param2 = fdir })
biome_lib.dbg("Node \""..n.."\" was randomly picked from a list and placed at "..minetest.pos_to_string(p_top), 4) biome_lib.dbg("Node \""..n.."\" was randomly picked from a list and placed at "..
minetest.pos_to_string(p_top), 4)
spawned = true spawned = true
end end
elseif objtype == "string" and elseif objtype == "string" and
minetest.registered_nodes[nodes_or_function_or_model] then minetest.registered_nodes[nodes_or_function_or_model] then
local fdir = nil
if biome.random_facedir then
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
end
minetest.swap_node(p_top, { name = nodes_or_function_or_model, param2 = fdir }) minetest.swap_node(p_top, { name = nodes_or_function_or_model, param2 = fdir })
biome_lib.dbg("Node \""..nodes_or_function_or_model.."\" was placed at "..minetest.pos_to_string(p_top), 4) biome_lib.dbg("Node \""..nodes_or_function_or_model.."\" was placed at "..
minetest.pos_to_string(p_top), 4)
spawned = true spawned = true
elseif objtype == "function" then elseif objtype == "function" then
nodes_or_function_or_model(pos) nodes_or_function_or_model(pos, fdir)
biome_lib.dbg("A function was run on surface node at "..minetest.pos_to_string(pos), 4) biome_lib.dbg("A function was run on surface node at "..minetest.pos_to_string(pos), 4)
spawned = true spawned = true
elseif objtype == "string" and pcall(loadstring(("return %s(...)"): elseif objtype == "string" and pcall(loadstring(("return %s(...)"):
format(nodes_or_function_or_model)),pos) then format(nodes_or_function_or_model)),pos) then
spawned = true spawned = true
biome_lib.dbg("An obsolete string-specified function was run on surface node at "..minetest.pos_to_string(p_top), 4) biome_lib.dbg("An obsolete string-specified function was run on surface node at "..
minetest.pos_to_string(p_top), 4)
else else
biome_lib.dbg("Warning: Ignored invalid definition for object "..dump(nodes_or_function_or_model).." that was pointed at {"..dump(pos).."}", 2) biome_lib.dbg("Warning: Ignored invalid definition for object "..
dump(nodes_or_function_or_model).." that was pointed at {"..dump(pos).."}", 2)
end end
else else
tries = tries + 1 tries = tries + 1
@ -393,7 +411,7 @@ local function confirm_block_surroundings(p)
for x = -32,32,64 do -- step of 64 causes it to only check the 8 corner blocks for x = -32,32,64 do -- step of 64 causes it to only check the 8 corner blocks
for y = -32,32,64 do for y = -32,32,64 do
for z = -32,32,64 do for z = -32,32,64 do
local n=minetest.get_node_or_nil({x=p.x + x, y=p.y + y, z=p.z + z}) n = minetest.get_node_or_nil({x=p.x + x, y=p.y + y, z=p.z + z})
if not n or n.name == "ignore" then return false end if not n or n.name == "ignore" then return false end
end end
end end
@ -427,7 +445,6 @@ function biome_lib.generate_block(shutting_down)
local minp = blocklog[1][1] local minp = blocklog[1][1]
local maxp = blocklog[1][2] local maxp = blocklog[1][2]
local airflag = blocklog[1][3] local airflag = blocklog[1][3]
local pos_hash = minetest.hash_node_position(minp)
if not biome_lib.pos_hash then -- we need to read the maplock and get the surfaces list if not biome_lib.pos_hash then -- we need to read the maplock and get the surfaces list
local now = minetest.get_us_time() local now = minetest.get_us_time()
@ -435,7 +452,8 @@ function biome_lib.generate_block(shutting_down)
minetest.load_area(minp) minetest.load_area(minp)
if not confirm_block_surroundings(minp) if not confirm_block_surroundings(minp)
and not shutting_down and not shutting_down
and (blocklog[1][4] + biome_lib.block_timeout) > now then -- if any neighbors appear not to be loaded and the block hasn't expired yet, defer it -- if any neighbors appear not to be loaded and the block hasn't expired yet, defer it
and (blocklog[1][4] + biome_lib.block_timeout) > now then
if biome_lib.run_block_recheck_list then if biome_lib.run_block_recheck_list then
biome_lib.block_log[#biome_lib.block_log + 1] = table.copy(biome_lib.block_recheck_list[1]) biome_lib.block_log[#biome_lib.block_log + 1] = table.copy(biome_lib.block_recheck_list[1])
@ -542,9 +560,10 @@ function biome_lib.register_active_spawner(sd,sp,sr,sc,ss,sa)
neighbors = biome.neighbors, neighbors = biome.neighbors,
label = biome.label, label = biome.label,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local p_top = { x = pos.x, y = pos.y + 1, z = pos.z } local p_top = { x = pos.x, y = pos.y + 1, z = pos.z }
local n_top = minetest.get_node(p_top) local n_top = minetest.get_node(p_top)
local perlin_fertile_area = minetest.get_perlin(biome.seed_diff, biome_lib.fertile_perlin_octaves, biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale) local perlin_fertile_area = minetest.get_perlin(biome.seed_diff, biome_lib.fertile_perlin_octaves,
biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale)
local fertility, temperature, humidity = get_biome_data(pos, perlin_fertile_area) local fertility, temperature, humidity = get_biome_data(pos, perlin_fertile_area)
@ -654,12 +673,14 @@ function biome_lib.replace_plant(pos, replacement, grow_function, walldir, seedd
biome_lib.grow_ltree(pos, grow_function) biome_lib.grow_ltree(pos, grow_function)
return return
elseif growtype == "function" then elseif growtype == "function" then
local perlin_fertile_area = minetest.get_perlin(seeddiff, biome_lib.fertile_perlin_octaves, biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale) local perlin_fertile_area = minetest.get_perlin(seeddiff, biome_lib.fertile_perlin_octaves,
biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale)
local fertility, temperature, _ = get_biome_data(pos, perlin_fertile_area) local fertility, temperature, _ = get_biome_data(pos, perlin_fertile_area)
grow_function(pos, fertility, temperature, walldir) grow_function(pos, fertility, temperature, walldir)
return return
elseif growtype == "string" then elseif growtype == "string" then
local perlin_fertile_area = minetest.get_perlin(seeddiff, biome_lib.fertile_perlin_octaves, biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale) local perlin_fertile_area = minetest.get_perlin(seeddiff, biome_lib.fertile_perlin_octaves,
biome_lib.fertile_perlin_persistence, biome_lib.fertile_perlin_scale)
local fertility, temperature, _ = get_biome_data(pos, perlin_fertile_area) local fertility, temperature, _ = get_biome_data(pos, perlin_fertile_area)
assert(loadstring(grow_function.."(...)"))(pos, fertility, temperature, walldir) assert(loadstring(grow_function.."(...)"))(pos, fertility, temperature, walldir)
return return

View file

@ -108,7 +108,8 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
end end
end end
else else
biome_lib.dbg("Did not enqueue mapblocks at elevation "..miny.."m, they're out of range of any generate_plant() calls.", 4) biome_lib.dbg("Did not enqueue mapblocks at elevation "..miny..
"m, they're out of range of any generate_plant() calls.", 4)
end end
end end
biome_lib.run_block_recheck_list = true biome_lib.run_block_recheck_list = true

View file

@ -81,7 +81,7 @@ function biome_lib.can_use_decorations(b, nodes_or_function_or_treedef)
["y_min"] = biome.min_elevation, ["y_min"] = biome.min_elevation,
["y_max"] = biome.max_elevation, ["y_max"] = biome.max_elevation,
["spawn_by"] = biome.near_nodes, ["spawn_by"] = biome.near_nodes,
["num_spawn_by"] = biome.near_nodes and biome.near_nodes_count, ["num_spawn_by"] = biome.near_nodes and biome.near_nodes_count,
} }
local r = (100-biome.rarity)/100 local r = (100-biome.rarity)/100

View file

@ -48,7 +48,6 @@ function biome_lib.update_plant(opts)
local p_bot = {x=pos.x, y=pos.y-1, z=pos.z} local p_bot = {x=pos.x, y=pos.y-1, z=pos.z}
local n_top = minetest.get_node(p_top) local n_top = minetest.get_node(p_top)
local n_bot = minetest.get_node(p_bot) local n_bot = minetest.get_node(p_bot)
local root_node = minetest.get_node({x=pos.x, y=pos.y-options.height_limit, z=pos.z})
local walldir = nil local walldir = nil
if options.need_wall and options.verticals_list then if options.need_wall and options.verticals_list then
walldir = biome_lib.find_adjacent_wall(p_top, options.verticals_list, options.choose_random_wall) walldir = biome_lib.find_adjacent_wall(p_top, options.verticals_list, options.choose_random_wall)

View file

@ -7,18 +7,9 @@
biome_lib = {} biome_lib = {}
biome_lib.modpath = minetest.get_modpath("biome_lib") biome_lib.modpath = minetest.get_modpath("biome_lib")
-- Boilerplate to support localized strings if intllib mod is installed. local function tableize(s)
local S return string.split(string.trim(string.gsub(s, " ", "")))
if minetest.global_exists("intllib") then
if intllib.make_gettext_pair then
S = intllib.make_gettext_pair()
else
S = intllib.Getter()
end
else
S = function(s) return s end
end end
biome_lib.intllib = S
local c1 = minetest.settings:get("biome_lib_default_grow_through_nodes") local c1 = minetest.settings:get("biome_lib_default_grow_through_nodes")
biome_lib.default_grow_through_nodes = {["air"] = true} biome_lib.default_grow_through_nodes = {["air"] = true}
@ -85,15 +76,18 @@ minetest.after(0.01, function()
biome_lib.dbg("All mapgen registrations completed.", 0) biome_lib.dbg("All mapgen registrations completed.", 0)
if n > 0 then if n > 0 then
biome_lib.dbg("Total items/actions to handle manually: "..n.." ("..#biome_lib.actionslist_no_aircheck.." without air checks)", 0) biome_lib.dbg("Total items/actions to handle manually: "..n..
biome_lib.dbg("Total surface types to handle manually: "..#biome_lib.surfaceslist_aircheck + #biome_lib.surfaceslist_no_aircheck, 0) " ("..#biome_lib.actionslist_no_aircheck.." without air checks)", 0)
biome_lib.dbg("Total surface types to handle manually: "
..#biome_lib.surfaceslist_aircheck + #biome_lib.surfaceslist_no_aircheck, 0)
else else
biome_lib.dbg("There are no \"handle manually\" items/actions registered,", 0) biome_lib.dbg("There are no \"handle manually\" items/actions registered,", 0)
biome_lib.dbg("so the mapblock queue will not be not used this session.", 0) biome_lib.dbg("so the mapblock queue will not be not used this session.", 0)
end end
biome_lib.dbg("Items sent to the engine's decorations handler: "..#biome_lib.registered_decorations, 0) biome_lib.dbg("Items sent to the engine's decorations handler: "..#biome_lib.registered_decorations, 0)
biome_lib.dbg("Elevation range: "..biome_lib.mapgen_elevation_limit.min.." to "..string.format("%+d", biome_lib.mapgen_elevation_limit.max).." meters.", 0) biome_lib.dbg("Elevation range: "..biome_lib.mapgen_elevation_limit.min.." to "..
string.format("%+d", biome_lib.mapgen_elevation_limit.max).." meters.", 0)
if n > 0 then if n > 0 then
dofile(biome_lib.modpath .. "/block_queue_checks.lua") dofile(biome_lib.modpath .. "/block_queue_checks.lua")

View file

@ -1,5 +0,0 @@
# Translation by Xanthin
someone = jemand
Sorry, %s owns that spot. = Entschuldige, %s gehoert diese Stelle.
[Plantlife Library] Loaded = [Plantlife Library] Geladen

View file

@ -1,5 +0,0 @@
# Template
someone = quelqu'un
Sorry, %s owns that spot. = Désolé, %s possède cet endroit.
[Plantlife Library] Loaded = [Librairie Plantlife] Chargée.

View file

@ -1,5 +0,0 @@
# Translation by inpos
someone = кто-то
Sorry, %s owns that spot. = Извините, но %s уже является владельцем этой точки.
[Plantlife Library] Loaded = [Plantlife Library] Загружена

View file

@ -1,5 +0,0 @@
# Template
someone =
Sorry, %s owns that spot. =
[Plantlife Library] Loaded =

View file

@ -1,5 +0,0 @@
# Turkish translation by mahmutelmas06
someone = birisi
Sorry, %s owns that spot. = Üzgünüm, buranın sahibi %s.
[Plantlife Library] Loaded = [Plantlife Library] yüklendi

View file

@ -1,3 +1,3 @@
name = biome_lib name = biome_lib
min_minetest_version = 5.2.0 min_minetest_version = 5.2.0
optional_depends = default, intllib optional_depends = default

View file

@ -6,7 +6,7 @@ function biome_lib.find_adjacent_wall(pos, verticals, randomflag)
local verts = dump(verticals) local verts = dump(verticals)
if randomflag then if randomflag then
local walltab = {} local walltab = {}
if string.find(verts, minetest.get_node({ x=pos.x-1, y=pos.y, z=pos.z }).name) then walltab[#walltab + 1] = 3 end if string.find(verts, minetest.get_node({ x=pos.x-1, y=pos.y, z=pos.z }).name) then walltab[#walltab + 1] = 3 end
if string.find(verts, minetest.get_node({ x=pos.x+1, y=pos.y, z=pos.z }).name) then walltab[#walltab + 1] = 2 end if string.find(verts, minetest.get_node({ x=pos.x+1, y=pos.y, z=pos.z }).name) then walltab[#walltab + 1] = 2 end
if string.find(verts, minetest.get_node({ x=pos.x , y=pos.y, z=pos.z-1 }).name) then walltab[#walltab + 1] = 5 end if string.find(verts, minetest.get_node({ x=pos.x , y=pos.y, z=pos.z-1 }).name) then walltab[#walltab + 1] = 5 end

View file

@ -55,7 +55,7 @@ minetest.register_craft({
minetest.register_craftitem("farming:cornstarch", { minetest.register_craftitem("farming:cornstarch", {
description = S("Cornstarch"), description = S("Cornstarch"),
inventory_image = "farming_cornstarch.png", inventory_image = "farming_cornstarch.png",
groups = {food_cornstarch = 1, food_gelatin = 1, food_flammable = 2} groups = {food_cornstarch = 1, food_gelatin = 1, flammable = 2}
}) })
minetest.register_craft({ minetest.register_craft({

View file

@ -7,7 +7,7 @@
farming = { farming = {
mod = "redo", mod = "redo",
version = "20211116", version = "20211204",
path = minetest.get_modpath("farming"), path = minetest.get_modpath("farming"),
select = { select = {
type = "fixed", type = "fixed",

View file

@ -3,48 +3,99 @@ vines = {
recipes = {} recipes = {}
} }
local enable_roots = minetest.settings:get_bool("vines_enable_roots") local enable_vines = minetest.settings:get_bool("vines_enable_vines", true)
local enable_rope = minetest.settings:get_bool("vines_enable_rope", true)
local enable_roots = minetest.settings:get_bool("vines_enable_roots", true)
local enable_standard = minetest.settings:get_bool("vines_enable_standard", true)
local enable_side = minetest.settings:get_bool("vines_enable_side", true)
local enable_jungle = minetest.settings:get_bool("vines_enable_jungle", true)
local enable_willow = minetest.settings:get_bool("vines_enable_willow", true)
local default_rarity = 90
local rarity_roots = tonumber(minetest.settings:get("vines_rarity_roots")) or default_rarity
local rarity_standard = tonumber(minetest.settings:get("vines_rarity_standard")) or default_rarity
local rarity_side = tonumber(minetest.settings:get("vines_rarity_side")) or default_rarity
local rarity_jungle = tonumber(minetest.settings:get("vines_rarity_jungle")) or default_rarity
local rarity_willow = tonumber(minetest.settings:get("vines_rarity_willow")) or default_rarity
local growth_min = tonumber(minetest.settings:get("vines_growth_min")) or 180
local growth_max = tonumber(minetest.settings:get("vines_growth_max")) or 360
-- support for i18n -- support for i18n
local S = minetest.get_translator("vines") local S = minetest.get_translator("vines")
-- ITEMS -- ITEMS
minetest.register_craftitem("vines:vines", { if enable_vines ~= false then
description = S("Vines"), minetest.register_craftitem("vines:vines", {
inventory_image = "vines_item.png", description = S("Vines"),
groups = {vines = 1, flammable = 2} inventory_image = "vines_item.png",
}) groups = {vines = 1, flammable = 2}
})
end
-- FUNCTIONS -- FUNCTIONS
local function dig_down(pos, node, digger) local function on_dig(pos, node, player)
vine_name_end = node.name:gsub("_middle", "_end")
drop_item = "vines:vines"
if enable_vines == false then
drop_item = vine_name_end
end
wielded_item = player:get_wielded_item()
if wielded_item then
wielded_item:add_wear(1)
if wielded_item:get_name() == 'vines:shears' then
drop_item = vine_name_end
end
end
if digger == nil then return end break_pos = {x = pos.x, y = pos.y, z = pos.z}
while minetest.get_item_group(minetest.get_node(break_pos).name, "vines") > 0 do
minetest.remove_node(break_pos)
minetest.handle_node_drops(break_pos, {drop_item}, player)
break_pos.y = break_pos.y - 1
end
end
local np = {x = pos.x, y = pos.y - 1, z = pos.z} local function ensure_vine_end(pos, oldnode)
local np = {x = pos.x, y = pos.y + 1, z = pos.z}
local nn = minetest.get_node(np) local nn = minetest.get_node(np)
vine_name_end = oldnode.name:gsub("_middle", "_end")
if minetest.get_item_group(nn.name, "vines") > 0 then if minetest.get_item_group(nn.name, "vines") > 0 then
minetest.node_dig(np, nn, digger) minetest.swap_node(np, { name = vine_name_end, param2 = oldnode.param2 })
minetest.registered_items[vine_name_end].on_construct(np, minetest.get_node(np))
end end
end end
vines.register_vine = function( name, defs, biome ) vines.register_vine = function( name, defs, biome )
local groups = {vines = 1, snappy = 3, flammable = 2, attached_node = 1} local groups = {vines = 1, snappy = 3, flammable = 2}
local vine_name_end = 'vines:' .. name .. '_end' local vine_name_end = 'vines:' .. name .. '_end'
local vine_name_middle = 'vines:' .. name .. '_middle' local vine_name_middle = 'vines:' .. name .. '_middle'
local vine_image_end = "vines_" .. name .. "_end.png" local vine_image_end = "vines_" .. name .. "_end.png"
local vine_image_middle = "vines_" .. name .. "_middle.png" local vine_image_middle = "vines_" .. name .. "_middle.png"
local drop_node = vine_name_end
biome.spawn_plants = {vine_name_end} local spawn_plants = function(pos, fdir)
local max_length = math.random(defs.average_length)
local current_length = 1
if minetest.get_node({ x=pos.x, y=pos.y - 1, z=pos.z }).name == 'air' then
while minetest.get_node({ x=pos.x, y=pos.y - 1, z=pos.z }).name == 'air' and current_length < max_length do
minetest.swap_node(pos, { name = vine_name_middle, param2 = fdir })
pos.y = pos.y - 1
current_length = current_length + 1
end
minetest.set_node(pos, { name = vine_name_end, param2 = fdir })
end
end
local vine_group = 'group:' .. name .. '_vines' local vine_group = 'group:' .. name .. '_vines'
biome.spawn_surfaces[#biome.spawn_surfaces + 1] = vine_group biome.surface[#biome.surface + 1] = vine_group
local selection_box = {type = "wallmounted",} local selection_box = {type = "wallmounted",}
local drawtype = 'signlike' local drawtype = 'signlike'
@ -64,7 +115,7 @@ vines.register_vine = function( name, defs, biome )
walkable = false, walkable = false,
climbable = true, climbable = true,
wield_image = vine_image_end, wield_image = vine_image_end,
drop = "vines:vines", drop = {},
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
@ -79,8 +130,7 @@ vines.register_vine = function( name, defs, biome )
on_construct = function(pos) on_construct = function(pos)
local timer = minetest.get_node_timer(pos) local timer = minetest.get_node_timer(pos)
timer:start(math.random(growth_min, growth_max))
timer:start(math.random(5, 10))
end, end,
on_timer = function(pos) on_timer = function(pos)
@ -88,12 +138,11 @@ vines.register_vine = function( name, defs, biome )
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local bottom = {x = pos.x, y = pos.y - 1, z = pos.z} local bottom = {x = pos.x, y = pos.y - 1, z = pos.z}
local bottom_node = minetest.get_node( bottom ) local bottom_node = minetest.get_node( bottom )
if bottom_node.name == "air" then if bottom_node.name == "air" then
if not math.random(defs.average_length) == 1 then if math.random(defs.average_length) ~= 1 then
minetest.set_node(pos, { minetest.swap_node(pos, {
name = vine_name_middle, param2 = node.param2}) name = vine_name_middle, param2 = node.param2})
minetest.set_node(bottom, { minetest.set_node(bottom, {
@ -101,13 +150,15 @@ vines.register_vine = function( name, defs, biome )
local timer = minetest.get_node_timer(bottom_node) local timer = minetest.get_node_timer(bottom_node)
timer:start(math.random(5, 10)) timer:start(math.random(growth_min, growth_max))
end end
end end
end, end,
after_dig_node = function(pos, node, metadata, digger) on_dig = on_dig,
dig_down(pos, node, digger)
after_destruct = function(pos, oldnode)
ensure_vine_end(pos, oldnode)
end, end,
}) })
@ -115,7 +166,7 @@ vines.register_vine = function( name, defs, biome )
description = S("Matured") .. " " .. defs.description, description = S("Matured") .. " " .. defs.description,
walkable = false, walkable = false,
climbable = true, climbable = true,
drop = "vines:vines", drop = {},
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
@ -128,12 +179,14 @@ vines.register_vine = function( name, defs, biome )
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
selection_box = selection_box, selection_box = selection_box,
after_dig_node = function(pos, node, metadata, digger) on_dig = on_dig,
dig_down(pos, node, digger)
after_destruct = function(pos, oldnode)
ensure_vine_end(pos, oldnode)
end, end,
}) })
biome_lib.register_active_spawner(biome) biome_lib.register_on_generate(biome, spawn_plants)
end end
-- ALIASES -- ALIASES
@ -184,110 +237,112 @@ minetest.register_craft({
-- NODES -- NODES
minetest.register_node("vines:rope_block", { if enable_rope ~= false then
description = S("Rope"), minetest.register_node("vines:rope_block", {
sunlight_propagates = true, description = S("Rope"),
paramtype = "light", sunlight_propagates = true,
tiles = { paramtype = "light",
"default_wood.png^vines_rope.png", tiles = {
"default_wood.png^vines_rope.png", "default_wood.png^vines_rope.png",
"default_wood.png", "default_wood.png^vines_rope.png",
"default_wood.png", "default_wood.png",
"default_wood.png^vines_rope.png", "default_wood.png",
"default_wood.png^vines_rope.png", "default_wood.png^vines_rope.png",
}, "default_wood.png^vines_rope.png",
groups = {flammable = 2, choppy = 2, oddly_breakable_by_hand = 1}, },
groups = {flammable = 2, choppy = 2, oddly_breakable_by_hand = 1},
after_place_node = function(pos) after_place_node = function(pos)
local p = {x = pos.x, y = pos.y - 1, z = pos.z} local p = {x = pos.x, y = pos.y - 1, z = pos.z}
local n = minetest.get_node(p) local n = minetest.get_node(p)
if n.name == "air" then if n.name == "air" then
minetest.add_node(p, {name = "vines:rope_end"}) minetest.add_node(p, {name = "vines:rope_end"})
end
end,
after_dig_node = function(pos, node, digger)
local p = {x = pos.x, y = pos.y - 1, z = pos.z}
local n = minetest.get_node(p)
while n.name == 'vines:rope' or n.name == 'vines:rope_end' do
minetest.remove_node(p)
p = {x = p.x, y = p.y - 1, z = p.z}
n = minetest.get_node(p)
end
end end
end, })
after_dig_node = function(pos, node, digger) minetest.register_node("vines:rope", {
description = S("Rope"),
walkable = false,
climbable = true,
sunlight_propagates = true,
paramtype = "light",
drop = {},
tiles = {"vines_rope.png"},
drawtype = "plantlike",
groups = {flammable = 2, not_in_creative_inventory = 1},
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
},
})
local p = {x = pos.x, y = pos.y - 1, z = pos.z} minetest.register_node("vines:rope_end", {
local n = minetest.get_node(p) description = S("Rope"),
walkable = false,
climbable = true,
sunlight_propagates = true,
paramtype = "light",
drop = {},
tiles = {"vines_rope_end.png"},
drawtype = "plantlike",
groups = {flammable = 2, not_in_creative_inventory = 1},
sounds = default.node_sound_leaves_defaults(),
while n.name == 'vines:rope' or n.name == 'vines:rope_end' do after_place_node = function(pos)
minetest.remove_node(p) local yesh = {x = pos.x, y = pos.y - 1, z = pos.z}
p = {x = p.x, y = p.y - 1, z = p.z} minetest.add_node(yesh, {name = "vines:rope"})
n = minetest.get_node(p) end,
end
end
})
minetest.register_node("vines:rope", { selection_box = {
description = S("Rope"), type = "fixed",
walkable = false, fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
climbable = true, },
sunlight_propagates = true,
paramtype = "light",
drop = {},
tiles = {"vines_rope.png"},
drawtype = "plantlike",
groups = {flammable = 2, not_in_creative_inventory = 1},
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
},
})
minetest.register_node("vines:rope_end", { on_construct = function(pos)
description = S("Rope"),
walkable = false,
climbable = true,
sunlight_propagates = true,
paramtype = "light",
drop = {},
tiles = {"vines_rope_end.png"},
drawtype = "plantlike",
groups = {flammable = 2, not_in_creative_inventory = 1},
sounds = default.node_sound_leaves_defaults(),
after_place_node = function(pos)
local yesh = {x = pos.x, y = pos.y - 1, z = pos.z}
minetest.add_node(yesh, {name = "vines:rope"})
end,
selection_box = {
type = "fixed",
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
},
on_construct = function(pos)
local timer = minetest.get_node_timer(pos)
timer:start(1)
end,
on_timer = function( pos, elapsed )
local p = {x = pos.x, y = pos.y - 1, z = pos.z}
local n = minetest.get_node(p)
if n.name == "air" then
minetest.set_node(pos, {name = "vines:rope"})
minetest.add_node(p, {name = "vines:rope_end"})
else
local timer = minetest.get_node_timer(pos) local timer = minetest.get_node_timer(pos)
timer:start(1) timer:start(1)
end,
on_timer = function( pos, elapsed )
local p = {x = pos.x, y = pos.y - 1, z = pos.z}
local n = minetest.get_node(p)
if n.name == "air" then
minetest.set_node(pos, {name = "vines:rope"})
minetest.add_node(p, {name = "vines:rope_end"})
else
local timer = minetest.get_node_timer(pos)
timer:start(1)
end
end end
end })
}) end
-- SHEARS -- SHEARS
@ -314,100 +369,116 @@ if enable_roots ~= false then
"default:dirt_with_grass", "default:dirt_with_grass",
"default:dirt" "default:dirt"
} }
vines.register_vine('root',
{description = S("Roots"), average_length = 9}, {
choose_random_wall = true,
avoid_nodes = {"vines:root_middle"},
avoid_radius = 5,
surface = spawn_root_surfaces,
spawn_on_bottom = true,
plantlife_limit = -0.6,
rarity = rarity_roots,
-- humidity_min = 0.4,
})
else
minetest.register_alias('vines:root_middle', 'air')
minetest.register_alias('vines:root_end', 'air')
end end
vines.register_vine('root', if enable_standard ~= false then
{description = S("Roots"), average_length = 9}, { vines.register_vine('vine',
choose_random_wall = true, {description = S("Vines"), average_length = 5}, {
avoid_nodes = {"vines:root_middle"}, choose_random_wall = true,
avoid_radius = 5, avoid_nodes = {"group:vines"},
spawn_delay = 500, avoid_radius = 5,
spawn_chance = 10, surface = {
spawn_surfaces = spawn_root_surfaces, -- "default:leaves",
spawn_on_bottom = true, "default:jungleleaves",
plantlife_limit = -0.6, "moretrees:jungletree_leaves_red",
humidity_min = 0.4, "moretrees:jungletree_leaves_yellow",
}) "moretrees:jungletree_leaves_green"
},
spawn_on_bottom = true,
plantlife_limit = -0.9,
rarity = rarity_standard,
-- humidity_min = 0.7,
})
else
minetest.register_alias('vines:vine_middle', 'air')
minetest.register_alias('vines:vine_end', 'air')
end
vines.register_vine('vine', if enable_side ~= false then
{description = S("Vines"), average_length = 5}, { vines.register_vine('side',
choose_random_wall = true, {description = S("Vines"), average_length = 6}, {
avoid_nodes = {"group:vines"}, choose_random_wall = true,
avoid_radius = 5, avoid_nodes = {"group:vines", "default:apple"},
spawn_delay = 500, avoid_radius = 3,
spawn_chance = 100, surface = {
spawn_surfaces = { -- "default:leaves",
-- "default:leaves", "default:jungleleaves",
"default:jungleleaves", "moretrees:jungletree_leaves_red",
"moretrees:jungletree_leaves_red", "moretrees:jungletree_leaves_yellow",
"moretrees:jungletree_leaves_yellow", "moretrees:jungletree_leaves_green"
"moretrees:jungletree_leaves_green" },
}, spawn_on_side = true,
spawn_on_bottom = true, plantlife_limit = -0.9,
plantlife_limit = -0.9, rarity = rarity_side,
humidity_min = 0.7, -- humidity_min = 0.4,
}) })
else
minetest.register_alias('vines:side_middle', 'air')
minetest.register_alias('vines:side_end', 'air')
end
vines.register_vine('side', if enable_jungle ~= false then
{description = S("Vines"), average_length = 6}, { vines.register_vine("jungle",
choose_random_wall = true, {description = S("Jungle Vines"), average_length = 7}, {
avoid_nodes = {"group:vines", "default:apple"}, choose_random_wall = true,
avoid_radius = 3, neighbors = {
spawn_delay = 500, "default:jungleleaves",
spawn_chance = 100, "moretrees:jungletree_leaves_red",
spawn_surfaces = { "moretrees:jungletree_leaves_yellow",
-- "default:leaves", "moretrees:jungletree_leaves_green"
"default:jungleleaves", },
"moretrees:jungletree_leaves_red", avoid_nodes = {
"moretrees:jungletree_leaves_yellow", "vines:jungle_middle",
"moretrees:jungletree_leaves_green" "vines:jungle_end",
}, },
spawn_on_side = true, avoid_radius = 5,
plantlife_limit = -0.9, surface = {
humidity_min = 0.4, "default:jungletree",
}) "moretrees:jungletree_trunk"
},
spawn_on_side = true,
plantlife_limit = -0.9,
rarity = rarity_jungle,
-- humidity_min = 0.2,
})
else
minetest.register_alias('vines:jungle_middle', 'air')
minetest.register_alias('vines:jungle_end', 'air')
end
vines.register_vine("jungle", if enable_willow ~= false then
{description = S("Jungle Vines"), average_length = 7}, { vines.register_vine( 'willow',
choose_random_wall = true, {description = S("Willow Vines"), average_length = 9}, {
neighbors = { choose_random_wall = true,
"default:jungleleaves", avoid_nodes = {"vines:willow_middle"},
"moretrees:jungletree_leaves_red", avoid_radius = 5,
"moretrees:jungletree_leaves_yellow", near_nodes = {'default:water_source'},
"moretrees:jungletree_leaves_green" near_nodes_size = 1,
}, near_nodes_count = 1,
avoid_nodes = { near_nodes_vertical = 7,
"vines:jungle_middle", plantlife_limit = -0.8,
"vines:jungle_end", spawn_on_side = true,
}, surface = {"moretrees:willow_leaves"},
avoid_radius = 5, rarity = rarity_willow,
spawn_delay = 500, -- humidity_min = 0.5
spawn_chance = 100, })
spawn_surfaces = { else
"default:jungletree", minetest.register_alias('vines:willow_middle', 'air')
"moretrees:jungletree_trunk" minetest.register_alias('vines:willow_end', 'air')
}, end
spawn_on_side = true,
plantlife_limit = -0.9,
humidity_min = 0.2,
})
vines.register_vine( 'willow',
{description = S("Willow Vines"), average_length = 9}, {
choose_random_wall = true,
avoid_nodes = {"vines:willow_middle"},
avoid_radius = 5,
near_nodes = {'default:water_source'},
near_nodes_size = 1,
near_nodes_count = 1,
near_nodes_vertical = 7,
plantlife_limit = -0.8,
spawn_chance = 10,
spawn_delay = 500,
spawn_on_side = true,
spawn_surfaces = {"moretrees:willow_leaves"},
humidity_min = 0.5
})
print("[Vines] Loaded!")

View file

@ -0,0 +1,41 @@
#Enable the vines item
vines_enable_vines (Enable vines item) bool true
#Enables ropes made of vine.
vines_enable_rope (Enable vine ropes) bool true
#Enables root vines.
vines_enable_roots (Enable root vines) bool true
#Rarity of root vines, from 1 to 100, higher numbers are rarer.
vines_rarity_roots (Rarity of roots vines) int 90 1 100
#Enables the standard type of vines.
vines_enable_standard (Enable standard vines) bool true
#Rarity of standard vines, from 1 to 100, higher numbers are rarer.
vines_rarity_standard (Rarity of standard vines) int 90 1 100
#Enables the type of vines that grow on the sides of leaf blocks.
vines_enable_side (Enable side vines) bool true
#Rarity of side vines, from 1 to 100, higher numbers are rarer.
vines_rarity_side (Rarity of side vines) int 90 1 100
#Enables jungle style vines.
vines_enable_jungle (Enable jungle vines) bool true
#Rarity of jungle vines, from 1 to 100, higher numbers are rarer.
vines_rarity_jungle (Rarity of jungle vines) int 90 1 100
#Enables willow vines.
vines_enable_willow (Enable willow vines) bool true
#Rarity of willow vines, from 1 to 100, higher numbers are rarer.
vines_rarity_willow (Rarity of willow vines) int 90 1 100
#Vine growth speed, minimum number of seconds between each growth.
vines_growth_min (Minimum number of seconds between growth) int 180 1 3600
#Vine growth speed, maximum number of seconds between each growth.
vines_growth_max (Maximum number of seconds between growth) int 360 1 3600

View file

@ -29,7 +29,7 @@ minetest.register_chatcommand("protector_remove", {
end end
removal_names = param removal_names = param
end, end
}) })
@ -63,7 +63,7 @@ minetest.register_chatcommand("protector_replace", {
end end
replace_names = param replace_names = param
end, end
}) })
@ -163,8 +163,8 @@ minetest.register_node("protector:protect_hidden", {
-- 1px block inside door hinge near node top -- 1px block inside door hinge near node top
collision_box = { collision_box = {
type = "fixed", type = "fixed",
fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32}, fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32}
}, }
}) })

View file

@ -300,7 +300,6 @@ function register_door(name, def)
sunlight_propagates = def.sunlight, sunlight_propagates = def.sunlight,
on_blast = function() end, on_blast = function() end,
}) })
end end
-- Protected Wooden Door -- Protected Wooden Door
@ -317,7 +316,7 @@ register_door(name, {
tiles_bottom = {"doors_wood_b.png^protector_logo.png", "doors_brown.png"}, tiles_bottom = {"doors_wood_b.png^protector_logo.png", "doors_brown.png"},
tiles_top = {"doors_wood_a.png", "doors_brown.png"}, tiles_top = {"doors_wood_a.png", "doors_brown.png"},
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
sunlight = false, sunlight = false
}) })
if protector_crafts then if protector_crafts then
@ -480,7 +479,7 @@ if protector_crafts then
output = "protector:trapdoor 2", output = "protector:trapdoor 2",
recipe = { recipe = {
{"group:wood", "default:copper_ingot", "group:wood"}, {"group:wood", "default:copper_ingot", "group:wood"},
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"}
} }
}) })
@ -521,7 +520,7 @@ if protector_crafts then
output = "protector:trapdoor_steel", output = "protector:trapdoor_steel",
recipe = { recipe = {
{"default:copper_ingot", "default:steel_ingot"}, {"default:copper_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot"}, {"default:steel_ingot", "default:steel_ingot"}
} }
}) })
@ -736,7 +735,7 @@ if protector_crafts then
minetest.register_craft({ minetest.register_craft({
output = "protector:chest", output = "protector:chest",
recipe = { recipe = {
{"mcl_chests:chest", "mcl_core:gold_ingot"}, {"mcl_chests:chest", "mcl_core:gold_ingot"}
} }
}) })
else else
@ -745,14 +744,14 @@ if protector_crafts then
recipe = { recipe = {
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"},
{"group:wood", "default:copper_ingot", "group:wood"}, {"group:wood", "default:copper_ingot", "group:wood"},
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"}
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = "protector:chest", output = "protector:chest",
recipe = { recipe = {
{"default:chest", "default:copper_ingot"}, {"default:chest", "default:copper_ingot"}
} }
}) })
end end

View file

@ -155,7 +155,6 @@ local protector_formspec = function(meta)
local formspec = "size[8,7]" local formspec = "size[8,7]"
.. default.gui_bg .. default.gui_bg
.. default.gui_bg_img .. default.gui_bg_img
.. default.gui_slots
.. "label[2.5,0;" .. F(S("-- Protector interface --")) .. "]" .. "label[2.5,0;" .. F(S("-- Protector interface --")) .. "]"
.. "label[0,1;" .. F(S("PUNCH node to show protected area")) .. "]" .. "label[0,1;" .. F(S("PUNCH node to show protected area")) .. "]"
.. "label[0,2;" .. F(S("Members:")) .. "]" .. "label[0,2;" .. F(S("Members:")) .. "]"
@ -489,7 +488,7 @@ minetest.register_node("protector:protect", {
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5 ,-0.5, -0.5, 0.5, 0.5, 0.5}, {-0.5 ,-0.5, -0.5, 0.5, 0.5, 0.5}
} }
}, },
@ -558,7 +557,7 @@ if protector_recipe then
recipe = { recipe = {
{"default:stone", "default:stone", "default:stone"}, {"default:stone", "default:stone", "default:stone"},
{"default:stone", "default:gold_ingot", "default:stone"}, {"default:stone", "default:gold_ingot", "default:stone"},
{"default:stone", "default:stone", "default:stone"}, {"default:stone", "default:stone", "default:stone"}
} }
}) })
else else
@ -568,7 +567,7 @@ if protector_recipe then
recipe = { recipe = {
{"mcl_core:stone", "mcl_core:stone", "mcl_core:stone"}, {"mcl_core:stone", "mcl_core:stone", "mcl_core:stone"},
{"mcl_core:stone", "mcl_core:gold_ingot", "mcl_core:stone"}, {"mcl_core:stone", "mcl_core:gold_ingot", "mcl_core:stone"},
{"mcl_core:stone", "mcl_core:stone", "mcl_core:stone"}, {"mcl_core:stone", "mcl_core:stone", "mcl_core:stone"}
} }
}) })
end end
@ -594,7 +593,7 @@ minetest.register_node("protector:protect2", {
type = "wallmounted", type = "wallmounted",
wall_top = {-0.375, 0.4375, -0.5, 0.375, 0.5, 0.5}, wall_top = {-0.375, 0.4375, -0.5, 0.375, 0.5, 0.5},
wall_bottom = {-0.375, -0.5, -0.5, 0.375, -0.4375, 0.5}, wall_bottom = {-0.375, -0.5, -0.5, 0.375, -0.4375, 0.5},
wall_side = {-0.5, -0.5, -0.375, -0.4375, 0.5, 0.375}, wall_side = {-0.5, -0.5, -0.375, -0.4375, 0.5, 0.375}
}, },
selection_box = {type = "wallmounted"}, selection_box = {type = "wallmounted"},
@ -755,7 +754,7 @@ minetest.register_entity("protector:display", {
if self.timer > protector_show then if self.timer > protector_show then
self.object:remove() self.object:remove()
end end
end, end
}) })
@ -765,7 +764,7 @@ minetest.register_entity("protector:display", {
local x = protector_radius local x = protector_radius
minetest.register_node("protector:display_node", { minetest.register_node("protector:display_node", {
tiles = {"protector_display.png"}, tiles = {"protector_display.png"},
use_texture_alpha = "clip", -- true, use_texture_alpha = "clip",
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "nodebox",
node_box = { node_box = {
@ -781,15 +780,15 @@ minetest.register_node("protector:display_node", {
-- bottom -- bottom
{-(x+.55), -(x+.55), -(x+.55), (x+.55), -(x+.45), (x+.55)}, {-(x+.55), -(x+.55), -(x+.55), (x+.55), -(x+.45), (x+.55)},
-- middle (surround protector) -- middle (surround protector)
{-.55,-.55,-.55, .55,.55,.55}, {-.55,-.55,-.55, .55,.55,.55}
}, }
}, },
selection_box = { selection_box = {
type = "regular", type = "regular",
}, },
paramtype = "light", paramtype = "light",
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "", drop = ""
}) })

View file

@ -13,6 +13,6 @@ if minetest.get_modpath("lucky_block") then
{"dro", {"protector:trapdoor_steel"}, 1}, {"dro", {"protector:trapdoor_steel"}, 1},
{"dro", {"protector:tool"}, 1}, {"dro", {"protector:tool"}, 1},
{"dro", {"protector:chest"}, 1}, {"dro", {"protector:chest"}, 1},
{"exp"}, {"exp"}
}) })
end end

View file

@ -164,6 +164,6 @@ minetest.register_craft({
recipe = { recipe = {
{df, df, df}, {df, df, df},
{df, "protector:protect", df}, {df, "protector:protect", df},
{df, df, df}, {df, df, df}
} }
}) })

View file

@ -0,0 +1,17 @@
unused_args = false
max_line_length = 180
globals = {
"minetest",
"signs_lib",
}
read_globals = {
-- Builtin
table = {fields = {"copy"}},
"ItemStack", "vector",
-- Mod deps
"intllib",
"screwdriver",
}

View file

@ -149,9 +149,11 @@ In this text, common terms such as `pos`, `node`, or `placer`/`digger` will not
* `font_size = int` * `font_size = int`
Selects which font to use, either 15 or 31 (pixel height). This setting directly affects the sign's vertical resolution. Selects which font to use, either 16 or 32 (pixel height). This setting directly affects the sign's vertical resolution.
Default: 15 Default: 16
Note: Valid values were formerly 15 and 31, these are now aliases of 16 and 32 respectively.
* `x_offset = int` * `x_offset = int`
* `y_offset = int` * `y_offset = int`

View file

@ -22,10 +22,16 @@ That said, there are some basic text formatting options:
Writing "^" followed by a letter "a" through "h" will produce double-wide versions of these arrows, in the same order. These wide arrows occupy 0x89 to 0x91 in the character set. Writing "^" followed by a letter "a" through "h" will produce double-wide versions of these arrows, in the same order. These wide arrows occupy 0x89 to 0x91 in the character set.
* A color may be specified in the sign text by using "#" followed by a single hexadcimal digit (0-9 or a-f). These colors come from the standard Linux/IRC/CGA color set, and are shown in the sign's formspec. Any color change will remain in effect until changed again, or until the next line break. Any number of color changes in any arbitrary arrangement is allowed. To write "#" on a sign, write "##". To write a "^" on a sign, wirte "#^"
* A color may be specified in the sign text by using "#" followed by a single hexadcimal digit (0-9 or a-f). These colors come from the standard Linux/IRC/CGA color set, and are shown in the sign's formspec. Any color change will remain in effect until changed again, or until the next line break. Any number of color changes in any arbitrary arrangement is allowed.
To write "#" on a sign, write "##".
* Most writable signs can display double-wide text by flipping a switch in the sign's formspec. * Most writable signs can display double-wide text by flipping a switch in the sign's formspec.
* Support full Unicode Plane 0 charset (63000+ characters). The "Unicode font" switch on each sign can be turned on for a more consistent letter style in multilingual text.
## Sign placement and rotation notes ## Sign placement and rotation notes
* Pointing at a wall while placing will, of course, place the sign on the wall. * Pointing at a wall while placing will, of course, place the sign on the wall.

View file

@ -16,7 +16,7 @@ signs_lib.standard_lines = 6
signs_lib.standard_hscale = 1 signs_lib.standard_hscale = 1
signs_lib.standard_vscale = 1 signs_lib.standard_vscale = 1
signs_lib.standard_lspace = 1 signs_lib.standard_lspace = 1
signs_lib.standard_fsize = 15 signs_lib.standard_fsize = 16
signs_lib.standard_xoffs = 4 signs_lib.standard_xoffs = 4
signs_lib.standard_yoffs = 0 signs_lib.standard_yoffs = 0
signs_lib.standard_cpl = 35 signs_lib.standard_cpl = 35
@ -255,8 +255,7 @@ end
function signs_lib.set_obj_text(pos, text, glow) function signs_lib.set_obj_text(pos, text, glow)
local split = signs_lib.split_lines_and_words local split = signs_lib.split_lines_and_words
local text_ansi = Utf8ToAnsi(text) local text_ansi = signs_lib.Utf8ToAnsi(text)
local n = minetest.registered_nodes[minetest.get_node(pos).name]
signs_lib.delete_objects(pos) signs_lib.delete_objects(pos)
-- only create sign entity for actual text -- only create sign entity for actual text
if text_ansi and text_ansi ~= "" then if text_ansi and text_ansi ~= "" then
@ -342,6 +341,7 @@ local TP = signs_lib.path .. "/textures"
-- Font file formatter -- Font file formatter
local CHAR_FILE = "%s_%02x.png" local CHAR_FILE = "%s_%02x.png"
local CHAR_FILE_WIDE = "%s_%s.png" local CHAR_FILE_WIDE = "%s_%s.png"
local UNIFONT_TEX = "signs_lib_uni%02x.png\\^[sheet\\:16x16\\:%d,%d"
-- Fonts path -- Fonts path
local CHAR_PATH = TP .. "/" .. CHAR_FILE local CHAR_PATH = TP .. "/" .. CHAR_FILE
local CHAR_PATH_WIDE = TP .. "/" .. CHAR_FILE_WIDE local CHAR_PATH_WIDE = TP .. "/" .. CHAR_FILE_WIDE
@ -435,20 +435,18 @@ local function build_char_db(font_size)
return cw, cbw, cbh, (total_width / char_count), cw_wide return cw, cbw, cbh, (total_width / char_count), cw_wide
end end
signs_lib.charwidth15, signs_lib.charwidth16,
signs_lib.colorbgw15, signs_lib.colorbgw16,
signs_lib.lineheight15, signs_lib.lineheight16,
signs_lib.avgwidth15, signs_lib.avgwidth16,
signs_lib.charwidth_wide15 = build_char_db(15) signs_lib.charwidth_wide16 = build_char_db(16)
signs_lib.charwidth31, signs_lib.charwidth32,
signs_lib.colorbgw31, signs_lib.colorbgw32,
signs_lib.lineheight31, signs_lib.lineheight32,
signs_lib.avgwidth31, signs_lib.avgwidth32,
signs_lib.charwidth_wide31 = build_char_db(31) signs_lib.charwidth_wide32 = build_char_db(32)
local sign_groups = {choppy=2, dig_immediate=2}
local fences_with_sign = { }
-- some local helper functions -- some local helper functions
@ -470,7 +468,8 @@ local function char_tex(font_name, ch)
return ctexcache[font_name..ch], true return ctexcache[font_name..ch], true
else else
local c = ch:byte() local c = ch:byte()
local exists, tex = file_exists(CHAR_PATH:format(font_name, c)) local exists = file_exists(CHAR_PATH:format(font_name, c))
local tex
if exists and c ~= 14 then if exists and c ~= 14 then
tex = CHAR_FILE:format(font_name, c) tex = CHAR_FILE:format(font_name, c)
else else
@ -485,7 +484,8 @@ local function char_tex_wide(font_name, ch)
if ctexcache_wide[font_name..ch] then if ctexcache_wide[font_name..ch] then
return ctexcache_wide[font_name..ch], true return ctexcache_wide[font_name..ch], true
else else
local exists, tex = file_exists(CHAR_PATH_WIDE:format(font_name, ch)) local exists = file_exists(CHAR_PATH_WIDE:format(font_name, ch))
local tex
if exists then if exists then
tex = CHAR_FILE_WIDE:format(font_name, ch) tex = CHAR_FILE_WIDE:format(font_name, ch)
else else
@ -496,7 +496,7 @@ local function char_tex_wide(font_name, ch)
end end
end end
local function make_line_texture(line, lineno, pos, line_width, line_height, cwidth_tab, font_size, colorbgw, cwidth_tab_wide) local function make_line_texture(line, lineno, pos, line_width, line_height, cwidth_tab, font_size, colorbgw, cwidth_tab_wide, force_unicode_font)
local width = 0 local width = 0
local maxw = 0 local maxw = 0
local font_name = "signs_lib_font_"..font_size.."px" local font_name = "signs_lib_font_"..font_size.."px"
@ -512,58 +512,61 @@ local function make_line_texture(line, lineno, pos, line_width, line_height, cwi
for word_i, word in ipairs(line) do for word_i, word in ipairs(line) do
local chars = { } local chars = { }
local ch_offs = 0 local ch_offs = 0
word = string.gsub(word, "%^[12345678abcdefgh]", {
["^1"] = string.char(0x81),
["^2"] = string.char(0x82),
["^3"] = string.char(0x83),
["^4"] = string.char(0x84),
["^5"] = string.char(0x85),
["^6"] = string.char(0x86),
["^7"] = string.char(0x87),
["^8"] = string.char(0x88),
["^a"] = string.char(0x8a),
["^b"] = string.char(0x8b),
["^c"] = string.char(0x8c),
["^d"] = string.char(0x8d),
["^e"] = string.char(0x8e),
["^f"] = string.char(0x8f),
["^g"] = string.char(0x90),
["^h"] = string.char(0x91)
})
local word_l = #word local word_l = #word
local i = 1 local i = 1
local escape = 0
while i <= word_l do while i <= word_l do
local wide_c local wide_type, wide_c = string.match(word:sub(i), "^&#([xu])(%x+);")
if "&#x" == word:sub(i, i + 2) then
local j = i + 3
local collected = ""
while j <= word_l do
local c = word:sub(j, j)
if c == ";" then
wide_c = collected
break
elseif c < "0" then
break
elseif "f" < c then
break
elseif ("9" < c) and (c < "a") then
break
else
collected = collected .. c
j = j + 1
end
end
end
local c = word:sub(i, i) local c = word:sub(i, i)
local c2 = word:sub(i+1, i+1) local c2 = word:sub(i+1, i+1)
if c == "#" and c2 ~= "#" then
local cc = tonumber(c2, 16) if escape > 0 then escape = escape - 1 end
if cc then if c == "^" and escape == 0 and c2:find("[1-8a-h]") then
i = i + 1 c = string.char(tonumber(c2,18)+0x80)
cur_color = cc i = i + 1
end
local wide_skip = 0
if force_unicode_font then
if wide_c then
wide_skip = #wide_c + 3
wide_type = "u"
elseif c:byte() < 0x80 or c:byte() >= 0xa0 then
wide_type = "u"
local uchar = signs_lib.AnsiToUtf8(c)
local code
if #uchar == 1 then
code = uchar:byte()
else
code = uchar:byte() % (2 ^ (7 - #uchar))
for j = 1, #uchar do
code = code * (2 ^ 6) + uchar:byte(j) - 0x80
end
end
wide_c = string.format("%04x", code)
end end
elseif wide_c then elseif wide_c then
local w = cwidth_tab_wide[wide_c] wide_skip = #wide_c + 3
end
if c == "#" and escape == 0 and c2:find("[0-9A-Fa-f#^]") then
if c2 == "#" or c2 == "^" then
escape = 2
else
i = i + 1
cur_color = tonumber(c2, 16)
end
elseif wide_c then
local w, code
if wide_type == "x" then
w = cwidth_tab_wide[wide_c]
elseif wide_type == "u" and #wide_c <= 4 then
w = font_size
code = tonumber(wide_c, 16)
if signs_lib.unifont_halfwidth[code] then
w = math.floor(w / 2)
end
end
if w then if w then
width = width + w + 1 width = width + w + 1
if width >= (line_width - cwidth_tab[" "]) then if width >= (line_width - cwidth_tab[" "]) then
@ -572,15 +575,28 @@ local function make_line_texture(line, lineno, pos, line_width, line_height, cwi
maxw = math_max(width, maxw) maxw = math_max(width, maxw)
end end
if #chars < MAX_INPUT_CHARS then if #chars < MAX_INPUT_CHARS then
local tex
if wide_type == "u" then
local page = math.floor(code / 256)
local idx = code % 256
local x = idx % 16
local y = math.floor(idx / 16)
tex = UNIFONT_TEX:format(page, x, y)
if font_size == 32 then
tex = tex .. "\\^[resize\\:32x32"
end
else
tex = char_tex_wide(font_name, wide_c)
end
table.insert(chars, { table.insert(chars, {
off = ch_offs, off = ch_offs,
tex = char_tex_wide(font_name, wide_c), tex = tex,
col = ("%X"):format(cur_color), col = ("%X"):format(cur_color),
}) })
end end
ch_offs = ch_offs + w ch_offs = ch_offs + w
end end
i = i + #wide_c + 3 i = i + wide_skip
else else
local w = cwidth_tab[c] local w = cwidth_tab[c]
if w then if w then
@ -662,26 +678,23 @@ function signs_lib.make_sign_texture(lines, pos)
local char_width local char_width
local char_width_wide local char_width_wide
local colorbgw local colorbgw
local widemult = 1 local widemult = meta:get_int("widefont") == 1 and 0.5 or 1
local force_unicode_font = meta:get_int("unifont") == 1
if meta:get_int("widefont") == 1 then if def.font_size and (def.font_size == 32 or def.font_size == 31) then
widemult = 0.5 font_size = 32
end line_width = math.floor(signs_lib.avgwidth32 * def.chars_per_line) * (def.horiz_scaling * widemult)
line_height = signs_lib.lineheight32
if def.font_size and def.font_size == 31 then char_width = signs_lib.charwidth32
font_size = 31 char_width_wide = signs_lib.charwidth_wide32
line_width = math.floor(signs_lib.avgwidth31 * def.chars_per_line) * (def.horiz_scaling * widemult) colorbgw = signs_lib.colorbgw32
line_height = signs_lib.lineheight31
char_width = signs_lib.charwidth31
char_width_wide = signs_lib.charwidth_wide31
colorbgw = signs_lib.colorbgw31
else else
font_size = 15 font_size = 16
line_width = math.floor(signs_lib.avgwidth15 * def.chars_per_line) * (def.horiz_scaling * widemult) line_width = math.floor(signs_lib.avgwidth16 * def.chars_per_line) * (def.horiz_scaling * widemult)
line_height = signs_lib.lineheight15 line_height = signs_lib.lineheight16
char_width = signs_lib.charwidth15 char_width = signs_lib.charwidth16
char_width_wide = signs_lib.charwidth_wide15 char_width_wide = signs_lib.charwidth_wide16
colorbgw = signs_lib.colorbgw15 colorbgw = signs_lib.colorbgw16
end end
local texture = { ("[combine:%dx%d"):format(line_width, (line_height + def.line_spacing) * def.number_of_lines * def.vert_scaling) } local texture = { ("[combine:%dx%d"):format(line_width, (line_height + def.line_spacing) * def.number_of_lines * def.vert_scaling) }
@ -689,7 +702,7 @@ function signs_lib.make_sign_texture(lines, pos)
local lineno = 0 local lineno = 0
for i = 1, #lines do for i = 1, #lines do
if lineno >= def.number_of_lines then break end if lineno >= def.number_of_lines then break end
local linetex, ln = make_line_texture(lines[i], lineno, pos, line_width, line_height, char_width, font_size, colorbgw, char_width_wide) local linetex, ln = make_line_texture(lines[i], lineno, pos, line_width, line_height, char_width, font_size, colorbgw, char_width_wide, force_unicode_font)
table.insert(texture, linetex) table.insert(texture, linetex)
lineno = ln + 1 lineno = ln + 1
end end
@ -729,7 +742,9 @@ local function make_infotext(text)
local lines = signs_lib.split_lines_and_words(text) or {} local lines = signs_lib.split_lines_and_words(text) or {}
local lines2 = { } local lines2 = { }
for _, line in ipairs(lines) do for _, line in ipairs(lines) do
table.insert(lines2, (table.concat(line, " "):gsub("#[0-9a-fA-F]", ""):gsub("##", "#"))) table.insert(lines2, (table.concat(line, " "):gsub("#[0-9a-fA-F#^]", function (s)
return s:sub(2):find("[#^]") and s:sub(2) or ""
end)))
end end
return table.concat(lines2, "\n") return table.concat(lines2, "\n")
end end
@ -893,10 +908,6 @@ function signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locke
local def = minetest.registered_items[signname] local def = minetest.registered_items[signname]
local ppos = minetest.get_pointed_thing_position(pointed_thing)
local pnode = minetest.get_node(ppos)
local pdef = minetest.registered_items[pnode.name]
if def.allow_onpole and signs_lib.check_for_pole(pos, pointed_thing) and not controls.sneak then if def.allow_onpole and signs_lib.check_for_pole(pos, pointed_thing) and not controls.sneak then
local newparam2 local newparam2
local lookdir = minetest.yaw_to_dir(placer:get_look_horizontal()) local lookdir = minetest.yaw_to_dir(placer:get_look_horizontal())
@ -905,7 +916,6 @@ function signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locke
else else
newparam2 = minetest.dir_to_facedir(lookdir) newparam2 = minetest.dir_to_facedir(lookdir)
end end
local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = no_wall_name.."_onpole", param2 = newparam2}) minetest.swap_node(pos, {name = no_wall_name.."_onpole", param2 = newparam2})
elseif def.allow_onpole_horizontal and signs_lib.check_for_horizontal_pole(pos, pointed_thing) and not controls.sneak then elseif def.allow_onpole_horizontal and signs_lib.check_for_horizontal_pole(pos, pointed_thing) and not controls.sneak then
local newparam2 local newparam2
@ -915,15 +925,12 @@ function signs_lib.after_place_node(pos, placer, itemstack, pointed_thing, locke
else else
newparam2 = minetest.dir_to_facedir(lookdir) newparam2 = minetest.dir_to_facedir(lookdir)
end end
local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = no_wall_name.."_onpole_horiz", param2 = newparam2}) minetest.swap_node(pos, {name = no_wall_name.."_onpole_horiz", param2 = newparam2})
elseif def.allow_hanging and signs_lib.check_for_ceiling(pointed_thing) and not controls.sneak then elseif def.allow_hanging and signs_lib.check_for_ceiling(pointed_thing) and not controls.sneak then
local newparam2 = minetest.dir_to_facedir(placer:get_look_dir()) local newparam2 = minetest.dir_to_facedir(placer:get_look_dir())
local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = no_wall_name.."_hanging", param2 = newparam2}) minetest.swap_node(pos, {name = no_wall_name.."_hanging", param2 = newparam2})
elseif def.allow_yard and signs_lib.check_for_floor(pointed_thing) and not controls.sneak then elseif def.allow_yard and signs_lib.check_for_floor(pointed_thing) and not controls.sneak then
local newparam2 = minetest.dir_to_facedir(placer:get_look_dir()) local newparam2 = minetest.dir_to_facedir(placer:get_look_dir())
local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = no_wall_name.."_yard", param2 = newparam2}) minetest.swap_node(pos, {name = no_wall_name.."_yard", param2 = newparam2})
elseif def.paramtype2 == "facedir" and signs_lib.check_for_ceiling(pointed_thing) then elseif def.paramtype2 == "facedir" and signs_lib.check_for_ceiling(pointed_thing) then
minetest.swap_node(pos, {name = signname, param2 = 6}) minetest.swap_node(pos, {name = signname, param2 = 6})
@ -1225,7 +1232,7 @@ minetest.register_lbm({
run_at_every_load = true, run_at_every_load = true,
action = function(pos, node) action = function(pos, node)
-- yeah, yeah... I know I'm hashing a block pos, but it's still just a set of coords -- yeah, yeah... I know I'm hashing a block pos, but it's still just a set of coords
local hash = minetest.hash_node_position(vector.floor(vector.divide(pos, core.MAP_BLOCKSIZE))) local hash = minetest.hash_node_position(vector.floor(vector.divide(pos, minetest.MAP_BLOCKSIZE)))
if not signs_lib.block_list[hash] then if not signs_lib.block_list[hash] then
signs_lib.block_list[hash] = true signs_lib.block_list[hash] = true
signs_lib.totalblocks = signs_lib.totalblocks + 1 signs_lib.totalblocks = signs_lib.totalblocks + 1
@ -1242,9 +1249,9 @@ minetest.register_chatcommand("regen_signs", {
local totalsigns = 0 local totalsigns = 0
for b in pairs(signs_lib.block_list) do for b in pairs(signs_lib.block_list) do
local blockpos = minetest.get_position_from_hash(b) local blockpos = minetest.get_position_from_hash(b)
local pos1 = vector.multiply(blockpos, core.MAP_BLOCKSIZE) local pos1 = vector.multiply(blockpos, minetest.MAP_BLOCKSIZE)
local pos2 = vector.add(pos1, core.MAP_BLOCKSIZE - 1) local pos2 = vector.add(pos1, minetest.MAP_BLOCKSIZE - 1)
if minetest.get_node_or_nil(vector.add(pos1, core.MAP_BLOCKSIZE/2)) then if minetest.get_node_or_nil(vector.add(pos1, minetest.MAP_BLOCKSIZE/2)) then
local signs_in_block = minetest.find_nodes_in_area(pos1, pos2, {"group:sign"}) local signs_in_block = minetest.find_nodes_in_area(pos1, pos2, {"group:sign"})
allsigns[#allsigns + 1] = signs_in_block allsigns[#allsigns + 1] = signs_in_block
totalsigns = totalsigns + #signs_in_block totalsigns = totalsigns + #signs_in_block
@ -1289,20 +1296,23 @@ function get_sign_formspec(pos, nodename)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local txt = meta:get_string("text") local txt = meta:get_string("text")
local state = meta:get_int("unifont") == 1 and "on" or "off"
local formspec = { local formspec = {
"size[6,4]", "size[6,4]",
"background[-0.5,-0.5;7,5;signs_lib_sign_bg.png]", "background[-0.5,-0.5;7,5;signs_lib_sign_bg.png]",
"image[0.1,2.4;7,1;signs_lib_sign_color_palette.png]", "image[0.1,2.4;7,1;signs_lib_sign_color_palette.png]",
"textarea[0.15,-0.2;6.3,2.8;text;;" .. minetest.formspec_escape(txt) .. "]", "textarea[0.15,-0.2;6.3,2.8;text;;" .. minetest.formspec_escape(txt) .. "]",
"button_exit[3,3.4;2,1;ok;" .. S("Write") .. "]" "button_exit[3.7,3.4;2,1;ok;" .. S("Write") .. "]",
"label[0.3,3.4;Unicode font]",
"image_button[0.6,3.7;1,0.6;signs_lib_switch_" .. state .. ".png;uni_"
.. state .. ";;;false;signs_lib_switch_interm.png]",
} }
if minetest.registered_nodes[nodename].allow_widefont then if minetest.registered_nodes[nodename].allow_widefont then
local state = "off" state = meta:get_int("widefont") == 1 and "on" or "off"
if meta:get_int("widefont") == 1 then state = "on" end formspec[#formspec+1] = "label[2.1,3.4;Wide font]"
formspec[#formspec+1] = "label[0.9,3.4;Use wide font]" formspec[#formspec+1] = "image_button[2.3,3.7;1,0.6;signs_lib_switch_" .. state .. ".png;wide_"
formspec[#formspec+1] = "image_button[1.1,3.7;1,0.6;signs_lib_switch_" .. state .. ".png;"
.. state .. ";;;false;signs_lib_switch_interm.png]" .. state .. ";;;false;signs_lib_switch_interm.png]"
end end
@ -1325,23 +1335,40 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
pos_string pos_string
)) ))
signs_lib.update_sign(pos, fields) signs_lib.update_sign(pos, fields)
elseif fields.on or fields.off then elseif fields.wide_on or fields.wide_off or fields.uni_on or fields.uni_off then
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local change local change_wide
local change_uni
if fields.on and meta:get_int("widefont") == 1 then if fields.wide_on and meta:get_int("widefont") == 1 then
meta:set_int("widefont", 0) meta:set_int("widefont", 0)
change = true change_wide = true
elseif fields.off and meta:get_int("widefont") == 0 then elseif fields.wide_off and meta:get_int("widefont") == 0 then
meta:set_int("widefont", 1) meta:set_int("widefont", 1)
change = true change_wide = true
end
if fields.uni_on and meta:get_int("unifont") == 1 then
meta:set_int("unifont", 0)
change_uni = true
elseif fields.uni_off and meta:get_int("unifont") == 0 then
meta:set_int("unifont", 1)
change_uni = true
end end
if change then if change_wide then
minetest.log("action", S("@1 flipped the wide-font switch to \"@2\" at @3", minetest.log("action", S("@1 flipped the wide-font switch to \"@2\" at @3",
(playername or ""), (playername or ""),
(fields.on and "off" or "on"), (fields.wide_on and "off" or "on"),
minetest.pos_to_string(pos)
))
signs_lib.update_sign(pos, fields)
minetest.show_formspec(playername, "signs_lib:sign", get_sign_formspec(pos, node.name))
end
if change_uni then
minetest.log("action", S("@1 flipped the unicode-font switch to \"@2\" at @3",
(playername or ""),
(fields.uni_on and "off" or "on"),
minetest.pos_to_string(pos) minetest.pos_to_string(pos)
)) ))
signs_lib.update_sign(pos, fields) signs_lib.update_sign(pos, fields)

View file

@ -1,5 +1,8 @@
-- encoding borrowed from signs_lib fork at https://github.com/lord-server/lord -- encoding borrowed from signs_lib fork at https://github.com/lord-server/lord
-- The "ANSI" encoding here actually refers to "windows-1251", which shows up as
-- "ANSI" on Russian version of MS Windows
local ansi_decode = { local ansi_decode = {
[128] = "\208\130", [128] = "\208\130",
[129] = "\208\131", [129] = "\208\131",
@ -234,7 +237,7 @@ local nmdc = {
[124] = "|" [124] = "|"
} }
function AnsiToUtf8(s) function signs_lib.AnsiToUtf8(s)
local r, b = "" local r, b = ""
for i = 1, s and s:len() or 0 do for i = 1, s and s:len() or 0 do
b = s:byte(i) b = s:byte(i)
@ -255,10 +258,14 @@ function AnsiToUtf8(s)
return r return r
end end
function Utf8ToAnsi(s) function signs_lib.Utf8ToAnsi(s)
local a, j, r, b, scope = 0, 0, "" local r, b = ""
local scope
local j, l, u
for i = 1, s and s:len() or 0 do for i = 1, s and s:len() or 0 do
b = s:byte(i) b = s:byte(i)
-- legacy parser
if b == 0x26 then if b == 0x26 then
r = r .. "&#x26;" r = r .. "&#x26;"
elseif b < 128 then elseif b < 128 then
@ -271,18 +278,57 @@ function Utf8ToAnsi(s)
if scope[b] then if scope[b] then
scope = scope[b] scope = scope[b]
if "string" == type(scope) then if "string" == type(scope) then
r, scope = r .. scope r, scope = r .. scope, nil
j = -1 -- supress general UTF-8 parser
end end
else else
r, scope = r .. "_" scope = nil
end end
elseif utf8_decode[b] then elseif utf8_decode[b] then
scope = utf8_decode[b] scope = utf8_decode[b]
else
r = r .. "_"
end end
-- general UTF-8 parser
if j == -1 then -- supressed by legacy parser
j = nil
elseif b < 0x80 then
if j then
r = r .. "&#ufffd;"
j = nil
end
-- ASCII handled by legacy parser
elseif b >= 0xc0 then
if j then
r = r .. "&#ufffd;"
end
j = i
if b >= 0xf8 then
r = r .. "&#ufffd;"
j = nil
elseif b >= 0xf0 then
l, u = 4, b % (2 ^ 3)
elseif b >= 0xe0 then
l, u = 3, b % (2 ^ 4)
else
l, u = 2, b % (2 ^ 5)
end
else
if j then
u = u * (2 ^ 6) + b % (2 ^ 6)
if i == j + l - 1 then
r = r .. string.format("&#u%x;", u)
j = nil
end
else
r = r .. "&#ufffd;"
end
end
end
if j then
r = r .. "&#ufffd;"
end end
return r return r
end end
signs_lib.wide_character_codes = wide_character_codes signs_lib.wide_character_codes = wide_character_codes
signs_lib.unifont_halfwidth = dofile(signs_lib.path.."/unifont-halfwidth.lua")

View file

@ -7,7 +7,7 @@ signs_lib = {}
signs_lib.path = minetest.get_modpath(minetest.get_current_modname()) signs_lib.path = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(signs_lib.path .. "/intllib.lua") local S = dofile(signs_lib.path .. "/intllib.lua")
signs_lib.gettext = S signs_lib.gettext = S
dofile(signs_lib.path.."/encoding.lua") dofile(signs_lib.path.."/encoding.lua")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

Some files were not shown because too many files have changed in this diff Show more