These will overflow the network buffer and cause dropped packets, making levels unplayable.
1705 lines
45 KiB
Lua
1705 lines
45 KiB
Lua
|
|
--[[
|
|
|
|
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, "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)
|
|
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)
|
|
return itemstack
|
|
else
|
|
minetest.log("info", name .. " attempted to place a " .. place .. " outside a box")
|
|
return itemstack
|
|
end
|
|
end
|
|
|
|
local function 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
|
|
|
|
local function 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 = "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 = 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},
|
|
{"bricks_limestone", true, "pickaxe", sounds.stone},
|
|
{"bricks_marble", true, "pickaxe", sounds.stone},
|
|
{"bricks_sandstone", true, "pickaxe", sounds.stone},
|
|
{"bricks_stone", true, "pickaxe", sounds.stone},
|
|
{"bricks_stone_moss", true, "pickaxe", sounds.stone},
|
|
{"cobble", true, "pickaxe", sounds.stone},
|
|
{"cobble_moss", true, "pickaxe", sounds.stone},
|
|
{"limestone", true, "pickaxe", sounds.stone},
|
|
{"marble", true, "pickaxe", sounds.stone},
|
|
{"sandstone", true, "pickaxe", sounds.stone},
|
|
{"stone", true, "pickaxe", sounds.stone},
|
|
{"stone_moss", true, "pickaxe", sounds.stone},
|
|
{"obsidian", true, false, sounds.stone},
|
|
{"bedrock", true, false, sounds.stone},
|
|
{"redrock", true, false, sounds.stone},
|
|
{"bronze", false, "pickaxe", sounds.metal},
|
|
{"gold", false, "pickaxe", sounds.metal},
|
|
{"emerald", false, "pickaxe", sounds.stone},
|
|
{"iron", false, "pickaxe", sounds.metal},
|
|
{"clay", false, "shovel", sounds.dirt},
|
|
{"dirt", false, "shovel", sounds.dirt},
|
|
{"gravel", false, "shovel", sounds.gravel, 1},
|
|
{"sand", false, "shovel", sounds.sand, 1},
|
|
{"wood_dark", true, "axe", sounds.wood},
|
|
{"wood_light", true, "axe", sounds.wood},
|
|
{"wood_medium", true, "axe", sounds.wood},
|
|
{"grass", false, false, sounds.grass},
|
|
{"snow", false, "shovel", sounds.snow},
|
|
{"ice", false, "pickaxe", sounds.stone},
|
|
{"ore_black", false, "pickaxe", sounds.stone},
|
|
{"ore_blue", false, "pickaxe", sounds.stone},
|
|
{"ore_brown", false, "pickaxe", sounds.stone},
|
|
{"ore_cyan", false, "pickaxe", sounds.stone},
|
|
{"ore_gold", false, "pickaxe", sounds.stone},
|
|
{"ore_green", false, "pickaxe", sounds.stone},
|
|
{"ore_red", false, "pickaxe", sounds.stone},
|
|
}
|
|
|
|
|
|
local function make_stair_slab(name, groups, b1, b2, snd, tex)
|
|
if not tex then
|
|
tex = name
|
|
end
|
|
minetest.register_node("nodes:" .. name .. b1 .. "_stairs", {
|
|
description = nm(name .. " 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(name .. " 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[5] 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[1]),
|
|
tiles = {tex},
|
|
groups = gg,
|
|
sounds = v[4],
|
|
})
|
|
if v[2] then
|
|
make_stair_slab(v[1], 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[1]),
|
|
tiles = {tex},
|
|
groups = groups,
|
|
sounds = v[4],
|
|
})
|
|
if v[2] then
|
|
make_stair_slab(v[1], groups, "", "", v[4], tex)
|
|
if groups.stone then
|
|
walls.register("nodes:" .. v[1] .. "_wall", v[1] .. " Wall", tex, v[4],
|
|
groups, {"group:stone"})
|
|
else
|
|
walls.register("nodes:" .. v[1] .. "_wall", v[1] .. " Wall", tex, v[4],
|
|
groups, {"group:wood"})
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_node("nodes:marble_pillar", {
|
|
description = "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 = "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 = "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, {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, {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.clay,
|
|
})
|
|
make_stair_slab("hardened_clay_" .. v, {node = 1, unbreakable = 1}, "", "", sounds.cloth, tex)
|
|
minetest.register_node("nodes:hardened_clay_" .. v .. "_breakable", {
|
|
description = nm(v .. " hardened clay"),
|
|
tiles = {tex},
|
|
groups = {pickaxe = 1, node = 1},
|
|
sounds = sounds.cloth,
|
|
})
|
|
make_stair_slab("hardened_clay_" .. v, {axe = 1, node = 1}, "_breakable", "", sounds.cloth, 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 = "Barrier",
|
|
pointable = true, -- make it easy to understand that it's a barrier
|
|
drawtype = "airlike",
|
|
inventory_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 = "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 = "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 = "A 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 = "Broken 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 = "Broken 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,
|
|
})
|
|
|
|
for n, wood in ipairs({"wood_dark", "wood_light", "wood_medium"}) do
|
|
fences.register_fence("nodes:fence_" .. wood, {
|
|
description = nm(wood .. " fence"),
|
|
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 = "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 = "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 = "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 = "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 = "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 = "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 = "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 = "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 = "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 = "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"},
|
|
{"rope", "plantlike"},
|
|
{"vine", "signlike"},
|
|
}) 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 = nm(n[1]),
|
|
drawtype = n[2],
|
|
tiles = {tex},
|
|
inventory_image = tex,
|
|
paramtype = "light",
|
|
paramtype2 = "wallmounted",
|
|
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 = sounds.wood,
|
|
})
|
|
minetest.register_node("nodes:" .. n[1] .. "_breakable", {
|
|
description = nm(n[1]),
|
|
drawtype = n[2],
|
|
tiles = {tex},
|
|
inventory_image = tex,
|
|
paramtype = "light",
|
|
paramtype2 = "wallmounted",
|
|
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 = sounds.wood,
|
|
})
|
|
frame.register("nodes:" .. n[1] .. "_breakable")
|
|
end
|
|
|
|
minetest.register_node("nodes:waterlily", {
|
|
description = "Waterlily",
|
|
drawtype = "nodebox",
|
|
sunlight_propagates = true,
|
|
tiles = {"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 = "Trampoline (" .. 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},
|
|
})
|
|
end
|
|
|
|
-- Sponge (cushion, nojump broken in 0.4.16)
|
|
minetest.register_node("nodes:sponge", {
|
|
description = "Sponge",
|
|
tiles = {"sponge.png"},
|
|
paramtype = "light",
|
|
groups = {node = 1, fall_damage_add_percent = -25, disable_jump = 1},
|
|
-- 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 = "TNT",
|
|
tiles = {"itb_tnt_top.png", "itb_tnt_bottom.png", "itb_tnt_side.png"},
|
|
paramtype = "light",
|
|
groups = {node = 1},
|
|
on_trigger = tnt_explode,
|
|
})
|
|
|
|
minetest.register_node("nodes:tnt_diggable", {
|
|
description = "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,
|
|
})
|
|
frame.register("nodes:tnt_diggable")
|
|
|
|
-- special nodes
|
|
-- liquids
|
|
minetest.register_node("nodes:water_source", {
|
|
description = "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,
|
|
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 = "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,
|
|
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 = "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,
|
|
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 = "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,
|
|
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 = "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},
|
|
sounds = sounds.water,
|
|
})
|
|
|
|
minetest.register_node("nodes:lava_flowing", {
|
|
description = "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},
|
|
sounds = sounds.water,
|
|
})
|
|
|
|
-- 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 = "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 _, name in ipairs({
|
|
"nothing",
|
|
"boxes:nexus",
|
|
"tools:axe",
|
|
"tools:pickaxe",
|
|
"tools:shovel",
|
|
"tools:sword",
|
|
"tools:flint_and_steel",
|
|
}) do
|
|
minetest.register_node("nodes:chest_with_" .. string.gsub(name, ":", "_"), {
|
|
description = "Chest with " .. name,
|
|
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,
|
|
})
|
|
end
|
|
minetest.register_alias("nodes:chest_with_boxes_findme_item", "nodes:chest_with_boxes_nexus")
|
|
|
|
minetest.register_node("nodes:chest_open", {
|
|
description = "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},
|
|
})
|
|
|
|
|
|
|
|
-- grass variants
|
|
-- flowers
|
|
-- farming plants
|
|
-- flowerpot combos
|
|
for _, n in pairs({
|
|
{"grass_1", "3,3", 56},
|
|
{"grass_2", "4,3", 56},
|
|
{"grass_3", "5,3", 56},
|
|
{"grass_4", "6,3", 56},
|
|
{"grass_5", "7,3", 56},
|
|
{"dead_bush", "1,3", 56},
|
|
{"rose", "6,4", 9},
|
|
{"dandelion", "0,3", 9},
|
|
{"white_tulip", "4,5", 9},
|
|
{"allium", "6,2", 9},
|
|
{"orchid", "3,4", 9},
|
|
{"daisy", "7,2", 9},
|
|
{"houstonia", "0,4", 9},
|
|
{"paeonia", "4,4", 9},
|
|
{"wheat_stage_0", "0,1", 11},
|
|
{"wheat_stage_1", "1,1", 11},
|
|
{"wheat_stage_2", "2,1", 11},
|
|
{"wheat_stage_3", "3,1", 11},
|
|
{"wheat_stage_4", "4,1", 11},
|
|
{"wheat_stage_5", "5,1", 11},
|
|
{"wheat_stage_6", "6,1", 11},
|
|
{"wheat_stage_7", "7,1", 11},
|
|
{"potatoes_stage_0", "4,0", 10},
|
|
{"potatoes_stage_1", "5,0", 10},
|
|
{"potatoes_stage_2", "6,0", 10},
|
|
{"potatoes_stage_3", "7,0", 10},
|
|
{"carrots_stage_0", "0,0", 8},
|
|
{"carrots_stage_1", "1,0", 8},
|
|
{"carrots_stage_2", "2,0", 8},
|
|
{"carrots_stage_3", "3,0", 8},
|
|
{"sapling_1", "0,2", 8, true},
|
|
{"sapling_2", "1,2", 8, true},
|
|
{"sapling_3", "2,2", 8, true},
|
|
{"sapling_4", "3,2", 8, true},
|
|
{"sapling_5", "4,2", 8, true},
|
|
{"sapling_6", "5,2", 8, true},
|
|
{"mushroom_red", "2,4", 10, true},
|
|
{"mushroom_brown", "1,4", 10, true},
|
|
{"fern", "2,3", 9},
|
|
{"reeds", "5,4", 0},
|
|
}) do
|
|
local tex = "plant_tiles.png^[sheet:8x8:" .. n[2]
|
|
minetest.register_node("nodes:" .. n[1], {
|
|
description = nm(n[1]),
|
|
drawtype = "plantlike",
|
|
place_param2 = n[3],
|
|
tiles = {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[4] then
|
|
minetest.register_node("nodes:" .. n[1] .. "_breakable", {
|
|
description = nm(n[1]),
|
|
drawtype = "plantlike",
|
|
place_param2 = n[3],
|
|
tiles = {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 = nm("Pot with " .. n[1]),
|
|
drawtype = "mesh",
|
|
mesh = "flowerpot.obj",
|
|
tiles = {
|
|
{name = "pot.png"},
|
|
{name = tex},
|
|
},
|
|
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.wood,
|
|
groups = {node = 1},
|
|
})
|
|
end
|
|
|
|
-- seeds
|
|
for _, m in pairs({
|
|
{"melon", "0,5"},
|
|
{"wheat", "1,5"},
|
|
{"pumpkin", "7,4"},
|
|
}) do
|
|
local n = m[1]
|
|
local tex = "plant_tiles.png^[sheet:8x8:" .. m[2]
|
|
minetest.register_node("nodes:" .. n .. "_seeds", {
|
|
description = nm(n .. " seeds"),
|
|
drawtype = "signlike",
|
|
tiles = {tex},
|
|
inventory_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 = nm(n .. " seeds"),
|
|
drawtype = "signlike",
|
|
tiles = {tex},
|
|
inventory_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 = "Pot (empty)",
|
|
drawtype = "mesh",
|
|
mesh = "flowerpot.obj",
|
|
tiles = {
|
|
{name = "pot.png"},
|
|
{name = "itb_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.wood,
|
|
groups = {node = 1},
|
|
})
|
|
|
|
|
|
-- soil
|
|
for _, v in pairs({
|
|
"soil",
|
|
"soil_wet",
|
|
}) do
|
|
-- register diggable node version
|
|
minetest.register_node("nodes:" .. v .. "_breakable", {
|
|
description = nm(v),
|
|
tiles = {v .. ".png", "blocks_tiles.png^[sheet:8x8:5,2"},
|
|
groups = {node = 1, shovel = 1},
|
|
sounds = sounds.dirt,
|
|
})
|
|
minetest.register_node("nodes:" .. v, {
|
|
description = nm(v),
|
|
tiles = {v .. ".png", "blocks_tiles.png^[sheet:8x8:5,2"},
|
|
groups = {node = 1, unbreakable = 1},
|
|
sounds = sounds.dirt,
|
|
})
|
|
frame.register("nodes:" .. v .. "_breakable")
|
|
end
|
|
|
|
-- dirt with grass,
|
|
minetest.register_node("nodes:dirt_with_grass_breakable", {
|
|
description = "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 = "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 = "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 = "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 = "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 = "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 = "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 = "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 = "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},
|
|
},
|
|
},
|
|
})
|
|
|
|
for i, v in ipairs({[1] = "blue", [2] = "gray", [3] = "green", [4] = "rail", [5] = "red"}) do
|
|
minetest.register_node("nodes:line_" .. v, {
|
|
description = "Line (" .. v .. ")",
|
|
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,
|
|
},
|
|
selection_box = {type = "fixed",
|
|
fixed = {-1/2, -1/2, -1/2, 1/2, -7/16, 1/2},
|
|
},
|
|
groups = {node = 1, unbreakable = 1},
|
|
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 toolverb = "obtained"
|
|
if def.groups.shovel then
|
|
toolverb = "dug with a shovel"
|
|
elseif def.groups.axe then
|
|
toolverb = "chopped with an axe"
|
|
elseif def.groups.pickaxe then
|
|
toolverb = "dug with a pickaxe"
|
|
elseif def.groups.hand then
|
|
toolverb = "picked up"
|
|
end
|
|
local desc = def.description
|
|
minetest.override_item(name, {
|
|
description = desc .. "\nCan be " .. toolverb .. " by the player",
|
|
on_place = on_place_breakable,
|
|
on_destruct = on_destruct_breakable,
|
|
after_dig_node = after_dig_node_breakable,
|
|
node_placement_prediction = "",
|
|
})
|
|
end
|
|
end
|