Auke Kok 8d218d43d6 TExture alpha: fix deprecation warning.
The alpha values here are now no longer used. They are roughly the same
as the original value in the alpha channel, so this looks the same from
my perspective.
2021-07-07 21:20:04 -07:00

1817 lines
50 KiB
Lua

--[[
ITB (insidethebox) minetest game - Copyright (C) 2017-2018 sofar & nore
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1
of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
]]--
local S = minetest.get_translator("nodes")
--[[
nodes.lua - basic node blocks for Inside The Box
]]--
--
-- visual marker for where breakable nodes can be placed
--
local function nm(s)
local ss = string.gsub(s, "_", " ")
return ss:gsub("^%l", string.upper)
end
-- tilecache API
nodes = {}
local tilecache = {}
function nodes.get_tiles(name)
if tilecache[name] then
return tilecache[name]
else
local def = minetest.registered_nodes[name]
local tex
if def.inventory_image and def.inventory_image ~= "" then
tex = def.inventory_image
elseif def.drawtype ~= "normal" then
tex = def.tiles[1] and def.tiles[1].name or def.tiles[1]
else
tex = minetest.inventorycube(
def.tiles[1] and def.tiles[1].name or def.tiles[1],
def.tiles[3] and def.tiles[3].name or def.tiles[3] or
def.tiles[2] and def.tiles[2].name or def.tiles[2] or
def.tiles[1] and def.tiles[1].name or def.tiles[1],
def.tiles[3] and def.tiles[3].name or def.tiles[3] or
def.tiles[2] and def.tiles[2].name or def.tiles[2] or
def.tiles[1] and def.tiles[1].name or def.tiles[1]
)
end
tilecache[name] = tex
return tex
end
end
--
-- handle placement for breakable nodes
--
local on_place_breakable = function(itemstack, placer, pointed_thing)
-- not a node?
if not pointed_thing or pointed_thing.type ~= "node" then
return itemstack
end
-- pass through?
local under = minetest.get_node(pointed_thing.under)
local udef = minetest.registered_nodes[under.name]
if udef.on_rightclick then
return udef.on_rightclick(pointed_thing.under, under, placer, itemstack, pointed_thing)
end
-- placeable here?
local pos = pointed_thing.above
local node = minetest.get_node(pos)
local place = itemstack:get_name()
local name = placer:get_player_name()
-- editing or playing?
if boxes.players_editing_boxes[name] then
-- holding SHIFT?
if placer:get_player_control().sneak then
-- param2
local def = minetest.registered_nodes[place]
local param2 = 0
if def.place_param2 ~= nil then
param2 = def.place_param2
elseif def.paramtype2 == "wallmounted" then
param2 = minetest.dir_to_wallmounted(vector.subtract(
pointed_thing.under, pointed_thing.above))
elseif def.paramtype2 == "facedir" then
param2 = minetest.dir_to_facedir(vector.subtract(
pointed_thing.under, pointed_thing.above))
end
minetest.set_node(pos, {name = place, param2 = param2})
return itemstack
end
if node.name ~= "air" and node.name ~= "nodes:placeholder" then
minetest.chat_send_player(name, S("Can only place this node at an empty node. Clear the space first!"))
return itemstack
end
-- place placeholder information
if node.name ~= "nodes:placeholder" then
minetest.set_node(pos, {name = "nodes:placeholder"})
end
local meta = minetest.get_meta(pos)
local placeable = meta:get_string("placeable")
if placeable == "" then
meta:set_string("placeable", minetest.write_json({[place] = true}))
else
local t = minetest.parse_json(placeable)
t[place] = true
meta:set_string("placeable", minetest.write_json(t))
end
elseif boxes.players_in_boxes[name] then
-- check meta if we can place here
local meta = minetest.get_meta(pos)
if meta:get_string("placed") ~= "" then
return itemstack
end
local placeable = meta:get_string("placeable")
if placeable == "" then
return itemstack
end
local t = minetest.parse_json(placeable)
if not t[place] then
return itemstack
end
-- place and remove one from itemstack
itemstack:take_item()
-- param2
local def = minetest.registered_nodes[place]
local param2 = 0
if def.place_param2 ~= nil then
param2 = def.place_param2
elseif def.paramtype2 == "wallmounted" then
param2 = minetest.dir_to_wallmounted(vector.subtract(
pointed_thing.under, pointed_thing.above))
elseif def.paramtype2 == "facedir" then
param2 = minetest.dir_to_facedir(vector.subtract(
pointed_thing.under, pointed_thing.above))
end
minetest.set_node(pos, {name = place, param2 = param2})
minetest.check_for_falling(pos)
-- preserve metadata
meta = minetest.get_meta(pos)
meta:set_string("placeable", placeable)
-- but set placed to true to avoid fast-rightclick bug
meta:set_string("placed", "true")
return itemstack
else
minetest.log("info", name .. " attempted to place a " .. place .. " outside a box")
return itemstack
end
end
function nodes.after_dig_node_breakable(pos, oldnode, oldmetadata, digger)
-- preserve metadata
minetest.set_node(pos, {name = "nodes:placeholder"})
if not oldmetadata.fields or not oldmetadata.fields.placeable then
return
end
local meta = minetest.get_meta(pos)
meta:set_string("placeable", oldmetadata.fields.placeable)
end
local function on_destruct_breakable(pos)
-- preserve metadata
local placeable = minetest.get_meta(pos):get_string("placeable")
minetest.after(0, function(p)
local node = minetest.get_node(pos)
if node.name == "air" then
-- put the placeholder back if the node was removed
minetest.set_node(pos, {name = "nodes:placeholder"})
end
local meta = minetest.get_meta(pos)
meta:set_string("placeable", p)
end, placeable)
end
function nodes.placeholder_particles(pos)
local meta = minetest.get_meta(pos)
local placeable = meta:get_string("placeable")
if placeable == "" then
return false
end
local nodelist = minetest.parse_json(placeable)
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 3)) do
if obj:is_player() then
local pname = obj:get_player_name()
local itemstack = obj:get_wielded_item()
local name = itemstack:get_name()
if itemstack and nodelist[name] then
minetest.add_particle({
pos = pos,
expirationtime = 0.55,
size = 5,
texture = nodes.get_tiles(name),
glow = 14,
playername = pname,
})
end
end
end
return true
end
minetest.register_node("nodes:placeholder", {
description = S("Placeable node location placeholder"),
inventory_image = "air.png",
wield_image = "air.png",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
floodable = true,
air_equivalent = true,
drop = "",
groups = {not_in_creative_inventory=1},
on_timer = nodes.placeholder_particles,
on_construct = function(pos)
minetest.get_node_timer(pos):start(0.5)
end,
on_destruct = on_destruct_breakable,
after_box_construct = function(pos)
minetest.get_node_timer(pos):start(0.5)
end,
})
-- table format:
-- [1] name, also used for texture
-- [2] true for stair/slab
-- [3] tool if diggable version needs to be added
-- [4] sounds
-- [5] falling node
local nodelist = {
{"bricks_clay", true, "pickaxe", sounds.stone, "clay bricks"},
{"bricks_limestone", true, "pickaxe", sounds.stone, "chiseled limestone"},
{"bricks_marble", true, "pickaxe", sounds.stone, "chiseled marble"},
{"bricks_sandstone", true, "pickaxe", sounds.stone, "sandstone bricks"},
{"bricks_stone", true, "pickaxe", sounds.stone, "stone bricks"},
{"bricks_stone_moss", true, "pickaxe", sounds.stone, "mossy stone bricks"},
{"cobble", true, "pickaxe", sounds.stone, "cobblestone"},
{"cobble_moss", true, "pickaxe", sounds.stone, "mossy cobblestone"},
{"limestone", true, "pickaxe", sounds.stone, "limestone"},
{"marble", true, "pickaxe", sounds.stone, "marble"},
{"sandstone", true, "pickaxe", sounds.stone, "sandstone"},
{"stone", true, "pickaxe", sounds.stone, "stone"},
{"stone_moss", true, "pickaxe", sounds.stone, "mossy stone"},
{"obsidian", true, false, sounds.stone, "obsidian"},
{"bedrock", true, false, sounds.stone, "bedrock"},
{"redrock", true, false, sounds.stone, "red rock"},
{"bronze", false, "pickaxe", sounds.metal, "bronze"},
{"gold", false, "pickaxe", sounds.metal, "gold"},
{"emerald", false, "pickaxe", sounds.stone, "emerald"},
{"iron", false, "pickaxe", sounds.metal, "iron"},
{"clay", false, "shovel", sounds.dirt, "clay"},
{"dirt", false, "shovel", sounds.dirt, "dirt"},
{"gravel", false, "shovel", sounds.gravel, "gravel", 1},
{"sand", false, "shovel", sounds.sand, "sand", 1},
{"wood_dark", true, "axe", sounds.wood, "dark wood"},
{"wood_light", true, "axe", sounds.wood, "light wood"},
{"wood_medium", true, "axe", sounds.wood, "medium wood"},
{"grass", false, false, sounds.grass, "grass block"},
{"snow", false, "shovel", sounds.snow, "snow"},
{"ice", false, "pickaxe", sounds.stone, "ice"},
{"ore_black", false, "pickaxe", sounds.stone, "black ore"},
{"ore_blue", false, "pickaxe", sounds.stone, "blue ore"},
{"ore_brown", false, "pickaxe", sounds.stone, "brown ore"},
{"ore_cyan", false, "pickaxe", sounds.stone, "cyan ore"},
{"ore_gold", false, "pickaxe", sounds.stone, "gold ore"},
{"ore_green", false, "pickaxe", sounds.stone, "green ore"},
{"ore_red", false, "pickaxe", sounds.stone, "red ore"},
}
local function make_stair_slab(name, desc, groups, b1, b2, snd, tex)
if not tex then
tex = name
end
minetest.register_node("nodes:" .. name .. b1 .. "_stairs", {
description = nm(desc .. " stairs" .. b2),
tiles = {tex .. ".png"},
drawtype = "mesh",
mesh = "stairs_stair.obj",
paramtype = "light",
paramtype2 = "facedir",
groups = groups,
selection_box = {
type = "fixed",
fixed = {
{-1/2, -1/2, -1/2, 1/2, 0, 1/2},
{-1/2, 0, 0, 1/2, 1/2, 1/2},
},
},
collision_box = {
type = "fixed",
fixed = {
{-1/2, -1/2, -1/2, 1/2, 0, 1/2},
{-1/2, 0, 0, 1/2, 1/2, 1/2},
},
},
sounds = snd,
})
minetest.register_node("nodes:" .. name .. b1 .. "_slab", {
description = nm(desc .. " slab" .. b2),
tiles = {tex .. ".png"},
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
groups = groups,
node_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, 0, 1/2},
},
sounds = snd,
})
end
for n, v in pairs(nodelist) do
local tex = "blocks_tiles.png^[sheet:8x8:" .. (n - 1) % 8 .. "," .. math.floor((n - 1) / 8)
local groups = {node = 1}
if v[6] then
groups.falling_node = 1
end
if v[4] == sounds.stone then
groups.stone = 1
elseif v[4] == sounds.wood then
groups.wood = 1
end
if v[3] then
-- register diggable node version
local gg = table.copy(groups)
gg[v[3]] = 3
minetest.register_node("nodes:" .. v[1] .. "_breakable", {
description = nm(v[5]),
tiles = {tex},
groups = gg,
sounds = v[4],
})
if v[2] then
make_stair_slab(v[1], v[5], gg, "_breakable", "", v[4], tex)
end
frame.register("nodes:" .. v[1] .. "_breakable")
end
groups.unbreakable = 1
minetest.register_node("nodes:" .. v[1], {
description = nm(v[5]),
tiles = {tex},
groups = groups,
sounds = v[4],
})
if v[2] then
make_stair_slab(v[1], v[5], groups, "", "", v[4], tex)
if groups.stone then
walls.register("nodes:" .. v[1] .. "_wall", nm(v[5] .. " wall"), nm("Middle " .. v[5] .. " wall"), tex, v[4],
groups, {"group:stone"})
else
walls.register("nodes:" .. v[1] .. "_wall", nm(v[5] .. " wall"), nm("Middle " ..v[5] .. " wall"), tex, v[4],
groups, {"group:wood"})
end
end
end
minetest.register_node("nodes:marble_pillar", {
description = S("Marble pillar"),
paramtype2 = "facedir",
tiles = {"marble_pillar_top.png", "marble_pillar_bottom.png", "marble_pillar_side.png"},
groups = {node = 1, unbreakable = 1},
sounds = sounds.stone,
})
minetest.register_node("nodes:marbleb", {
description = S("Marble border"),
tiles = {"blocks_tiles.png^[sheet:8x8:1,1"},
unpushable = true,
groups = {not_in_creative_inventory = 1},
sounds = sounds.stone,
})
minetest.register_node("nodes:bronzeb", {
description = S("Bronze border"),
tiles = {"blocks_tiles.png^[sheet:8x8:0,2"},
unpushable = true,
groups = {not_in_creative_inventory = 1},
sounds = sounds.metal,
})
--
-- wool
--
for n, v in pairs({"yellow", "white", "violet", "red",
"pink", "orange", "magenta", "grey",
"green", "dark_grey", "dark_green", "cyan",
"brown", "blue", "black"}) do
local tex = "wool_tiles.png^[sheet:4x4:" .. (n - 1) % 4 .. "," .. math.floor((n - 1) / 4)
minetest.register_node("nodes:wool_" .. v, {
description = nm(v .. " wool"),
tiles = {tex},
groups = {node = 1, unbreakable = 1},
sounds = sounds.cloth,
})
minetest.register_node("nodes:carpet_" .. v, {
description = nm(v .. " carpet"),
tiles = {tex},
groups = {node = 1, unbreakable = 1},
sounds = sounds.cloth,
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-7/16, -1/2, -7/16, 7/16, -7/16, 7/16},
},
},
})
make_stair_slab("wool_" .. v, nm(v .. " wool"), {node = 1, unbreakable = 1}, "", "", sounds.cloth, tex)
minetest.register_node("nodes:wool_" .. v .. "_breakable", {
description = nm(v .. " wool"),
tiles = {tex},
groups = {axe = 1, node = 1},
sounds = sounds.cloth,
})
make_stair_slab("wool_" .. v, nm(v .. " wool"), {axe = 1, node = 1}, "_breakable", "", sounds.cloth, tex)
frame.register("nodes:wool_" .. v .. "_breakable")
end
-- hardened clay
for n, v in pairs({"black", "violet", "brown", "cyan",
"gray", "green", "blue", "lime",
"pink", "orange", "magenta", "purple",
"red", "silver", "light_brown", "cream",
"yellow"}) do
local tex = "hardened_clay_tiles.png^[sheet:4x5:" .. (n - 1) % 4 .. "," .. math.floor((n - 1) / 4)
minetest.register_node("nodes:hardened_clay_" .. v, {
description = nm(v .. " hardened clay"),
tiles = {tex},
groups = {node = 1, unbreakable = 1},
sounds = sounds.stone,
})
make_stair_slab("hardened_clay_" .. v, nm(v .. " hardened clay"), {node = 1, unbreakable = 1}, "", "", sounds.stone, tex)
minetest.register_node("nodes:hardened_clay_" .. v .. "_breakable", {
description = nm(v .. " hardened clay"),
tiles = {tex},
groups = {pickaxe = 1, node = 1},
sounds = sounds.stone,
})
make_stair_slab("hardened_clay_" .. v, nm(v .. " hardened clay"), {pickaxe = 1, node = 1}, "_breakable", "", sounds.stone, tex)
frame.register("nodes:hardened_clay_" .. v .. "_breakable")
end
-- trunks and leaves
for _, v in pairs({
{"light", 1},
{"medium", 1},
{"dark", 1},
{"fall"},
{"jungle"},
}) do
if v[2] then
minetest.register_node("nodes:trunk_" .. v[1] .. "_breakable", {
description = nm(v[1] .. " trunk"),
tiles = {"trunk_" .. v[1] .. "_top.png", "trunk_" .. v[1] .. "_top.png", "trunk_" .. v[1] .. ".png"},
groups = {axe = 1, node = 1, wood = 1},
paramtype2 = "facedir",
sounds = sounds.wood,
})
minetest.register_node("nodes:trunk_" .. v[1] .. "", {
description = nm(v[1] .. " trunk"),
tiles = {"trunk_" .. v[1] .. "_top.png", "trunk_" .. v[1] .. "_top.png", "trunk_" .. v[1] .. ".png"},
groups = {node = 1, unbreakable = 1, wood = 1},
paramtype2 = "facedir",
sounds = sounds.wood,
})
frame.register("nodes:trunk_" .. v[1] .. "_breakable")
end
minetest.register_node("nodes:leaves_" .. v[1] .. "_breakable", {
description = nm(v[1] .. " leaves"),
drawtype = "allfaces_optional",
paramtype = "light",
tiles = {"leaves_" .. v[1] .. ".png"},
groups = {node = 1, axe = 1, leaves = 1},
sounds = sounds.leaves,
})
minetest.register_node("nodes:leaves_" .. v[1], {
description = nm(v[1] .. " leaves"),
drawtype = "allfaces_optional",
paramtype = "light",
tiles = {"leaves_" .. v[1] .. ".png"},
groups = {node = 1, unbreakable = 1, leaves = 1},
sounds = sounds.leaves,
})
end
-- barrier
minetest.register_node("nodes:barrier", {
description = S("Barrier"),
pointable = true, -- make it easy to understand that it's a barrier
drawtype = "airlike",
inventory_image = "barrier.png",
wield_image = "barrier.png",
sunlight_propagates = true,
paramtype = "light",
unpushable = true,
groups = {not_in_creative_inventory = 1, fall_damage_add_percent = 1000},
collision_box = {
type = "fixed",
-- oversized to prevent crawling through
fixed = {-1,-0.5,-1,1,1,1},
},
})
local function lamp_on_untrigger(pos)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
meta:set_string("on_name", node.name)
node.name = "nodes:lamp_bar_0"
minetest.swap_node(pos, node)
end
-- glass
minetest.register_node("nodes:glass", {
description = S("Glass"),
drawtype = "glasslike_framed_optional",
sunlight_propagates = true,
paramtype = "light",
tiles = {"glass.png"},
groups = {node = 1, unbreakable = 1},
sounds = sounds.glass,
})
minetest.register_node("nodes:glass_breakable", {
description = S("Glass"),
drawtype = "glasslike_framed_optional",
sunlight_propagates = true,
paramtype = "light",
tiles = {"glass.png"},
groups = {node = 1, pickaxe = 1},
sounds = sounds.glass,
})
frame.register("nodes:glass_breakable")
-- light fixtures
for _, v in pairs({14, 11, 8, 0}) do
local on_trigger = function(pos) end
local on_untrigger = function(pos) end
if v == 0 then
on_trigger = function(pos)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
local new_name = meta:get_string("on_name")
if new_name ~= "" then
node.name = new_name
minetest.swap_node(pos, node)
if string.find(new_name, "broken") then
minetest.get_node_timer(pos):start(math.random(50)/10)
end
end
minetest.sound_play("lamp_on", {pos = pos, max_hear_distance = 16, gain = 0.2})
end
else
on_untrigger = lamp_on_untrigger
end
minetest.register_node("nodes:lamp_bar_" .. v, {
description = "Wall lamp (" .. v .. ")",
light_source = v,
sunlight_propagates = true,
tiles = {"lamp_bar.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = false,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {-1, 1/4, 1/4, 1, 1/2, 1/2},
},
groups = {node = 1, unbreakable = 1},
sounds = sounds.glass,
on_rotate = screwdriver.rotate_simple,
on_trigger = on_trigger,
on_untrigger = on_untrigger,
after_dig_node = mech.after_dig,
})
end
minetest.register_node("nodes:lamp_bar_broken", {
description = S("Broken wall lamp (flickering)"),
light_source = 8,
sunlight_propagates = true,
tiles = {"lamp_bar.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = false,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {-1, 1/4, 1/4, 1, 1/2, 1/2},
},
groups = {node = 1, unbreakable = 1},
sounds = sounds.glass,
on_rotate = screwdriver.rotate_simple,
on_trigger = function(pos) end,
on_untrigger = lamp_on_untrigger,
on_timer = function(pos)
local node = minetest.get_node(pos)
minetest.set_node(pos, {name = "nodes:lamp_bar_broken_off", param2 = node.param2})
end,
on_construct = function(pos)
minetest.get_node_timer(pos):start(math.random(50)/10)
end,
after_dig_node = mech.after_dig,
})
minetest.register_node("nodes:lamp_bar_broken_off", {
description = S("Broken wall lamp (flickering, off)"),
sunlight_propagates = true,
tiles = {"lamp_bar.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = false,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {-1, 1/4, 1/4, 1, 1/2, 1/2},
},
groups = {node = 1, unbreakable = 1},
sounds = sounds.glass,
on_rotate = screwdriver.rotate_simple,
on_trigger = function(pos) end,
on_untrigger = lamp_on_untrigger,
on_timer = function(pos)
local node = minetest.get_node(pos)
minetest.set_node(pos, {name = "nodes:lamp_bar_broken", param2 = node.param2})
end,
on_construct = function(pos)
minetest.get_node_timer(pos):start(math.random(50)/10)
end,
after_dig_node = mech.after_dig,
})
-- glowblock
minetest.register_node("nodes:glowblock", {
description = S("Glowblock"),
tiles = {"glowblock.png"},
light_source = 13,
groups = {node = 1, unbreakable = 1},
sounds = sounds.glass,
})
-- lamp blocks
for _, v in pairs({14, 11, 8, 0}) do
local on_trigger = function(pos) end
local on_untrigger = function(pos) end
local tiles = {"lamp_block_on.png"}
if v == 0 then
on_trigger = function(pos)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
local new_name = meta:get_string("on_name")
if new_name ~= "" then
node.name = new_name
minetest.swap_node(pos, node)
end
minetest.sound_play("lamp_on", {pos = pos, max_hear_distance = 16, gain = 0.2})
end
tiles = {"lamp_block_off.png"}
else
on_untrigger = function(pos)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
meta:set_string("on_name", node.name)
node.name = "nodes:lamp_block_0"
minetest.swap_node(pos, node)
end
end
minetest.register_node("nodes:lamp_block_" .. v, {
description = S("Lamp block (@1)", v),
tiles = tiles,
light_source = v,
groups = {node = 1, unbreakable = 1},
sounds = sounds.glass,
on_trigger = on_trigger,
on_untrigger = on_untrigger,
after_dig_node = mech.after_dig,
})
end
local wood_fences = {
{ "wood_dark", S("Dark wood fence") },
{ "wood_light", S("Light wood fence") },
{ "wood_medium", S("Medium wood fence") },
}
for n, wood in ipairs(wood_fences) do
fences.register_fence("nodes:fence_" .. wood[1], {
description = wood[2],
texture = "blocks_tiles.png^[sheet:8x8:" .. n - 1 ..",3",
inventory_image = "default_fence_overlay.png^" .. "blocks_tiles.png^[sheet:8x8:" .. n - 1 ..",3" ..
"^default_fence_overlay.png^[makealpha:255,126,126",
wield_image = "default_fence_overlay.png^" .. "blocks_tiles.png^[sheet:8x8:" .. n - 1 ..",3" ..
"^default_fence_overlay.png^[makealpha:255,126,126",
groups = {node = 1, unbreakable = 1, wood = 1},
sounds = sounds.wood,
})
end
minetest.register_node("nodes:bookshelf", {
description = S("Bookshelf"),
tiles = {"blocks_tiles.png^[sheet:8x8:2,3", "blocks_tiles.png^[sheet:8x8:2,3", "bookshelf.png",
"bookshelf.png", "blocks_tiles.png^[sheet:8x8:2,3"},
sounds = sounds.wood,
paramtype2 = "facedir",
on_rotate = screwdriver.rotate_simple,
groups = {node = 1, unbreakable = 1, wood = 1},
})
minetest.register_node("nodes:workbench", {
description = S("Workbench"),
tiles = {"workbench_top.png", "workbench_top.png", "workbench_side.png"},
sounds = sounds.wood,
paramtype2 = "facedir",
groups = {node = 1, unbreakable = 1, wood = 1},
})
minetest.register_node("nodes:furnace", {
description = S("Furnace (off)"),
tiles = {"furnace_top.png", "furnace_top.png", "furnace_side.png",
"furnace_side.png", "furnace_side.png", "furnace_front_off.png"},
sounds = sounds.stone,
paramtype2 = "facedir",
groups = {node = 1, unbreakable = 1, stone = 1, mech = 1},
on_trigger = function(pos)
local node = minetest.get_node(pos)
node.name = "nodes:furnace_on"
minetest.swap_node(pos, node)
end,
})
minetest.register_node("nodes:furnace_on", {
description = S("Furnace (on)"),
tiles = {"furnace_top.png", "furnace_top.png", "furnace_side.png",
"furnace_side.png", "furnace_side.png", "furnace_front_on.png"},
sounds = sounds.stone,
paramtype2 = "facedir",
light_source = 5,
groups = {node = 1, unbreakable = 1, stone = 1, mech = 1},
on_trigger = function() end,
on_untrigger = function(pos)
local node = minetest.get_node(pos)
node.name = "nodes:furnace"
minetest.swap_node(pos, node)
end
})
-- melon, pumpkin, hay
minetest.register_node("nodes:melon", {
description = S("Melon"),
tiles = {"melon_top.png", "melon_top.png", "melon_side.png"},
sounds = sounds.wood,
paramtype2 = "facedir",
groups = {node = 1, unbreakable = 1},
})
minetest.register_node("nodes:melon_breakable", {
description = S("Melon"),
tiles = {"melon_top.png", "melon_top.png", "melon_side.png"},
sounds = sounds.wood,
paramtype2 = "facedir",
groups = {node = 1, hand = 1},
})
frame.register("nodes:melon_breakable")
minetest.register_node("nodes:pumpkin", {
description = S("Pumpkin"),
tiles = {"pumpkin_top.png", "pumpkin_top.png", "pumpkin_side.png"},
sounds = sounds.wood,
paramtype2 = "facedir",
groups = {node = 1, unbreakable = 1},
})
minetest.register_node("nodes:pumpkin_breakable", {
description = S("Pumpkin"),
tiles = {"pumpkin_top.png", "pumpkin_top.png", "pumpkin_side.png"},
sounds = sounds.wood,
paramtype2 = "facedir",
groups = {node = 1, hand = 1},
})
frame.register("nodes:pumpkin_breakable")
minetest.register_node("nodes:hay", {
description = S("Hay"),
tiles = {"hay_top.png", "hay_top.png", "hay_side.png"},
sounds = sounds.grass,
paramtype2 = "facedir",
groups = {node = 1, unbreakable = 1},
})
minetest.register_node("nodes:hay_breakable", {
description = S("Hay"),
tiles = {"hay_top.png", "hay_top.png", "hay_side.png"},
sounds = sounds.grass,
paramtype2 = "facedir",
groups = {node = 1, hand = 1},
})
frame.register("nodes:hay_breakable")
-- ladders, rope & vines
for _, n in pairs({
{"ladder", "signlike", sounds.wood, S("Ladder")},
{"rope", "plantlike", nil, S("Rope")},
{"vine", "signlike", sounds.leaves, S("Vine")},
}) do
local tex
if n[1] == "vine" then
tex = "plant_tiles.png^[sheet:8x8:2,5"
else
tex = n[1] .. ".png"
end
minetest.register_node("nodes:" .. n[1], {
description = n[4],
drawtype = n[2],
tiles = {tex},
inventory_image = tex,
wield_image = tex,
paramtype = "light",
paramtype2 = n[2] == "signlike" and "wallmounted" or nil,
sunlight_propagates = true,
walkable = false,
climbable = true,
selection_box = n[2] == "signlike" and {type = "wallmounted"} or {
type = "fixed",
fixed = {-3/16, -1/2, -3/16, 3/16, 1/2, 3/16}
},
groups = {node = 1, unbreakable = 1},
sounds = n[3],
})
minetest.register_node("nodes:" .. n[1] .. "_breakable", {
description = n[4],
drawtype = n[2],
tiles = {tex},
inventory_image = tex,
wield_image = tex,
paramtype = "light",
paramtype2 = n[2] == "signlike" and "wallmounted" or nil,
sunlight_propagates = true,
walkable = false,
climbable = true,
selection_box = n[2] == "signlike" and {type = "wallmounted"} or {
type = "fixed",
fixed = {-3/16, -1/2, -3/16, 3/16, 1/2, 3/16}
},
groups = {node = 1, axe = 1},
sounds = n[3],
})
frame.register("nodes:" .. n[1] .. "_breakable")
end
minetest.register_node("nodes:waterlily", {
description = S("Waterlily"),
drawtype = "nodebox",
sunlight_propagates = true,
tiles = {"plant_tiles.png^[sheet:8x8:3,5"},
inventory_image = "plant_tiles.png^[sheet:8x8:3,5",
wield_image = "plant_tiles.png^[sheet:8x8:3,5",
walkable = true,
node_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -7/16, 1/2}
},
liquids_pointable = true,
paramtype = "light",
paramtype2 = "facedir",
groups = { node = 1 },
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
if not pos then
return itemstack
end
-- fixme pass through on_rightclick if present (item frame)
local node = minetest.get_node(pos)
if not node then
return itemstack
end
local name = itemstack:get_name()
local rng = PseudoRandom(pos.x % 16 + ((pos.z % 16) * 16) + ((pos.y % 16) * 256))
minetest.set_node(pointed_thing.above, {name = name, param2 = rng:next(0, 3)})
end,
})
--frame.register("nodes:waterlily")
-- Trampolines
for _, v in pairs({20, 40, 60, 80}) do
minetest.register_node("nodes:trampoline_" .. v , {
description = S("Trampoline (@1%)", v),
tiles = {"trampoline_top.png", "trampoline_top.png", "trampoline_side.png"},
paramtype = "light",
paramtype2 = "facedir",
groups = {node = 1, bouncy = v, fall_damage_add_percent = -v},
sounds = sounds.wood,
})
end
-- Sponge (cushion, nojump broken in 0.4.16)
minetest.register_node("nodes:sponge", {
description = S("Sponge"),
tiles = {"sponge.png"},
paramtype = "light",
groups = {node = 1, fall_damage_add_percent = -25, disable_jump = 1},
sounds = sounds.dirt,
-- fall ~25 nodes, normal node = 1 heart left, sponge = 5 hearts left
})
-- TNT
local function tnt_explode(pos)
minetest.remove_node(pos)
minetest.sound_play("tnt_explosion", {pos = pos, max_hear_distance = 64, gain = 1.0})
minetest.add_particlespawner({
amount = 128,
time = 1.0,
minpos = vector.add(pos, -2.5),
maxpos = vector.add(pos, 2.5),
minvel = {x = 0, y = 0, z = 0},
maxvel = {x = 0, y = 0, z = 0},
minacc = {x = 0, y = 0, z = 0},
maxacc = {x = 0, y = 0, z = 0},
minexptime = 0.4,
maxexptime = 0.4,
minsize = 8,
maxsize = 16,
texture = "explosion_effect_animated.png",
glow = 14,
animation = {
type = "sheet_2d",
frames_w = 8,
frames_h = 1,
frame_length = 0.05,
},
})
end
minetest.register_node("nodes:tnt", {
description = S("TNT"),
tiles = {"itb_tnt_top.png", "itb_tnt_bottom.png", "itb_tnt_side.png"},
paramtype = "light",
groups = {node = 1},
on_trigger = tnt_explode,
sounds = sounds.wood,
})
minetest.register_node("nodes:tnt_diggable", {
description = S("TNT"),
tiles = {"itb_tnt_top.png", "itb_tnt_bottom.png", "itb_tnt_side.png"},
paramtype = "light",
groups = {node = 1, hand = 1},
on_trigger = tnt_explode,
sounds = sounds.wood,
})
frame.register("nodes:tnt_diggable")
-- special nodes
-- liquids
minetest.register_node("nodes:water_source", {
description = S("Water source"),
drawtype = "liquid",
tiles = {
{
name = "water_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 2.0,
},
},
},
special_tiles = {
-- New-style water source material (mostly unused)
{
name = "water_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 2.0,
},
backface_culling = false,
},
},
--alpha = 160,
use_texture_alpha = "blend",
paramtype = "light",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 2,
liquidtype = "source",
liquid_alternative_flowing = "nodes:water_flowing",
liquid_alternative_source = "nodes:water_source",
liquid_viscosity = 1,
post_effect_color = {a = 203, r = 30, g = 60, b = 90},
groups = {water = 3, liquid = 3, puts_out_fire = 1, cools_lava = 1},
sounds = sounds.water,
})
minetest.register_node("nodes:water_flowing", {
description = S("Flowing water"),
drawtype = "flowingliquid",
tiles = {"water.png"},
special_tiles = {
{
name = "water_flowing_animated.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.2,
},
},
{
name = "water_flowing_animated.png",
backface_culling = true,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.2,
},
},
},
--alpha = 160,
use_texture_alpha = "blend",
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 2,
liquidtype = "flowing",
liquid_alternative_flowing = "nodes:water_flowing",
liquid_alternative_source = "nodes:water_source",
liquid_viscosity = 1,
post_effect_color = {a = 203, r = 30, g = 60, b = 90},
groups = {water = 3, liquid = 3, puts_out_fire = 1,
not_in_creative_inventory = 1, cools_lava = 1},
sounds = sounds.water,
})
minetest.register_node("nodes:river_water_source", {
description = S("River water source"),
drawtype = "liquid",
tiles = {
{
name = "river_water_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.2,
},
},
},
special_tiles = {
{
name = "river_water_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.2,
},
backface_culling = false,
},
},
--alpha = 160,
use_texture_alpha = "blend",
paramtype = "light",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 2,
liquidtype = "source",
liquid_alternative_flowing = "nodes:river_water_flowing",
liquid_alternative_source = "nodes:river_water_source",
liquid_viscosity = 1,
liquid_renewable = false,
liquid_range = 2,
post_effect_color = {a = 203, r = 30, g = 76, b = 90},
groups = {water = 3, liquid = 3, puts_out_fire = 1, cools_lava = 1},
sounds = sounds.water,
})
minetest.register_node("nodes:river_water_flowing", {
description = S("Flowing river water"),
drawtype = "flowingliquid",
tiles = {"river_water.png"},
special_tiles = {
{
name = "river_water_flowing_animated.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 0.8,
},
},
{
name = "river_water_flowing_animated.png",
backface_culling = true,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 0.8,
},
},
},
--alpha = 160,
use_texture_alpha = "blend",
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 2,
liquidtype = "flowing",
liquid_alternative_flowing = "nodes:river_water_flowing",
liquid_alternative_source = "nodes:river_water_source",
liquid_viscosity = 1,
liquid_renewable = false,
liquid_range = 2,
post_effect_color = {a = 203, r = 30, g = 76, b = 90},
groups = {water = 3, liquid = 3, puts_out_fire = 1,
not_in_creative_inventory = 1, cools_lava = 1},
sounds = sounds.water,
})
minetest.register_node("nodes:lava_source", {
description = S("Lava source"),
drawtype = "liquid",
tiles = {
{
name = "lava_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.0,
},
},
},
special_tiles = {
-- New-style lava source material (mostly unused)
{
name = "lava_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.0,
},
backface_culling = false,
},
},
paramtype = "light",
light_source = 8,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "source",
liquid_alternative_flowing = "nodes:lava_flowing",
liquid_alternative_source = "nodes:lava_source",
liquid_viscosity = 7,
liquid_renewable = false,
damage_per_second = 4 * 2,
post_effect_color = {a = 191, r = 255, g = 64, b = 0},
groups = {lava = 3, liquid = 2, igniter = 1},
})
minetest.register_node("nodes:lava_flowing", {
description = S("Flowing lava"),
drawtype = "flowingliquid",
tiles = {"lava.png"},
special_tiles = {
{
name = "lava_flowing_animated.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.3,
},
},
{
name = "lava_flowing_animated.png",
backface_culling = true,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.3,
},
},
},
paramtype = "light",
paramtype2 = "flowingliquid",
light_source = 8,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "flowing",
liquid_alternative_flowing = "nodes:lava_flowing",
liquid_alternative_source = "nodes:lava_source",
liquid_viscosity = 7,
liquid_renewable = false,
damage_per_second = 4 * 2,
post_effect_color = {a = 191, r = 255, g = 64, b = 0},
groups = {lava = 3, liquid = 2, igniter = 1,
not_in_creative_inventory = 1},
})
-- lava cooling ABM
lava_check_pos = {
{x = 0, y = 1, z = 0},
{x = 1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = -1, y = 0, z = 0},
{x = 0, y = 0, z = -1},
{x = 0, y = -1, z = 0},
}
minetest.register_abm({
label = "lava cooling abm",
nodenames = {"group:lava"},
neighbors = {"group:cools_lava"},
interval = 1, -- as fast as server allows, usually 1
chance = 1,
action = function(pos)
for k, v in pairs(lava_check_pos) do
local node = minetest.get_node(vector.add(pos, v))
local def = minetest.registered_nodes[node.name]
if def.groups.cools_lava then
if k == 1 and minetest.get_node(pos).name == "nodes:lava_source" then
minetest.set_node(pos, {name = "nodes:obsidian"})
else
minetest.set_node(pos, {name = "nodes:cobble_breakable"})
end
return
end
end
end,
})
--
-- particles
--
minetest.register_abm({
label = "smoke",
nodenames = {"group:torch", "nodes:fire"},
neighbors = {"air"},
interval = 0.1,
chance = 100,
catch_up = false,
action = function(pos, node)
pos.y = pos.y + 0.5
minetest.add_particle({
pos = vector.add(pos, math.random(50)/100 - 0.25),
velocity = {x = math.random(20)/100 - 0.1, y = 0.3, z = math.random(20)/100 - 0.1},
expirationtime = 2.3,
size = math.random(10)/5 + 2,
texture = "smoke_animated.png",
animation = {
type = "sheet_2d",
frames_w = 8,
frames_h = 1,
frame_length = 0.3,
},
})
end,
})
minetest.register_abm({
label = "water_bubble",
nodenames = {"group:water"},
neighbors = {"air"},
interval = 0.2,
chance = 800,
catch_up = false,
action = function(pos, node, a, b)
minetest.add_particle({
pos = vector.add(pos, math.random(50)/100 - 0.25),
velocity = {x = 0, y = 0.3, z = 0},
expirationtime = 0.78,
size = math.random(10)/5 + 1,
texture = "bubble_effect_animated.png",
animation = {
type = "sheet_2d",
frames_w = 8,
frames_h = 1,
frame_length = 0.1,
},
})
end,
})
minetest.register_abm({
label = "lava_bubble",
nodenames = {"group:lava"},
neighbors = {"air"},
interval = 0.1,
chance = 200,
catch_up = false,
action = function(pos, node, a, b)
pos.y = pos.y + 0.5
minetest.add_particle({
pos = vector.add(pos, math.random(50)/100 - 0.25),
velocity = {x = 0, y = 0.2, z = 0},
expirationtime = 0.78,
size = math.random(10)/5 + 1,
texture = "lava_bubble_animated.png",
glow = 13,
animation = {
type = "sheet_2d",
frames_w = 8,
frames_h = 1,
frame_length = 0.1,
},
})
end,
})
-- tnt
-- fire
minetest.register_node("nodes:fire", {
description = S("Fire"),
drawtype = "firelike",
tiles = {
{
name = "fire_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.6,
},
},
},
inventory_image = "fire.png",
paramtype = "light",
light_source = 13,
walkable = false,
buildable_to = true,
sunlight_propagates = true,
damage_per_second = 4,
groups = {igniter = 2},
selection_box = {type = "fixed",
fixed = {-7/16, -1/2, -7/16, 7/16, 6/16, 7/16}},
drop = "",
})
frame.register("nodes:fire")
-- chests:
-- empty (fake) chest
-- chest-with-key
-- chest-with-tool
for _, names in ipairs({
{ "nothing", S("Empty chest") },
{ "boxes:nexus", S("Chest with nexus") },
{ "tools:axe", S("Chest with axe") },
{ "tools:pickaxe", S("Chest with pickaxe") },
{ "tools:shovel", S("Chest with shovel") },
{ "tools:sword", S("Chest with sword") },
{ "tools:flint_and_steel", S("Chest with flint and steel") },
}) do
local name = names[1]
local desc = names[2]
minetest.register_node("nodes:chest_with_" .. string.gsub(name, ":", "_"), {
description = desc,
drawtype = "mesh",
paramtype = "light",
paramtype2 = "facedir",
mesh = "chest_close.obj",
tiles = {"chest.png"},
groups = { node = 1, trigger = 1 },
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
minetest.sound_play("chest_open", {pos = pos})
node.name = "nodes:chest_open"
mech.trigger(pos)
minetest.after(1.0, mech.untrigger, pos)
minetest.swap_node(pos, node)
minetest.get_node_timer(pos):start(3.0)
if name ~= "nothing" then
if itemstack:item_fits(name) then
itemstack:add_item(name)
return itemstack
end
clicker:get_inventory():add_item("main", name)
end
return itemstack
end,
sounds = sounds.wood,
})
end
minetest.register_alias("nodes:chest_with_boxes_findme_item", "nodes:chest_with_boxes_nexus")
minetest.register_node("nodes:chest_open", {
description = S("Open chest"),
drawtype = "mesh",
paramtype = "light",
paramtype2 = "facedir",
mesh = "chest_open.obj",
tiles = {"chest.png"},
on_timer = function(pos)
minetest.sound_play("chest_close", {pos = pos})
local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = "nodes:chest_with_nothing", param2 = node.param2})
end,
groups = {node = 0},
sounds = sounds.wood,
})
-- grass variants
-- flowers
-- farming plants
-- flowerpot combos
for _, n in pairs({
{"grass_1", "3,3", 56, "grass (1)"},
{"grass_2", "4,3", 56, "grass (2)"},
{"grass_3", "5,3", 56, "grass (3)"},
{"grass_4", "6,3", 56, "grass (4)"},
{"grass_5", "7,3", 56, "grass (5)"},
{"dead_bush", "1,3", 56, "dead bush"},
{"rose", "6,4", 9, "rose"},
{"dandelion", "0,3", 9, "dandelion"},
{"white_tulip", "4,5", 9, "white tulip"},
{"allium", "6,2", 9, "allium"},
{"orchid", "3,4", 9, "orchid"},
{"daisy", "7,2", 9, "daisy"},
{"houstonia", "0,4", 9, "bluet"},
{"paeonia", "4,4", 9, "peony"},
{"wheat_stage_0", "0,1", 11, "wheat (stage 0)"},
{"wheat_stage_1", "1,1", 11, "wheat (stage 1)"},
{"wheat_stage_2", "2,1", 11, "wheat (stage 2)"},
{"wheat_stage_3", "3,1", 11, "wheat (stage 3)"},
{"wheat_stage_4", "4,1", 11, "wheat (stage 4)"},
{"wheat_stage_5", "5,1", 11, "wheat (stage 5)"},
{"wheat_stage_6", "6,1", 11, "wheat (stage 6)"},
{"wheat_stage_7", "7,1", 11, "wheat (stage 7)"},
{"potatoes_stage_0", "4,0", 10, "potatoes (stage 0)"},
{"potatoes_stage_1", "5,0", 10, "potatoes (stage 1)"},
{"potatoes_stage_2", "6,0", 10, "potatoes (stage 2)"},
{"potatoes_stage_3", "7,0", 10, "potatoes (stage 3)"},
{"carrots_stage_0", "0,0", 8, "carrots (stage 0)"},
{"carrots_stage_1", "1,0", 8, "carrots (stage 1)"},
{"carrots_stage_2", "2,0", 8, "carrots (stage 2)"},
{"carrots_stage_3", "3,0", 8, "carrots (stage 3)"},
{"sapling_1", "0,2", 8, "light sapling", true},
{"sapling_2", "1,2", 8, "medium sapling", true},
{"sapling_3", "2,2", 8, "jungle sapling", true},
{"sapling_4", "3,2", 8, "dark sapling", true},
{"sapling_5", "4,2", 8, "fall sapling", true},
{"sapling_6", "5,2", 8, "pine sapling", true},
{"mushroom_red", "2,4", 10, "red mushroom", true},
{"mushroom_brown", "1,4", 10, "brown mushroom", true},
{"fern", "2,3", 9, "fern"},
{"reeds", "5,4", 0, "reeds"},
}) do
local tex = "plant_tiles.png^[sheet:8x8:" .. n[2]
minetest.register_node("nodes:" .. n[1], {
description = nm(n[4]),
drawtype = "plantlike",
place_param2 = n[3],
tiles = {tex},
inventory_image = tex,
wield_image = tex,
paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
floodable = true,
selection_box = {
type = "fixed",
fixed = {-1/4, -1/2, -1/4, 1/4, 1/4, 1/4},
},
sounds = sounds.grass,
groups = {node = 1},
})
if n[5] then
minetest.register_node("nodes:" .. n[1] .. "_breakable", {
description = nm(n[4]),
drawtype = "plantlike",
place_param2 = n[3],
tiles = {tex},
inventory_image = tex,
wield_image = tex,
paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
floodable = true,
selection_box = {
type = "fixed",
fixed = {-1/4, -1/2, -1/4, 1/4, 1/4, 1/4},
},
sounds = sounds.grass,
groups = {node = 1, hand = 1},
})
frame.register("nodes:" .. n[1] .. "_breakable")
else
frame.register("nodes:" .. n[1])
end
minetest.register_node("nodes:flowerpot_" ..n[1], {
description = S("Pot with @1", n[4]),
drawtype = "mesh",
mesh = "flowerpot.obj",
tiles = {
{name = "pot.png"},
{name = tex},
{name = "itb_blank.png"},
},
paramtype = "light",
paramtype2 = "facedir",
on_rotate = screwdriver.rotate_simple,
sunlight_propagates = true,
collision_box = {
type = "fixed",
fixed = {-1/4, -1/2, -1/4, 1/4, -1/8, 1/4},
},
selection_box = {
type = "fixed",
fixed = {-1/4, -1/2, -1/4, 1/4, 1/2, 1/4},
},
sounds = sounds.stone,
groups = {node = 1},
})
end
-- seeds
for _, m in pairs({
{"melon", "0,5", S("Melon seeds")},
{"wheat", "1,5", S("Wheat seeds")},
{"pumpkin", "7,4", S("Pumpkin seeds")},
}) do
local n = m[1]
local tex = "plant_tiles.png^[sheet:8x8:" .. m[2]
minetest.register_node("nodes:" .. n .. "_seeds", {
description = m[3],
drawtype = "signlike",
tiles = {tex},
inventory_image = tex,
wield_image = tex,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
floodable = true,
selection_box = {
type = "fixed",
fixed = {-7/16, -1/2, -7/16, 7/16, -7/16, 7/16},
},
sounds = sounds.grass,
groups = {node = 1},
})
minetest.register_node("nodes:" .. n .. "_seeds_breakable", {
description = m[3],
drawtype = "signlike",
tiles = {tex},
inventory_image = tex,
wield_image = tex,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
walkable = false,
buildable_to = true,
floodable = true,
selection_box = {
type = "fixed",
fixed = {-7/16, -1/2, -7/16, 7/16, -7/16, 7/16},
},
sounds = sounds.grass,
groups = {node = 1, hand = 1},
})
frame.register("nodes:" .. n .. "_seeds_breakable")
end
-- empty flowerpot
minetest.register_node("nodes:flowerpot_empty", {
description = S("Empty pot"),
drawtype = "mesh",
mesh = "flowerpot.obj",
tiles = {
{name = "pot.png"},
{name = "blank.png"},
},
paramtype = "light",
sunlight_propagates = true,
collision_box = {
type = "fixed",
fixed = {-1/4, -1/2, -1/4, 1/4, -1/8, 1/4},
},
selection_box = {
type = "fixed",
fixed = {-1/4, -1/2, -1/4, 1/4, 1/2, 1/4},
},
sounds = sounds.stone,
groups = {node = 1},
})
-- soil
for _, v in pairs({
{ "soil", S("Soil") },
{ "soil_wet", S("Wet soil") },
}) do
-- register diggable node version
minetest.register_node("nodes:" .. v[1] .. "_breakable", {
description = v[2],
tiles = {v[1] .. ".png", "blocks_tiles.png^[sheet:8x8:5,2"},
groups = {node = 1, shovel = 1},
sounds = sounds.dirt,
})
minetest.register_node("nodes:" .. v[1], {
description = v[2],
tiles = {v[1] .. ".png", "blocks_tiles.png^[sheet:8x8:5,2"},
groups = {node = 1, unbreakable = 1},
sounds = sounds.dirt,
})
frame.register("nodes:" .. v[1] .. "_breakable")
end
-- dirt with grass,
minetest.register_node("nodes:dirt_with_grass_breakable", {
description = S("Dirt with grass"),
tiles = {"blocks_tiles.png^[sheet:8x8:3,3", "blocks_tiles.png^[sheet:8x8:5,2", "grass_side.png"},
groups = {node = 1, shovel = 1},
sounds = sounds.dirt,
})
minetest.register_node("nodes:dirt_with_grass", {
description = S("Dirt with grass"),
tiles = {"blocks_tiles.png^[sheet:8x8:3,3", "blocks_tiles.png^[sheet:8x8:5,2", "grass_side.png"},
groups = {node = 1, unbreakable = 1},
sounds = sounds.dirt,
})
frame.register("nodes:dirt_with_grass_breakable")
-- dirt with podzol
minetest.register_node("nodes:dirt_with_podzol_breakable", {
description = S("Dirt with podzol"),
tiles = {"podzol.png", "blocks_tiles.png^[sheet:8x8:5,2", "podzol_side.png"},
groups = {node = 1, shovel = 1},
sounds = sounds.dirt,
})
minetest.register_node("nodes:dirt_with_podzol", {
description = S("Dirt with podzol"),
tiles = {"podzol.png", "blocks_tiles.png^[sheet:8x8:5,2", "podzol_side.png"},
groups = {node = 1, unbreakable = 1},
sounds = sounds.dirt,
})
frame.register("nodes:dirt_with_podzol_breakable")
-- mycelium
minetest.register_node("nodes:mycelium_breakable", {
description = S("Mycelium"),
tiles = {"mycelium_top.png", "blocks_tiles.png^[sheet:8x8:5,2", "mycelium_side.png"},
groups = {node = 1, shovel = 1},
sounds = sounds.dirt,
})
minetest.register_node("nodes:mycelium", {
description = S("Mycelium"),
tiles = {"mycelium_top.png", "blocks_tiles.png^[sheet:8x8:5,2", "mycelium_side.png"},
groups = {node = 1, unbreakable = 1},
sounds = sounds.dirt,
})
frame.register("nodes:mycelium_breakable")
-- dirt with snow
minetest.register_node("nodes:dirt_with_snow_breakable", {
description = S("Dirt with snow"),
tiles = {"blocks_tiles.png^[sheet:8x8:4,3", "blocks_tiles.png^[sheet:8x8:5,2", "grass_side_snowed.png"},
groups = {node = 1, shovel = 1},
sounds = sounds.snow,
})
minetest.register_node("nodes:dirt_with_snow", {
description = S("Dirt with snow"),
tiles = {"blocks_tiles.png^[sheet:8x8:4,3", "blocks_tiles.png^[sheet:8x8:5,2", "grass_side_snowed.png"},
groups = {node = 1, unbreakable = 1},
sounds = sounds.snow,
})
frame.register("nodes:dirt_with_snow_breakable")
minetest.register_node("nodes:snow_ledge", {
description = S("Snow ledge"),
paramtype = "light",
drop = {},
groups = {node = 1, hand = 1, dig_immediate = 3, attached_node = 1, falling_node = 1},
sounds = sounds.snow,
tiles = {"blocks_tiles.png^[sheet:8x8:4,3"},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-1/2, -1/2, -1/2, 1/2, -1/4, 1/2},
},
},
})
local lines = {
{ "blue", S("Blue line"), "line" },
{ "gray", S("Gray line"), "line" },
{ "green", S("Green line"), "line" },
{ "rail", S("Rail"), "rail" },
{ "red", S("Red line"), "line" },
}
for i, v in ipairs(lines) do
minetest.register_node("nodes:line_" .. v[1], {
description = v[2],
drawtype = "raillike",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
tiles = {
"line_tiles.png^[sheet:4x5:2," .. i-1,
"line_tiles.png^[sheet:4x5:1," .. i-1,
"line_tiles.png^[sheet:4x5:3," .. i-1,
"line_tiles.png^[sheet:4x5:0," .. i-1,
},
wield_image = "line_tiles.png^[sheet:4x5:2," .. i-1,
inventory_image = "line_tiles.png^[sheet:4x5:2," .. i-1,
selection_box = {type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -7/16, 1/2},
},
groups = {node = 1, unbreakable = 1, connect_to_raillike = minetest.raillike_group(v[3]) },
sounds = sounds.wood,
})
end
-- attach breakable callbacks to everything
for name, def in pairs(minetest.registered_nodes) do
assert(def.groups)
if def.groups.shovel or def.groups.axe or def.groups.pickaxe or def.groups.hand then
local toolinfo = S("Can be obtained by the player")
if def.groups.shovel then
toolinfo = S("Can be dug with a shovel by the player")
elseif def.groups.axe then
toolinfo = S("Can be chopped with an axe by the player")
elseif def.groups.pickaxe then
toolinfo = S("Can be dug with a pickaxe by the player")
elseif def.groups.hand then
toolinfo = S("Can be picked up by the player")
end
local desc = def.description
minetest.override_item(name, {
description = desc .. "\n" .. toolinfo,
on_place = on_place_breakable,
on_destruct = on_destruct_breakable,
after_dig_node = nodes.after_dig_node_breakable,
node_placement_prediction = "",
})
end
end