diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index a79c970cd..f37b34444 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -2,8 +2,8 @@ mcl_util = {} -- Updates all values in t using values from to*. function table.update(t, ...) - for _, to in ipairs{...} do - for k,v in pairs(to) do + for _, to in ipairs {...} do + for k, v in pairs(to) do t[k] = v end end @@ -12,8 +12,8 @@ end -- Updates nil values in t using values from to*. function table.update_nil(t, ...) - for _, to in ipairs{...} do - for k,v in pairs(to) do + for _, to in ipairs {...} do + for k, v in pairs(to) do if t[k] == nil then t[k] = v end @@ -22,9 +22,9 @@ function table.update_nil(t, ...) return t end -local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default",false) +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default", false) local LOG_MODULE = "[MCL2]" -function mcl_util.mcl_log (message, module, bypass_default_logger) +function mcl_util.mcl_log(message, module, bypass_default_logger) local selected_module = LOG_MODULE if module then selected_module = module @@ -34,7 +34,6 @@ function mcl_util.mcl_log (message, module, bypass_default_logger) end end - function mcl_util.file_exists(name) if type(name) ~= "string" then return end local f = io.open(name) @@ -69,7 +68,7 @@ function mcl_util.rotate_axis_and_place(itemstack, placer, pointed_thing, infini local undef = minetest.registered_nodes[unode.name] if undef and undef.on_rightclick then undef.on_rightclick(pointed_thing.under, unode, placer, - itemstack, pointed_thing) + itemstack, pointed_thing) return end local fdir = minetest.dir_to_facedir(placer:get_look_dir()) @@ -151,23 +150,23 @@ end function mcl_util.get_double_container_neighbor_pos(pos, param2, side) if side == "right" then if param2 == 0 then - return {x=pos.x-1, y=pos.y, z=pos.z} + return {x = pos.x - 1, y = pos.y, z = pos.z} elseif param2 == 1 then - return {x=pos.x, y=pos.y, z=pos.z+1} + return {x = pos.x, y = pos.y, z = pos.z + 1} elseif param2 == 2 then - return {x=pos.x+1, y=pos.y, z=pos.z} + return {x = pos.x + 1, y = pos.y, z = pos.z} elseif param2 == 3 then - return {x=pos.x, y=pos.y, z=pos.z-1} + return {x = pos.x, y = pos.y, z = pos.z - 1} end else if param2 == 0 then - return {x=pos.x+1, y=pos.y, z=pos.z} + return {x = pos.x + 1, y = pos.y, z = pos.z} elseif param2 == 1 then - return {x=pos.x, y=pos.y, z=pos.z-1} + return {x = pos.x, y = pos.y, z = pos.z - 1} elseif param2 == 2 then - return {x=pos.x-1, y=pos.y, z=pos.z} + return {x = pos.x - 1, y = pos.y, z = pos.z} elseif param2 == 3 then - return {x=pos.x, y=pos.y, z=pos.z+1} + return {x = pos.x, y = pos.y, z = pos.z + 1} end end end @@ -185,7 +184,7 @@ end function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_inventory, dst_list, condition) local size = src_inventory:get_size(src_list) local stack - for i=1, size do + for i = 1, size do stack = src_inventory:get_stack(src_list, i) if not stack:is_empty() and (condition == nil or condition(stack, src_inventory, src_list, dst_inventory, dst_list)) then return i @@ -288,10 +287,10 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, -- Main inventory for most container types if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 or sctype == 7 then source_list = "main" - -- Furnace: output + -- Furnace: output elseif sctype == 4 then source_list = "dst" - -- Unknown source container type. Bail out + -- Unknown source container type. Bail out else return false end @@ -344,7 +343,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, -- Main inventory for most container types if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 or dctype == 7 then destination_list = "main" - -- Furnace source slot + -- Furnace source slot elseif dctype == 4 then destination_list = "src" end @@ -409,7 +408,7 @@ end -- Returns true if item (itemstring or ItemStack) can be used as a furnace fuel. -- Returns false otherwise function mcl_util.is_fuel(item) - return minetest.get_craft_result({method="fuel", width=1, items={item}}).time ~= 0 + return minetest.get_craft_result({method = "fuel", width = 1, items = {item}}).time ~= 0 end -- Returns a on_place function for plants @@ -456,7 +455,7 @@ function mcl_util.generate_on_place_plant_function(condition) if success then if idef.sounds and idef.sounds.place then - minetest.sound_play(idef.sounds.place, {pos=pointed_thing.above, gain=1}, true) + minetest.sound_play(idef.sounds.place, {pos = pointed_thing.above, gain = 1}, true) end end itemstack = new_itemstack @@ -643,78 +642,80 @@ end local function roundN(n, d) if type(n) ~= "number" then return n end - local m = 10^d - return math.floor(n * m + 0.5) / m + local m = 10 ^ d + return math.floor(n * m + 0.5) / m end -local function close_enough(a,b) - local rt=true +local function close_enough(a, b) + local rt = true if type(a) == "table" and type(b) == "table" then - for k,v in pairs(a) do - if roundN(v,2) ~= roundN(b[k],2) then - rt=false + for k, v in pairs(a) do + if roundN(v, 2) ~= roundN(b[k], 2) then + rt = false break end end else - rt = roundN(a,2) == roundN(b,2) + rt = roundN(a, 2) == roundN(b, 2) end return rt end -local function props_changed(props,oldprops) - local changed=false - local p={} - for k,v in pairs(props) do - if not close_enough(v,oldprops[k]) then - p[k]=v - changed=true +local function props_changed(props, oldprops) + local changed = false + local p = {} + for k, v in pairs(props) do + if not close_enough(v, oldprops[k]) then + p[k] = v + changed = true end end - return changed,p + return changed, p end --tests for roundN -local test_round1=15 -local test_round2=15.00199999999 -local test_round3=15.00111111 -local test_round4=15.00999999 +local test_round1 = 15 +local test_round2 = 15.00199999999 +local test_round3 = 15.00111111 +local test_round4 = 15.00999999 -assert(roundN(test_round1,2)==roundN(test_round1,2)) -assert(roundN(test_round1,2)==roundN(test_round2,2)) -assert(roundN(test_round1,2)==roundN(test_round3,2)) -assert(roundN(test_round1,2)~=roundN(test_round4,2)) +assert(roundN(test_round1, 2) == roundN(test_round1, 2)) +assert(roundN(test_round1, 2) == roundN(test_round2, 2)) +assert(roundN(test_round1, 2) == roundN(test_round3, 2)) +assert(roundN(test_round1, 2) ~= roundN(test_round4, 2)) -- tests for close_enough -local test_cb = {-0.35,0,-0.35,0.35,0.8,0.35} --collisionboxes -local test_cb_close = {-0.351213,0,-0.35,0.35,0.8,0.351212} -local test_cb_diff = {-0.35,0,-1.35,0.35,0.8,0.35} +local test_cb = {-0.35, 0, -0.35, 0.35, 0.8, 0.35} --collisionboxes +local test_cb_close = {-0.351213, 0, -0.35, 0.35, 0.8, 0.351212} +local test_cb_diff = {-0.35, 0, -1.35, 0.35, 0.8, 0.35} local test_eh = 1.65 --eye height local test_eh_close = 1.65123123 local test_eh_diff = 1.35 -local test_nt = { r = 225, b = 225, a = 225, g = 225 } --nametag -local test_nt_diff = { r = 225, b = 225, a = 0, g = 225 } +local test_nt = {r = 225, b = 225, a = 225, g = 225} --nametag +local test_nt_diff = {r = 225, b = 225, a = 0, g = 225} -assert(close_enough(test_cb,test_cb_close)) -assert(not close_enough(test_cb,test_cb_diff)) -assert(close_enough(test_eh,test_eh_close)) -assert(not close_enough(test_eh,test_eh_diff)) -assert(not close_enough(test_nt,test_nt_diff)) --no floats involved here +assert(close_enough(test_cb, test_cb_close)) +assert(not close_enough(test_cb, test_cb_diff)) +assert(close_enough(test_eh, test_eh_close)) +assert(not close_enough(test_eh, test_eh_diff)) +assert(not close_enough(test_nt, test_nt_diff)) --no floats involved here --tests for properties_changed -local test_properties_set1={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }} -local test_properties_set2={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 225, g = 225 }} +local test_properties_set1 = {collisionbox = {-0.35, 0, -0.35, 0.35, 0.8, 0.35}, eye_height = 0.65, + nametag_color = {r = 225, b = 225, a = 225, g = 225}} +local test_properties_set2 = {collisionbox = {-0.35, 0, -0.35, 0.35, 0.8, 0.35}, eye_height = 1.35, + nametag_color = {r = 225, b = 225, a = 225, g = 225}} -local test_p1,_=props_changed(test_properties_set1,test_properties_set1) -local test_p2,_=props_changed(test_properties_set1,test_properties_set2) +local test_p1, _ = props_changed(test_properties_set1, test_properties_set1) +local test_p2, _ = props_changed(test_properties_set1, test_properties_set2) assert(not test_p1) assert(test_p2) -function mcl_util.set_properties(obj,props) - local changed,p=props_changed(props,obj:get_properties()) +function mcl_util.set_properties(obj, props) + local changed, p = props_changed(props, obj:get_properties()) if changed then obj:set_properties(p) end @@ -729,6 +730,243 @@ function mcl_util.set_bone_position(obj, bone, pos, rot) end end +---Return a function to use in `on_place`. +--- +---Allow to bypass the `buildable_to` node field in a `on_place` callback. +--- +---You have to make sure that the nodes you return true for have `buildable_to = true`. +---@param func fun(node_name: string): boolean Return `true` if node must not replace the buildable_to node which have `node_name` +---@return fun(itemstack: ItemStack, placer: ObjectRef, pointed_thing: pointed_thing, param2: integer): ItemStack? +function mcl_util.bypass_buildable_to(func) + -------------------------- + -- MINETEST CODE: UTILS -- + -------------------------- + + local function copy_pointed_thing(pointed_thing) + return { + type = pointed_thing.type, + above = pointed_thing.above and vector.copy(pointed_thing.above), + under = pointed_thing.under and vector.copy(pointed_thing.under), + ref = pointed_thing.ref, + } + end + + local function user_name(user) + return user and user:get_player_name() or "" + end + + -- Returns a logging function. For empty names, does not log. + local function make_log(name) + return name ~= "" and minetest.log or function() end + end + + local function check_attached_node(p, n, group_rating) + local def = core.registered_nodes[n.name] + local d = vector.zero() + if group_rating == 3 then + -- always attach to floor + d.y = -1 + elseif group_rating == 4 then + -- always attach to ceiling + d.y = 1 + elseif group_rating == 2 then + -- attach to facedir or 4dir direction + if (def.paramtype2 == "facedir" or + def.paramtype2 == "colorfacedir") then + -- Attach to whatever facedir is "mounted to". + -- For facedir, this is where tile no. 5 point at. + + -- The fallback vector here is in case 'facedir to dir' is nil due + -- to voxelmanip placing a wallmounted node without resetting a + -- pre-existing param2 value that is out-of-range for facedir. + -- The fallback vector corresponds to param2 = 0. + d = core.facedir_to_dir(n.param2) or vector.new(0, 0, 1) + elseif (def.paramtype2 == "4dir" or + def.paramtype2 == "color4dir") then + -- Similar to facedir handling + d = core.fourdir_to_dir(n.param2) or vector.new(0, 0, 1) + end + elseif def.paramtype2 == "wallmounted" or + def.paramtype2 == "colorwallmounted" then + -- Attach to whatever this node is "mounted to". + -- This where tile no. 2 points at. + + -- The fallback vector here is used for the same reason as + -- for facedir nodes. + d = core.wallmounted_to_dir(n.param2) or vector.new(0, 1, 0) + else + d.y = -1 + end + local p2 = vector.add(p, d) + local nn = core.get_node(p2).name + local def2 = core.registered_nodes[nn] + if def2 and not def2.walkable then + return false + end + return true + end + + return function(itemstack, placer, pointed_thing, param2) + ------------------- + -- MINETEST CODE -- + ------------------- + local def = itemstack:get_definition() + if def.type ~= "node" or pointed_thing.type ~= "node" then + return itemstack + end + + local under = pointed_thing.under + local oldnode_under = minetest.get_node_or_nil(under) + local above = pointed_thing.above + local oldnode_above = minetest.get_node_or_nil(above) + local playername = user_name(placer) + local log = make_log(playername) + + if not oldnode_under or not oldnode_above then + log("info", playername .. " tried to place" + .. " node in unloaded position " .. minetest.pos_to_string(above)) + return itemstack + end + + local olddef_under = minetest.registered_nodes[oldnode_under.name] + olddef_under = olddef_under or minetest.nodedef_default + local olddef_above = minetest.registered_nodes[oldnode_above.name] + olddef_above = olddef_above or minetest.nodedef_default + + if not olddef_above.buildable_to and not olddef_under.buildable_to then + log("info", playername .. " tried to place" + .. " node in invalid position " .. minetest.pos_to_string(above) + .. ", replacing " .. oldnode_above.name) + return itemstack + end + + --------------------- + -- CUSTOMIZED CODE -- + --------------------- + + -- Place above pointed node + local place_to = vector.copy(above) + + -- If node under is buildable_to, check for callback result and place into it instead + if olddef_under.buildable_to and not func(oldnode_under.name) then + log("info", "node under is buildable to") + place_to = vector.copy(under) + end + + ------------------- + -- MINETEST CODE -- + ------------------- + + if minetest.is_protected(place_to, playername) then + log("action", playername + .. " tried to place " .. def.name + .. " at protected position " + .. minetest.pos_to_string(place_to)) + minetest.record_protection_violation(place_to, playername) + return itemstack + end + + local oldnode = minetest.get_node(place_to) + local newnode = {name = def.name, param1 = 0, param2 = param2 or 0} + + -- Calculate direction for wall mounted stuff like torches and signs + if def.place_param2 ~= nil then + newnode.param2 = def.place_param2 + elseif (def.paramtype2 == "wallmounted" or + def.paramtype2 == "colorwallmounted") and not param2 then + local dir = vector.subtract(under, above) + newnode.param2 = minetest.dir_to_wallmounted(dir) + -- Calculate the direction for furnaces and chests and stuff + elseif (def.paramtype2 == "facedir" or + def.paramtype2 == "colorfacedir" or + def.paramtype2 == "4dir" or + def.paramtype2 == "color4dir") and not param2 then + local placer_pos = placer and placer:get_pos() + if placer_pos then + local dir = vector.subtract(above, placer_pos) + newnode.param2 = minetest.dir_to_facedir(dir) + log("info", "facedir: " .. newnode.param2) + end + end + + local metatable = itemstack:get_meta():to_table().fields + + -- Transfer color information + if metatable.palette_index and not def.place_param2 then + local color_divisor = nil + if def.paramtype2 == "color" then + color_divisor = 1 + elseif def.paramtype2 == "colorwallmounted" then + color_divisor = 8 + elseif def.paramtype2 == "colorfacedir" then + color_divisor = 32 + elseif def.paramtype2 == "color4dir" then + color_divisor = 4 + elseif def.paramtype2 == "colordegrotate" then + color_divisor = 32 + end + if color_divisor then + local color = math.floor(metatable.palette_index / color_divisor) + local other = newnode.param2 % color_divisor + newnode.param2 = color * color_divisor + other + end + end + + -- Check if the node is attached and if it can be placed there + local an = minetest.get_item_group(def.name, "attached_node") + if an ~= 0 and + not check_attached_node(place_to, newnode, an) then + log("action", "attached node " .. def.name .. + " cannot be placed at " .. minetest.pos_to_string(place_to)) + return itemstack + end + + log("action", playername .. " places node " + .. def.name .. " at " .. minetest.pos_to_string(place_to)) + + -- Add node and update + minetest.add_node(place_to, newnode) + + -- Play sound if it was done by a player + if playername ~= "" and def.sounds and def.sounds.place then + minetest.sound_play(def.sounds.place, { + pos = place_to, + exclude_player = playername, + }, true) + end + + local take_item = true + + -- Run callback + if def.after_place_node then + -- Deepcopy place_to and pointed_thing because callback can modify it + local place_to_copy = vector.copy(place_to) + local pointed_thing_copy = copy_pointed_thing(pointed_thing) + if def.after_place_node(place_to_copy, placer, itemstack, + pointed_thing_copy) then + take_item = false + end + end + + -- Run script hook + for _, callback in ipairs(minetest.registered_on_placenodes) do + -- Deepcopy pos, node and pointed_thing because callback can modify them + local place_to_copy = vector.copy(place_to) + local newnode_copy = {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} + local oldnode_copy = {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} + local pointed_thing_copy = copy_pointed_thing(pointed_thing) + if callback(place_to_copy, newnode_copy, placer, oldnode_copy, itemstack, pointed_thing_copy) then + take_item = false + end + end + + if take_item then + itemstack:take_item() + end + return itemstack + end +end + --[[Check for a protection violation in a given area. -- -- Applies is_protected() to a 3D lattice of points in the defined volume. The points are spaced diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr index f8a441fdc..4f9071825 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=Andesit ist ein magmatisches Gestein. Apple=Apfel Apples are food items which can be eaten.=Äpfel sind essbare Gegenstände. Barrier=Barriere -Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Barrieren sind unsichtbare feste Blöcke. Sie sind nützlich, um Grenzen für Abenteuerkarten und ähnliches zu bauen. Monster und Tiere werden auf Barrieren nicht auftauchen, und Zäune verbinden sich nicht mit Barrieren. Andere Blöcke können an Barrieren gebaut werden, wie bei allen anderen Blöcken. +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Barrieren sind unsichtbare feste Blöcke. Sie sind nützlich, um Grenzen für Abenteuerkarten und ähnliches zu bauen. Monster und Tiere werden auf Barrieren nicht auftauchen, und Zäune verbinden sich nicht mit Barrieren. Andere Blöcke können an Barrieren gebaut werden, wie bei allen anderen Blöcken. Bedrock=Grundgestein Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Grundgestein ist ein sehr harter Gesteinstyp. Er kann unter normalen Umständen nicht abgebaut, zerstört, aufgesammelt oder verschoben werden, außer im Kreativmodus. Birch Bark=Birkenrinde diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index 0f8656520..cf16e5bda 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=La andesita es una roca ígnea. Apple=Manzana Apples are food items which can be eaten.=Las manzanas son alimentos que se pueden comer. Barrier=Barrera -Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Las barreras son bloques transitables invisibles. Se utilizan para crear límites de mapas de aventura y similares. Los monstruos y los animales no aparecerán en las barreras, y las cercas no se conectan a las barreras. Otros bloques pueden construirse sobre barreras como en cualquier otro bloque. +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Las barreras son bloques transitables invisibles. Se utilizan para crear límites de mapas de aventura y similares. Los monstruos y los animales no aparecerán en las barreras, y las cercas no se conectan a las barreras. Otros bloques pueden construirse sobre barreras como en cualquier otro bloque. Bedrock=Lecho de roca Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=El lecho de roca es un tipo de roca muy duro. No se puede romper, destruir, recoger o mover por medios normales, a menos que esté en modo creativo. Birch Bark=Madera de abedul sin corteza diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index ad6c09b08..7dbe3b55a 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=L'andésite est une roche ignée. Apple=Pomme Apples are food items which can be eaten.=Les pommes sont des aliments qui peuvent être consommés. Barrier=Barrière invisible -Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Les barrières sont des blocs accessibles à pied. Ils sont utilisés pour créer des limites de cartes d'aventure et similaires. Les monstres et les animaux n'apparaissent pas sur les barrières, et les clôtures ne se connectent pas aux barrières. D'autres blocs peuvent être construits sur des barrières comme sur n'importe quel autre bloc. +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Les barrières sont des blocs accessibles à pied. Ils sont utilisés pour créer des limites de cartes d'aventure et similaires. Les monstres et les animaux n'apparaissent pas sur les barrières, et les clôtures ne se connectent pas aux barrières. D'autres blocs peuvent être construits sur des barrières comme sur n'importe quel autre bloc. Bedrock=Bedrock Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Le bedrock est un type de roche très dur. Il ne peut pas être brisé, détruit, collecté ou déplacé par des moyens normaux, sauf en mode créatif. Birch Bark=Bois de Bouleau @@ -286,3 +286,6 @@ Stackable=Empilable Crying Obsidian=Obsidienne pleureuse Crying obsidian is a luminous obsidian that can generate as part of ruined portals.=L'obsidienne pleureuse est une obsidienne luminause qui peut être générée dans les portails en ruine. Enchanted Golden Apple=Pomme dorée enchantée +Light=Lumière +Lights are invisible blocks. They are used to light up adventure maps and the like.=Les lumières sont des blocs invisibles. Ils sont utilisés pour éclairer les cartes d'aventure. +When you hold a light in hand, you reveal all placed lights in a short distance around you.=Lorsque vous tenez une lumière en main, vous révélez toutes les lumières placées à une courte distance autour de vous. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr index 8e9d7cf8f..669e4bc9b 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=Andezyt jest skałą pochodzenia wulkanicznego. Apple=Jabłko Apples are food items which can be eaten.=Jabłka to przedmioty które można zjeść. Barrier=Bariera -Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Bariery to niewidzialne bloki po których można chodzić. Są użyteczne do tworzenia ograniczeń na mapach przygodowych i im podobnych. Potwory i zwierzęta nie pojawiają się na barierach, a płoty się z nimi nie łączą. Inne bloki mogą być na nich budowane podobnie jak na innych blokach. +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Bariery to niewidzialne bloki po których można chodzić. Są użyteczne do tworzenia ograniczeń na mapach przygodowych i im podobnych. Potwory i zwierzęta nie pojawiają się na barierach, a płoty się z nimi nie łączą. Inne bloki mogą być na nich budowane podobnie jak na innych blokach. Bedrock=Skała macierzysta Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Skała macierzysta jest rodzajem bardzo twardej skały. Nie może być ona zniszczona, zebrana lub przesunięta normalnymi metodami, jeśli nie jesteś w trybie kreatywnym. Birch Bark=Brzozowa kora diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index 831795792..bf8ce9e4f 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=Андезит это камень вулканич Apple=Яблоко Apples are food items which can be eaten.=Яблоки относятся к продуктовым предметам, которые можно есть. Barrier=Барьер -Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Барьеры это невидимые блоки-препятствия. Они могут использоваться, например, для создания границ карты. Монстры и животные не будут появляться на барьерах. Заборы с барьерами визуально не связываются. Другие блоки могут строиться на барьерах, как на любых других блоках. +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Барьеры это невидимые блоки-препятствия. Они могут использоваться, например, для создания границ карты. Монстры и животные не будут появляться на барьерах. Заборы с барьерами визуально не связываются. Другие блоки могут строиться на барьерах, как на любых других блоках. Bedrock=Бедрок Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Бедрок это очень твёрдый камень. Его невозможно сломать, выкопать или сдвинуть обычным способом, за исключением творческого режима. Birch Bark=Кора берёзы diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr b/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr index 0e8280c6e..74f3297a1 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr @@ -23,7 +23,7 @@ Andesite is an igneous rock.=安山岩是一種火成岩。 Apple=蘋果 Apples are food items which can be eaten.=蘋果是一種可以被食用的食物 Barrier=屏障 -Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=屏障是看不見但可行走的方塊。它們通常被用來創建冒險地圖的邊界。怪物和動物不會出現在屏障上,柵欄也不會連接到屏障上。其他方塊可以像在其他方塊上一樣被放置在屏障上。 +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=屏障是看不見但可行走的方塊。它們通常被用來創建冒險地圖的邊界。怪物和動物不會出現在屏障上,柵欄也不會連接到屏障上。其他方塊可以像在其他方塊上一樣被放置在屏障上。 Bedrock=基岩 Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=基岩是一種堅實無比的石頭。除了創造模式的玩家,沒有人可以以正常方式破壞、銷毀、收集或移動它。 Birch Bark=白樺樹皮 diff --git a/mods/ITEMS/mcl_core/locale/template.txt b/mods/ITEMS/mcl_core/locale/template.txt index a7798b9cd..911746699 100644 --- a/mods/ITEMS/mcl_core/locale/template.txt +++ b/mods/ITEMS/mcl_core/locale/template.txt @@ -24,7 +24,7 @@ Andesite is an igneous rock.= Apple= Apples are food items which can be eaten.= Barrier= -Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.= +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.= Bedrock= Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.= Birch Bark= @@ -286,3 +286,6 @@ Stackable= Crying Obsidian= Crying obsidian is a luminous obsidian that can generate as part of ruined portals.= Enchanted Golden Apple= +Light= +Lights are invisible blocks. They are used to light up adventure maps and the like.= +When you hold a light in hand, you reveal all placed lights in a short distance around you.= diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index 5f5b005e2..47949057c 100644 --- a/mods/ITEMS/mcl_core/nodes_misc.lua +++ b/mods/ITEMS/mcl_core/nodes_misc.lua @@ -8,7 +8,14 @@ if mod_screwdriver then on_rotate = screwdriver.rotate_3way end -local alldirs = {{x=0,y=0,z=1}, {x=1,y=0,z=0}, {x=0,y=0,z=-1}, {x=-1,y=0,z=0}, {x=0,y=-1,z=0}, {x=0,y=1,z=0}} +local alldirs = { + vector.new(0, 0, 1), + vector.new(1, 0, 0), + vector.new(0, 0, -1), + vector.new(-1, 0, 0), + vector.new(0, -1, 0), + vector.new(0, 1, 0), +} minetest.register_node("mcl_core:bone_block", { description = S("Bone Block"), @@ -17,7 +24,7 @@ minetest.register_node("mcl_core:bone_block", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {pickaxey=1, building_block=1, material_stone=1}, + groups = {pickaxey = 1, building_block = 1, material_stone = 1}, sounds = mcl_sounds.node_sound_stone_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 2, @@ -41,16 +48,15 @@ minetest.register_node("mcl_core:slimeblock", { type = "regular", }, tiles = {"mcl_core_slime.png"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, - stack_max = 64, + use_texture_alpha = "blend", -- According to Minecraft Wiki, bouncing off a slime block from a height off 255 blocks should result in a bounce height of 50 blocks -- bouncy=44 makes the player bounce up to 49.6. This value was chosen by experiment. -- bouncy=80 was chosen because it is higher than 66 (bounciness of bed) - groups = {dig_immediate=3, bouncy=80,fall_damage_add_percent=-100,deco_block=1}, + groups = {dig_immediate = 3, bouncy = 80, fall_damage_add_percent = -100, deco_block = 1}, sounds = { - dug = {name="slimenodes_dug", gain=0.6}, - place = {name="slimenodes_place", gain=0.6}, - footstep = {name="slimenodes_step", gain=0.3}, + dug = {name = "slimenodes_dug", gain = 0.6}, + place = {name = "slimenodes_place", gain = 0.6}, + footstep = {name = "slimenodes_step", gain = 0.3}, }, _mcl_blast_resistance = 0, _mcl_hardness = 0, @@ -74,7 +80,8 @@ minetest.register_node("mcl_core:slimeblock", { elseif name == "mesecons_pistons:piston_down_sticky_off" or name == "mesecons_pistons:piston_down_normal_off" then piston, piston_down = true, true end - if not( (piston_side and (n-1==neighbor_node.param2)) or (piston_up and (n==5)) or (piston_down and (n==6)) ) then + if not + ((piston_side and (n - 1 == neighbor_node.param2)) or (piston_up and (n == 5)) or (piston_down and (n == 6))) then if piston and piston_pos then if piston_pos.x == neighbor_pos.x and piston_pos.y == neighbor_pos.y and piston_pos.z == neighbor_pos.z then -- Loopback to the same piston! Preventing unwanted behavior: @@ -98,7 +105,6 @@ minetest.register_node("mcl_core:cobweb", { drawtype = "plantlike", paramtype2 = "degrotate", visual_scale = 1.1, - stack_max = 64, tiles = {"mcl_core_web.png"}, inventory_image = "mcl_core_web.png", paramtype = "light", @@ -109,7 +115,8 @@ minetest.register_node("mcl_core:cobweb", { liquid_renewable = false, liquid_range = 0, walkable = false, - groups = {swordy_cobweb=1, shearsy_cobweb=1, fake_liquid=1, disable_jump=1, deco_block=1, dig_by_piston=1, dig_by_water=1,destroy_by_lava_flow=1,}, + groups = {swordy_cobweb = 1, shearsy_cobweb = 1, fake_liquid = 1, disable_jump = 1, deco_block = 1, dig_by_piston = 1, + dig_by_water = 1, destroy_by_lava_flow = 1,}, drop = "mcl_mobitems:string", _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), @@ -131,9 +138,9 @@ minetest.register_node("mcl_core:deadbush", { paramtype = "light", sunlight_propagates = true, walkable = false, - stack_max = 64, buildable_to = true, - groups = {handy=1,shearsy=1, flammable=3,attached_node=1,plant=1,non_mycelium_plant=1,dig_by_water=1,destroy_by_lava_flow=1,deco_block=1, fire_encouragement=60, fire_flammability=100}, + groups = {handy = 1, shearsy = 1, flammable = 3, attached_node = 1, plant = 1, non_mycelium_plant = 1, dig_by_water = 1, + destroy_by_lava_flow = 1, deco_block = 1, fire_encouragement = 60, fire_flammability = 100}, drop = { max_items = 1, items = { @@ -151,7 +158,7 @@ minetest.register_node("mcl_core:deadbush", { sounds = mcl_sounds.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-5/16, -8/16, -5/16, 5/16, 1/16, 5/16}, + fixed = {-5 / 16, -8 / 16, -5 / 16, 5 / 16, 1 / 16, 5 / 16}, }, _mcl_blast_resistance = 0, _mcl_hardness = 0, @@ -159,18 +166,17 @@ minetest.register_node("mcl_core:deadbush", { minetest.register_node("mcl_core:barrier", { description = S("Barrier"), - _doc_items_longdesc = S("Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block."), + _doc_items_longdesc = S("Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block."), _doc_items_usagehelp = S("When you hold a barrier in hand, you reveal all placed barriers in a short distance around you."), drawtype = "airlike", paramtype = "light", inventory_image = "mcl_core_barrier.png", wield_image = "mcl_core_barrier.png", - tiles = { "blank.png" }, - stack_max = 64, + tiles = {"blank.png"}, sunlight_propagates = true, is_ground_content = false, - groups = {creative_breakable=1, not_in_creative_inventory = 1, not_solid = 1 }, - on_blast = function() end, + groups = {creative_breakable = 1, not_in_creative_inventory = 1, not_solid = 1}, + on_blast = function(pos, intensity) end, drop = "", _mcl_blast_resistance = 36000008, _mcl_hardness = -1, @@ -193,11 +199,9 @@ minetest.register_node("mcl_core:barrier", { end -- Use pointed node's on_rightclick function first, if present - local node = minetest.get_node(pointed_thing.under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end + local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing) + if new_stack then + return new_stack end local name = placer:get_player_name() @@ -222,27 +226,84 @@ minetest.register_node("mcl_core:realm_barrier", { paramtype = "light", inventory_image = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX", wield_image = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX", - tiles = { "blank.png" }, - stack_max = 64, + tiles = {"blank.png"}, -- To avoid players getting stuck forever between realms damage_per_second = 8, sunlight_propagates = true, is_ground_content = false, pointable = false, - groups = {not_in_creative_inventory = 1, not_solid = 1 }, - on_blast = function() end, + groups = {not_in_creative_inventory = 1, not_solid = 1}, + on_blast = function(pos, intensity) end, drop = "", _mcl_blast_resistance = 36000008, _mcl_hardness = -1, -- Prevent placement to protect player from screwing up the world, because the node is not pointable and hard to get rid of. node_placement_prediction = "", - on_place = function(pos, placer, itemstack, pointed_thing) - minetest.chat_send_player(placer:get_player_name(), minetest.colorize(mcl_colors.RED, "You can't just place a realm barrier by hand!")) + on_place = function(itemstack, placer, pointed_thing) + if placer then + minetest.chat_send_player(placer:get_player_name(), + minetest.colorize(mcl_colors.RED, "You can't just place a realm barrier by hand!")) + end return end, }) +--- Light blocks +--- TODO: make node only pointable when wielding it + +local light_block_pattern = "^mcl_core:light_(%d+)$" + + +for i = 0, 14 do --minetest.LIGHT_MAX + minetest.register_node("mcl_core:light_" .. i, { + description = S("Light"), + _doc_items_longdesc = S("Lights are invisible blocks. They are used to light up adventure maps and the like."), + _doc_items_usagehelp = S("When you hold a light in hand, you reveal all placed lights in a short distance around you."), + drawtype = "airlike", + paramtype = "light", + walkable = false, + light_source = i, + drop = "", + buildable_to = true, + node_placement_prediction = "", + inventory_image = "mcl_core_light_" .. i .. ".png", + wield_image = "mcl_core_light_" .. i .. ".png", + sunlight_propagates = true, + is_ground_content = false, + groups = {creative_breakable = 1, not_solid = 1, light_block = i + 1}, + on_blast = function(pos, intensity) end, + on_use = function(itemstack, user, pointed_thing) + -- user:get_player_control() returns {} for non players, so we don't need user:is_player() + if pointed_thing.type == "node" and string.match(minetest.get_node(pointed_thing.under).name, light_block_pattern) and not user:get_player_control().sneak then + minetest.dig_node(pointed_thing.under) + return + end + itemstack:set_name("mcl_core:light_" .. ((i == 14) and 0 or i + 1)) + return itemstack + end, + on_place = mcl_util.bypass_buildable_to(function(node_name) + return string.match(node_name, light_block_pattern) + end), + after_place_node = function(pos, placer, itemstack, pointed_thing) + if not placer then + return + end + minetest.add_particle({ + pos = pos, + expirationtime = 1, + size = 8, + texture = "mcl_core_light_" .. i .. ".png", + glow = 14, + playername = placer:get_player_name() + }) + end, + _mcl_blast_resistance = 36000008, + _mcl_hardness = -1, + }) +end + + -- The void below the bedrock. Void damage is handled in mcl_playerplus. @@ -259,15 +320,17 @@ minetest.register_node("mcl_core:void", { buildable_to = false, inventory_image = "mcl_core_void.png", wield_image = "mcl_core_void.png", - stack_max = 64, sunlight_propagates = true, is_ground_content = false, - groups = { not_in_creative_inventory = 1 }, - on_blast = function() end, + groups = {not_in_creative_inventory = 1}, + on_blast = function(pos, intensity) end, -- Prevent placement to protect player from screwing up the world, because the node is not pointable and hard to get rid of. node_placement_prediction = "", - on_place = function(pos, placer, itemstack, pointed_thing) - minetest.chat_send_player(placer:get_player_name(), minetest.colorize(mcl_colors.RED, "You can't just place the void by hand!")) + on_place = function(itemstack, placer, pointed_thing) + if placer then + minetest.chat_send_player(placer:get_player_name(), + minetest.colorize(mcl_colors.RED, "You can't just place the void by hand!")) + end return end, drop = "", diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_0.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_0.png new file mode 100644 index 000000000..ba7b78474 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_0.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_1.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_1.png new file mode 100644 index 000000000..9d3aed216 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_1.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_10.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_10.png new file mode 100644 index 000000000..bdea1d56c Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_10.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_11.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_11.png new file mode 100644 index 000000000..3e7c8e863 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_11.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_12.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_12.png new file mode 100644 index 000000000..4b7bc671f Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_12.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_13.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_13.png new file mode 100644 index 000000000..66c617e2a Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_13.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_14.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_14.png new file mode 100644 index 000000000..47828a0d6 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_14.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_2.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_2.png new file mode 100644 index 000000000..692f7a5fa Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_2.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_3.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_3.png new file mode 100644 index 000000000..a30458b61 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_3.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_4.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_4.png new file mode 100644 index 000000000..89c7510ff Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_4.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_5.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_5.png new file mode 100644 index 000000000..a1c8c9a2f Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_5.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_6.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_6.png new file mode 100644 index 000000000..2ef86b8f5 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_6.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_7.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_7.png new file mode 100644 index 000000000..2adfc2729 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_7.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_8.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_8.png new file mode 100644 index 000000000..bf11f8384 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_8.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_light_9.png b/mods/ITEMS/mcl_core/textures/mcl_core_light_9.png new file mode 100644 index 000000000..12c4ee769 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_light_9.png differ diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 0faa9c53f..28822d1bc 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -627,7 +627,7 @@ minetest.register_globalstep(function(dtime) -- Show positions of barriers when player is wielding a barrier local wi = player:get_wielded_item():get_name() - if wi == "mcl_core:barrier" or wi == "mcl_core:realm_barrier" then + if wi == "mcl_core:barrier" or wi == "mcl_core:realm_barrier" or minetest.get_item_group(wi, "light_block") ~= 0 then local pos = vector.round(player:get_pos()) local r = 8 local vm = get_voxel_manip() @@ -642,11 +642,15 @@ minetest.register_globalstep(function(dtime) for z=pos.z-r, pos.z+r do local vi = area:indexp({x=x, y=y, z=z}) local nodename = get_name_from_content_id(data[vi]) + local light_block_group = minetest.get_item_group(nodename, "light_block") + local tex if nodename == "mcl_core:barrier" then tex = "mcl_core_barrier.png" elseif nodename == "mcl_core:realm_barrier" then tex = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX" + elseif light_block_group ~= 0 then + tex = "mcl_core_light_" .. (light_block_group - 1) .. ".png" end if tex then add_particle({