Merge branch 'master' into nalc-1.2

This commit is contained in:
2019-05-04 19:25:15 +02:00
834 changed files with 5613 additions and 5985 deletions

View File

@ -0,0 +1,73 @@
-- crafts for common items that are used by more than one home decor component
local S = homedecor.gettext
-- items
minetest.register_craftitem(":homedecor:roof_tile_terracotta", {
description = S("Terracotta Roof Tile"),
inventory_image = "homedecor_roof_tile_terracotta.png",
})
minetest.register_craftitem(":homedecor:drawer_small", {
description = S("Small Wooden Drawer"),
inventory_image = "homedecor_drawer_small.png",
})
-- cooking/fuel
minetest.register_craft({
type = "cooking",
output = "homedecor:roof_tile_terracotta",
recipe = "basic_materials:terracotta_base",
})
minetest.register_craft({
type = "fuel",
recipe = "homedecor:shingles_wood",
burntime = 30,
})
-- crafing
minetest.register_craft( {
output = "homedecor:shingles_terracotta",
recipe = {
{ "homedecor:roof_tile_terracotta", "homedecor:roof_tile_terracotta"},
{ "homedecor:roof_tile_terracotta", "homedecor:roof_tile_terracotta"},
},
})
minetest.register_craft( {
output = "homedecor:roof_tile_terracotta 8",
recipe = {
{ "homedecor:shingles_terracotta", "homedecor:shingles_terracotta" }
}
})
minetest.register_craft( {
output = "homedecor:shingles_wood 12",
recipe = {
{ "group:stick", "group:wood"},
{ "group:wood", "group:stick"},
},
})
minetest.register_craft( {
output = "homedecor:shingles_wood 12",
recipe = {
{ "group:wood", "group:stick"},
{ "group:stick", "group:wood"},
},
})
minetest.register_craft( {
output = "homedecor:shingles_asphalt 6",
recipe = {
{ "building_blocks:gravel_spread", "dye:black", "building_blocks:gravel_spread" },
{ "group:sand", "dye:black", "group:sand" },
{ "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" },
},
})

View File

@ -0,0 +1,3 @@
default
creative

View File

@ -0,0 +1,379 @@
local S = homedecor.gettext
-- vectors to place one node next to or behind another
homedecor.fdir_to_right = {
{ 1, 0 },
{ 0, -1 },
{ -1, 0 },
{ 0, 1 },
}
homedecor.fdir_to_left = {
{ -1, 0 },
{ 0, 1 },
{ 1, 0 },
{ 0, -1 },
}
homedecor.fdir_to_fwd = {
{ 0, 1 },
{ 1, 0 },
{ 0, -1 },
{ -1, 0 },
}
-- special case for wallmounted nodes
homedecor.wall_fdir_to_right = {
nil,
nil,
{ -1, 0 },
{ 1, 0 },
{ 0, -1 },
{ 0, 1 },
}
homedecor.wall_fdir_to_left = {
nil,
nil,
{ 1, 0 },
{ -1, 0 },
{ 0, 1 },
{ 0, -1 },
}
homedecor.wall_fdir_to_fwd = {
nil,
nil,
{ 0, -1 },
{ 0, 1 },
{ 1, 0 },
{ -1, 0 },
}
local placeholder_node = "air"
minetest.register_alias("homedecor:expansion_placeholder", "air")
--- select which node was pointed at based on it being known, not ignored, buildable_to
-- returns nil if no node could be selected
local function select_node(pointed_thing)
local pos = pointed_thing.under
local node = minetest.get_node_or_nil(pos)
local def = node and minetest.registered_nodes[node.name]
if not def or not def.buildable_to then
pos = pointed_thing.above
node = minetest.get_node_or_nil(pos)
def = node and minetest.registered_nodes[node.name]
end
return def and pos, def
end
--- check if all nodes can and may be build to
local function is_buildable_to(placer_name, ...)
for _, pos in ipairs({...}) do
local node = minetest.get_node_or_nil(pos)
local def = node and minetest.registered_nodes[node.name]
if not (def and def.buildable_to) or minetest.is_protected(pos, placer_name) then
return false
end
end
return true
end
-- place one or two nodes if and only if both can be placed
local function stack(itemstack, placer, fdir, pos, def, pos2, node1, node2, pointed_thing)
local placer_name = placer:get_player_name() or ""
if is_buildable_to(placer_name, pos, pos2) then
local lfdir = fdir or minetest.dir_to_facedir(placer:get_look_dir())
minetest.set_node(pos, { name = node1, param2 = lfdir })
node2 = node2 or "air" -- this can be used to clear buildable_to nodes even though we are using a multinode mesh
-- do not assume by default, as we still might want to allow overlapping in some cases
local has_facedir = node2 ~= "air"
if node2 == "placeholder" then
has_facedir = false
node2 = placeholder_node
end
minetest.set_node(pos2, { name = node2, param2 = (has_facedir and lfdir) or nil })
-- call after_place_node of the placed node if available
local ctrl_node_def = minetest.registered_nodes[node1]
if ctrl_node_def and ctrl_node_def.after_place_node then
ctrl_node_def.after_place_node(pos, placer, itemstack, pointed_thing)
end
if not creative.is_enabled_for(placer_name) then
itemstack:take_item()
end
end
return itemstack
end
local function rightclick_pointed_thing(pos, placer, itemstack, pointed_thing)
local node = minetest.get_node_or_nil(pos)
if not node then return false end
local def = minetest.registered_nodes[node.name]
if not def or not def.on_rightclick then return false end
return def.on_rightclick(pos, node, placer, itemstack, pointed_thing) or itemstack
end
-- Stack one node above another
-- leave the last argument nil if it's one 2m high node
function homedecor.stack_vertically(itemstack, placer, pointed_thing, node1, node2)
local rightclick_result = rightclick_pointed_thing(pointed_thing.under, placer, itemstack, pointed_thing)
if rightclick_result then return rightclick_result end
local pos, def = select_node(pointed_thing)
if not pos then return itemstack end
local top_pos = { x=pos.x, y=pos.y+1, z=pos.z }
return stack(itemstack, placer, nil, pos, def, top_pos, node1, node2, pointed_thing)
end
-- Stack one door node above another
-- like homedecor.stack_vertically but tests first if it was placed as a right wing, then uses node1_right and node2_right instead
function homedecor.stack_wing(itemstack, placer, pointed_thing, node1, node2, node1_right, node2_right)
local rightclick_result = rightclick_pointed_thing(pointed_thing.under, placer, itemstack, pointed_thing)
if rightclick_result then return rightclick_result end
local pos, def = select_node(pointed_thing)
if not pos then return itemstack end
local forceright = placer:get_player_control()["sneak"]
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local is_right_wing = node1 == minetest.get_node({ x = pos.x + homedecor.fdir_to_left[fdir+1][1], y=pos.y, z = pos.z + homedecor.fdir_to_left[fdir+1][2] }).name
if forceright or is_right_wing then
node1, node2 = node1_right, node2_right
end
local top_pos = { x=pos.x, y=pos.y+1, z=pos.z }
return stack(itemstack, placer, fdir, pos, def, top_pos, node1, node2, pointed_thing)
end
function homedecor.stack_sideways(itemstack, placer, pointed_thing, node1, node2, dir)
local rightclick_result = rightclick_pointed_thing(pointed_thing.under, placer, itemstack, pointed_thing)
if rightclick_result then return rightclick_result end
local pos, def = select_node(pointed_thing)
if not pos then return itemstack end
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local fdir_transform = dir and homedecor.fdir_to_right or homedecor.fdir_to_fwd
local pos2 = { x = pos.x + fdir_transform[fdir+1][1], y=pos.y, z = pos.z + fdir_transform[fdir+1][2] }
return stack(itemstack, placer, fdir, pos, def, pos2, node1, node2, pointed_thing)
end
function homedecor.bed_expansion(pos, placer, itemstack, pointed_thing, trybunks)
local thisnode = minetest.get_node(pos)
local param2 = thisnode.param2
local fdir = param2 % 8
local fxd = homedecor.wall_fdir_to_fwd[fdir+1][1]
local fzd = homedecor.wall_fdir_to_fwd[fdir+1][2]
local forwardpos = {x=pos.x+fxd, y=pos.y, z=pos.z+fzd}
local forwardnode = minetest.get_node(forwardpos)
local def = minetest.registered_nodes[forwardnode.name]
local placer_name = placer:get_player_name()
if not (def and def.buildable_to) then
minetest.chat_send_player( placer:get_player_name(),
S("Not enough room - the space for the headboard is occupied!"))
minetest.set_node(pos, {name = "air"})
return true
end
if minetest.is_protected(forwardpos, placer_name) then
minetest.chat_send_player( placer:get_player_name(),
S("Someone already owns the spot where the headboard goes."))
return true
end
minetest.set_node(forwardpos, {name = "air"})
local lxd = homedecor.wall_fdir_to_left[fdir+1][1]
local lzd = homedecor.wall_fdir_to_left[fdir+1][2]
local leftpos = {x=pos.x+lxd, y=pos.y, z=pos.z+lzd}
local leftnode = minetest.get_node(leftpos)
local rxd = homedecor.wall_fdir_to_right[fdir+1][1]
local rzd = homedecor.wall_fdir_to_right[fdir+1][2]
local rightpos = {x=pos.x+rxd, y=pos.y, z=pos.z+rzd}
local rightnode = minetest.get_node(rightpos)
local inv = placer:get_inventory()
if leftnode.name == "homedecor:bed_regular" then
local newname = string.gsub(thisnode.name, "_regular", "_kingsize")
local meta = minetest.get_meta(pos)
local leftmeta = minetest.get_meta(leftpos)
minetest.set_node(pos, {name = "air"})
minetest.swap_node(leftpos, { name = newname, param2 = param2})
elseif rightnode.name == "homedecor:bed_regular" then
local newname = string.gsub(thisnode.name, "_regular", "_kingsize")
local meta = minetest.get_meta(pos)
local rightmeta = minetest.get_meta(rightpos)
minetest.set_node(rightpos, {name = "air"})
minetest.swap_node(pos, { name = newname, param2 = param2})
end
local toppos = {x=pos.x, y=pos.y+1.0, z=pos.z}
local topposfwd = {x=toppos.x+fxd, y=toppos.y, z=toppos.z+fzd}
if trybunks and is_buildable_to(placer_name, toppos, topposfwd) then
local newname = string.gsub(thisnode.name, "_regular", "_extended")
local newparam2 = param2 % 8
minetest.swap_node(toppos, { name = thisnode.name, param2 = param2})
minetest.swap_node(pos, { name = newname, param2 = param2})
itemstack:take_item()
end
end
function homedecor.unextend_bed(pos)
local bottomnode = minetest.get_node({x=pos.x, y=pos.y-1.0, z=pos.z})
local param2 = bottomnode.param2
if bottomnode.name == "homedecor:bed_extended" then
local newname = string.gsub(bottomnode.name, "_extended", "_regular")
minetest.swap_node({x=pos.x, y=pos.y-1.0, z=pos.z}, { name = newname, param2 = param2})
end
end
function homedecor.place_banister(itemstack, placer, pointed_thing)
local rightclick_result = rightclick_pointed_thing(pointed_thing.under, placer, itemstack, pointed_thing)
if rightclick_result then return rightclick_result end
local pos, _ = select_node(pointed_thing)
if not pos then return itemstack end
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local meta = itemstack:get_meta()
local pindex = meta:get_int("palette_index")
local abovepos = { x=pos.x, y=pos.y+1, z=pos.z }
local abovenode = minetest.get_node(abovepos)
local adef = minetest.registered_nodes[abovenode.name]
local placer_name = placer:get_player_name()
if not (adef and adef.buildable_to) then
minetest.chat_send_player(placer_name, S("Not enough room - the upper space is occupied!" ))
return itemstack
end
if minetest.is_protected(abovepos, placer_name) then
minetest.chat_send_player(placer_name, S("Someone already owns that spot."))
return itemstack
end
local lxd = homedecor.fdir_to_left[fdir+1][1]
local lzd = homedecor.fdir_to_left[fdir+1][2]
local rxd = homedecor.fdir_to_right[fdir+1][1]
local rzd = homedecor.fdir_to_right[fdir+1][2]
local fxd = homedecor.fdir_to_fwd[fdir+1][1]
local fzd = homedecor.fdir_to_fwd[fdir+1][2]
local below_pos = { x=pos.x, y=pos.y-1, z=pos.z }
local fwd_pos = { x=pos.x+fxd, y=pos.y, z=pos.z+fzd }
local left_pos = { x=pos.x+lxd, y=pos.y, z=pos.z+lzd }
local right_pos = { x=pos.x+rxd, y=pos.y, z=pos.z+rzd }
local left_fwd_pos = { x=pos.x+lxd+fxd, y=pos.y, z=pos.z+lzd+fzd }
local right_fwd_pos = { x=pos.x+rxd+fxd, y=pos.y, z=pos.z+rzd+fzd }
local right_fwd_above_pos = { x=pos.x+rxd+fxd, y=pos.y+1, z=pos.z+rzd+fzd }
local left_fwd_above_pos = { x=pos.x+lxd+fxd, y=pos.y+1, z=pos.z+lzd+fzd }
local right_fwd_below_pos = { x=pos.x+rxd+fxd, y=pos.y-1, z=pos.z+rzd+fzd }
local left_fwd_below_pos = { x=pos.x+lxd+fxd, y=pos.y-1, z=pos.z+lzd+fzd }
local below_node = minetest.get_node(below_pos)
--local fwd_node = minetest.get_node(fwd_pos)
local left_node = minetest.get_node(left_pos)
local right_node = minetest.get_node(right_pos)
local left_fwd_node = minetest.get_node(left_fwd_pos)
local right_fwd_node = minetest.get_node(right_fwd_pos)
local left_below_node = minetest.get_node({x=left_pos.x, y=left_pos.y-1, z=left_pos.z})
local right_below_node = minetest.get_node({x=right_pos.x, y=right_pos.y-1, z=right_pos.z})
--local right_fwd_above_node = minetest.get_node(right_fwd_above_pos)
--local left_fwd_above_node = minetest.get_node(left_fwd_above_pos)
local right_fwd_below_node = minetest.get_node(right_fwd_below_pos)
local left_fwd_below_node = minetest.get_node(left_fwd_below_pos)
local new_place_name = itemstack:get_name()
-- try to place a diagonal one on the side of blocks stacked like stairs
-- or follow an existing diagonal with another.
if (left_below_node and string.find(left_below_node.name, "banister_.-_diagonal_right")
and below_node and is_buildable_to(placer_name, below_pos, below_pos))
or not is_buildable_to(placer_name, right_fwd_above_pos, right_fwd_above_pos) then
new_place_name = string.gsub(new_place_name, "_horizontal", "_diagonal_right")
elseif (right_below_node and string.find(right_below_node.name, "banister_.-_diagonal_left")
and below_node and is_buildable_to(placer_name, below_pos, below_pos))
or not is_buildable_to(placer_name, left_fwd_above_pos, left_fwd_above_pos) then
new_place_name = string.gsub(new_place_name, "_horizontal", "_diagonal_left")
-- try to follow a diagonal with the corresponding horizontal
-- from the top of a diagonal...
elseif left_below_node and string.find(left_below_node.name, "homedecor:banister_.*_diagonal") then
fdir = left_below_node.param2
new_place_name = string.gsub(left_below_node.name, "_diagonal_.-$", "_horizontal")
elseif right_below_node and string.find(right_below_node.name, "homedecor:banister_.*_diagonal") then
fdir = right_below_node.param2
new_place_name = string.gsub(right_below_node.name, "_diagonal_.-$", "_horizontal")
-- try to place a horizontal in-line with the nearest diagonal, at the top
elseif left_fwd_below_node and string.find(left_fwd_below_node.name, "homedecor:banister_.*_diagonal")
and is_buildable_to(placer_name, fwd_pos, fwd_pos) then
fdir = left_fwd_below_node.param2
pos = fwd_pos
new_place_name = string.gsub(left_fwd_below_node.name, "_diagonal_.-$", "_horizontal")
elseif right_fwd_below_node and string.find(right_fwd_below_node.name, "homedecor:banister_.*_diagonal")
and is_buildable_to(placer_name, fwd_pos, fwd_pos) then
fdir = right_fwd_below_node.param2
pos = fwd_pos
new_place_name = string.gsub(right_fwd_below_node.name, "_diagonal_.-$", "_horizontal")
-- try to follow a diagonal with a horizontal, at the bottom of the diagonal
elseif left_node and string.find(left_node.name, "homedecor:banister_.*_diagonal") then
fdir = left_node.param2
new_place_name = string.gsub(left_node.name, "_diagonal_.-$", "_horizontal")
elseif right_node and string.find(right_node.name, "homedecor:banister_.*_diagonal") then
fdir = right_node.param2
new_place_name = string.gsub(right_node.name, "_diagonal_.-$", "_horizontal")
-- try to place a horizontal in-line with the nearest diagonal, at the bottom
elseif left_fwd_node and string.find(left_fwd_node.name, "homedecor:banister_.*_diagonal")
and is_buildable_to(placer_name, fwd_pos, fwd_pos) then
fdir = left_fwd_node.param2
pos = fwd_pos
new_place_name = string.gsub(left_fwd_node.name, "_diagonal_.-$", "_horizontal")
elseif right_fwd_node and string.find(right_fwd_node.name, "homedecor:banister_.*_diagonal")
and is_buildable_to(placer_name, fwd_pos, fwd_pos) then
fdir = right_fwd_node.param2
pos = fwd_pos
new_place_name = string.gsub(right_fwd_node.name, "_diagonal_.-$", "_horizontal")
end
-- manually invert left-right orientation
if placer:get_player_control()["sneak"] then
if string.find(new_place_name, "banister_.*_diagonal") then
new_place_name = string.gsub(new_place_name, "_left", "_right")
else
new_place_name = string.gsub(new_place_name, "_right", "_left")
end
end
minetest.set_node(pos, {name = new_place_name, param2 = fdir+pindex})
itemstack:take_item()
return itemstack
end

View File

@ -0,0 +1,283 @@
-- This code supplies an oven/stove. Basically it's just a copy of the default furnace with different textures.
local S = homedecor.gettext
local function swap_node(pos, name)
local node = minetest.get_node(pos)
if node.name == name then return end
node.name = name
minetest.swap_node(pos, node)
end
local function make_formspec(furnacedef, percent)
local fire
if percent and (percent > 0) then
fire = ("%s^[lowpart:%d:%s"):format(
furnacedef.fire_bg,
(100-percent),
furnacedef.fire_fg
)
else
fire = "default_furnace_fire_bg.png"
end
local w = furnacedef.output_width
local h = math.ceil(furnacedef.output_slots / furnacedef.output_width)
return "size["..math.max(8, 6 + w)..",9]"..
"image[2,2;1,1;"..fire.."]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;1,1;]"..
"list[current_name;dst;5,1;"..w..","..h..";]"..
"list[current_player;main;0,5;8,4;]"..
"listring[current_name;dst]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"
end
--[[
furnacedef = {
description = "Oven",
tiles = { ... },
tiles_active = { ... },
^ +Y -Y +X -X +Z -Z
tile_format = "oven_%s%s.png",
^ First '%s' replaced by one of "top", "bottom", "side", "front".
^ Second '%s' replaced by "" for inactive, and "_active" for active "front"
^ "side" is used for left, right and back.
^ tiles_active for front is set
output_slots = 4,
output_width = 2,
cook_speed = 1,
^ Higher values cook stuff faster.
extra_nodedef_fields = { ... },
^ Stuff here is copied verbatim into both active and inactive nodedefs
^ Useful for overriding drawtype, etc.
}
]]
local function make_tiles(tiles, fmt, active)
if not fmt then return tiles end
tiles = { }
for i,side in ipairs{"top", "bottom", "side", "side", "side", "front"} do
if active and (i == 6) then
tiles[i] = fmt:format(side, "_active")
else
tiles[i] = fmt:format(side, "")
end
end
return tiles
end
local furnace_can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("fuel")
and inv:is_empty("dst")
and inv:is_empty("src")
end
function homedecor.register_furnace(name, furnacedef)
furnacedef.fire_fg = furnacedef.fire_bg or "default_furnace_fire_fg.png"
furnacedef.fire_bg = furnacedef.fire_bg or "default_furnace_fire_bg.png"
furnacedef.output_slots = furnacedef.output_slots or 4
furnacedef.output_width = furnacedef.output_width or 2
furnacedef.cook_speed = furnacedef.cook_speed or 1
local description = furnacedef.description or S("Furnace")
local furnace_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", make_formspec(furnacedef, 0))
meta:set_string("infotext", description)
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 1)
inv:set_size("dst", furnacedef.output_slots)
end
local furnace_allow_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext", S("@1 (empty)", description))
end
return stack:get_count()
else
return 0
end
elseif listname == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
end
local furnace_allow_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
if to_list == "fuel" then
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
if inv:is_empty("src") then
meta:set_string("infotext", S("@1 (empty)", description))
end
return count
else
return 0
end
elseif to_list == "src" then
return count
elseif to_list == "dst" then
return 0
end
end
local def = {
description = description,
tiles = make_tiles(furnacedef.tiles, furnacedef.tile_format, false),
groups = furnacedef.groups or {cracky=2},
sounds = furnacedef.sounds or default.node_sound_wood_defaults(),
on_construct = furnace_construct,
can_dig = furnace_can_dig,
allow_metadata_inventory_put = furnace_allow_put,
allow_metadata_inventory_move = furnace_allow_move,
inventory = { lockable = true }
}
local def_active = {
description = S("@1 (active)", description),
tiles = make_tiles(furnacedef.tiles_active, furnacedef.tile_format, true),
light_source = 8,
drop = "homedecor:" .. name,
groups = furnacedef.groups or {cracky=2, not_in_creative_inventory=1},
sounds = furnacedef.sounds or default.node_sound_stone_defaults(),
on_construct = furnace_construct,
can_dig = furnace_can_dig,
allow_metadata_inventory_put = furnace_allow_put,
allow_metadata_inventory_move = furnace_allow_move,
inventory = { lockable = true }
}
if furnacedef.extra_nodedef_fields then
for k, v in pairs(furnacedef.extra_nodedef_fields) do
def[k] = v
def_active[k] = v
end
end
local n_active = name.."_active"
homedecor.register(name, def)
homedecor.register(n_active, def_active)
local nname, name_active = "homedecor:"..name, "homedecor:"..n_active
minetest.register_abm({
nodenames = {nname, name_active, nname.."_locked", name_active.."_locked"},
label = "furnaces",
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
for i, pname in ipairs({
"fuel_totaltime",
"fuel_time",
"src_totaltime",
"src_time"
}) do
if meta:get_string(pname) == "" then
meta:set_float(pname, 0.0)
end
end
local inv = meta:get_inventory()
local srclist = inv:get_list("src")
local cooked = nil
local aftercooked
if srclist then
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
local was_active = false
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
was_active = true
meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
meta:set_float("src_time", meta:get_float("src_time") + furnacedef.cook_speed)
if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
-- check if there's room for output in "dst" list
if inv:room_for_item("dst",cooked.item) then
-- Put result in "dst" list
inv:add_item("dst", cooked.item)
-- take stuff from "src" list
inv:set_stack("src", 1, aftercooked.items[1])
end
meta:set_string("src_time", 0)
end
end
-- XXX: Quick patch, make it better in the future.
local locked = node.name:find("_locked$") and "_locked" or ""
local desc = minetest.registered_nodes[nname..locked].description
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
local percent = math.floor(meta:get_float("fuel_time") /
meta:get_float("fuel_totaltime") * 100)
meta:set_string("infotext", S("@1 (active: @2%)", desc, percent))
swap_node(pos,name_active..locked)
meta:set_string("formspec", make_formspec(furnacedef, percent))
return
end
local fuel = nil
local afterfuel
cooked = nil
local fuellist = inv:get_list("fuel")
srclist = inv:get_list("src")
if srclist then
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
if fuellist then
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
end
if (not fuel) or (fuel.time <= 0) then
meta:set_string("infotext", S("@1 (out of fuel)", desc))
swap_node(pos, nname..locked)
meta:set_string("formspec", make_formspec(furnacedef, 0))
return
end
if cooked.item:is_empty() then
if was_active then
meta:set_string("infotext", S("@1 (empty)", desc))
swap_node(pos, nname..locked)
meta:set_string("formspec", make_formspec(furnacedef, 0))
end
return
end
if not inv:room_for_item("dst", cooked.item) then
meta:set_string("infotext", S("@1 (output bins are full)", desc))
swap_node(pos, nname..locked)
meta:set_string("formspec", make_formspec(furnacedef, 0))
return
end
meta:set_string("fuel_totaltime", fuel.time)
meta:set_string("fuel_time", 0)
inv:set_stack("fuel", 1, afterfuel.items[1])
end,
})
end

82
homedecor_common/init.lua Normal file
View File

@ -0,0 +1,82 @@
-- Home Decor API/functions, and common textures and models
-- by VanessaE
local modpath = minetest.get_modpath("homedecor_common")
homedecor = {}
homedecor.modpath = modpath
-- Intllib support
homedecor.gettext, homedecor.ngettext = dofile(modpath.."/intllib.lua")
local S = homedecor.gettext
-- Determine if the item being pointed at is the underside of a node (e.g a ceiling)
function homedecor.find_ceiling(itemstack, placer, pointed_thing)
-- most of this is copied from the rotate-and-place function in builtin
local unode = core.get_node_or_nil(pointed_thing.under)
if not unode then
return
end
local undef = core.registered_nodes[unode.name]
if undef and undef.on_rightclick then
undef.on_rightclick(pointed_thing.under, unode, placer,
itemstack, pointed_thing)
return
end
local above = pointed_thing.above
local under = pointed_thing.under
local iswall = (above.y == under.y)
local isceiling = not iswall and (above.y < under.y)
local anode = core.get_node_or_nil(above)
if not anode then
return
end
local pos = pointed_thing.above
local node = anode
if undef and undef.buildable_to then
pos = pointed_thing.under
node = unode
end
if core.is_protected(pos, placer:get_player_name()) then
core.record_protection_violation(pos,
placer:get_player_name())
return
end
local ndef = core.registered_nodes[node.name]
if not ndef or not ndef.buildable_to then
return
end
return isceiling, pos
end
screwdriver = screwdriver or {}
homedecor.plain_wood = { name = "homedecor_generic_wood_plain.png", color = 0xffa76820 }
homedecor.mahogany_wood = { name = "homedecor_generic_wood_plain.png", color = 0xff7d2506 }
homedecor.white_wood = "homedecor_generic_wood_plain.png"
homedecor.dark_wood = { name = "homedecor_generic_wood_plain.png", color = 0xff39240f }
homedecor.lux_wood = { name = "homedecor_generic_wood_luxury.png", color = 0xff643f23 }
homedecor.color_black = 0xff303030
homedecor.color_dark_grey = 0xff606060
homedecor.color_med_grey = 0xffa0a0a0
-- load different handler subsystems
dofile(modpath.."/nodeboxes.lua")
dofile(modpath.."/expansion.lua")
dofile(modpath.."/furnaces.lua")
dofile(modpath.."/inventory.lua")
dofile(modpath.."/registration.lua")
dofile(modpath.."/water_particles.lua")
dofile(modpath.."/mt_game_beds_functions.lua")
dofile(modpath.."/sit.lua")
dofile(modpath.."/crafts.lua")
if minetest.settings:get_bool("log_mods") then
minetest.log("action", "[HomeDecor API] " .. S("Loaded!"))
end

View File

@ -0,0 +1,45 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

View File

@ -0,0 +1,189 @@
local S = homedecor.gettext
local default_can_dig = function(pos,player)
local meta = minetest.get_meta(pos)
return meta:get_inventory():is_empty("main")
end
local background = default.gui_bg .. default.gui_bg_img .. default.gui_slots
local default_inventory_formspecs = {
["4"]="size[8,6]".. background ..
"list[context;main;2,0;4,1;]" ..
"list[current_player;main;0,2;8,4;]" ..
"listring[]",
["6"]="size[8,6]".. background ..
"list[context;main;1,0;6,1;]"..
"list[current_player;main;0,2;8,4;]" ..
"listring[]",
["8"]="size[8,6]".. background ..
"list[context;main;0,0;8,1;]"..
"list[current_player;main;0,2;8,4;]" ..
"listring[]",
["12"]="size[8,7]".. background ..
"list[context;main;1,0;6,2;]"..
"list[current_player;main;0,3;8,4;]" ..
"listring[]",
["16"]="size[8,7]".. background ..
"list[context;main;0,0;8,2;]"..
"list[current_player;main;0,3;8,4;]" ..
"listring[]",
["24"]="size[8,8]".. background ..
"list[context;main;0,0;8,3;]"..
"list[current_player;main;0,4;8,4;]" ..
"listring[]",
["32"]="size[8,9]".. background ..
"list[context;main;0,0.3;8,4;]"..
"list[current_player;main;0,4.85;8,1;]"..
"list[current_player;main;0,6.08;8,3;8]"..
"listring[context;main]" ..
"listring[current_player;main]" ..
default.get_hotbar_bg(0,4.85),
["50"]="size[10,10]".. background ..
"list[context;main;0,0;10,5;]"..
"list[current_player;main;1,6;8,4;]" ..
"listring[]",
}
local function get_formspec_by_size(size)
--TODO heuristic to use the "next best size"
local formspec = default_inventory_formspecs[tostring(size)]
return formspec or default_inventory_formspecs
end
----
-- handle inventory setting
-- inventory = {
-- size = 16,
-- formspec = …,
-- locked = false,
-- lockable = true,
-- }
--
function homedecor.handle_inventory(name, def, original_def)
local inventory = def.inventory
if not inventory then return end
def.inventory = nil
if inventory.size then
local on_construct = def.on_construct
def.on_construct = function(pos)
local size = inventory.size
local meta = minetest.get_meta(pos)
meta:get_inventory():set_size("main", size)
meta:set_string("formspec", inventory.formspec or get_formspec_by_size(size))
if on_construct then on_construct(pos) end
end
end
def.can_dig = def.can_dig or default_can_dig
def.on_metadata_inventory_move = def.on_metadata_inventory_move or function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", S("@1 moves stuff in @2 at @3",
player:get_player_name(), name, minetest.pos_to_string(pos)
))
end
def.on_metadata_inventory_put = def.on_metadata_inventory_put or function(pos, listname, index, stack, player)
minetest.log("action", S("@1 moves @2 to @3 at @4",
player:get_player_name(), stack:get_name(), name, minetest.pos_to_string(pos)
))
end
def.on_metadata_inventory_take = def.on_metadata_inventory_take or function(pos, listname, index, stack, player)
minetest.log("action", S("@1 takes @2 from @3 at @4",
player:get_player_name(), stack:get_name(), name, minetest.pos_to_string(pos)
))
end
local locked = inventory.locked
if locked then
local after_place_node = def.after_place_node
def.after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
local owner = placer:get_player_name() or ""
meta:set_string("owner", owner)
meta:set_string("infotext", S("@1 (owned by @2)", def.infotext or def.description, owner))
return after_place_node and after_place_node(pos, placer)
end
local allow_move = def.allow_metadata_inventory_move
def.allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
local playername = player:get_player_name()
if playername == owner or
minetest.check_player_privs(playername, "protection_bypass") then
return allow_move and
allow_move(pos, from_list, from_index, to_list, to_index, count, player) or
count
end
minetest.log("action", S("@1 tried to access a @2 belonging to @3 at @4",
playername, name, owner, minetest.pos_to_string(pos)
))
return 0
end
local allow_put = def.allow_metadata_inventory_put
def.allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
local playername = player:get_player_name()
if playername == owner or
minetest.check_player_privs(playername, "protection_bypass") then
return allow_put and allow_put(pos, listname, index, stack, player) or
stack:get_count()
end
minetest.log("action", S("@1 tried to access a @2 belonging to @3 at @4",
playername, name, owner, minetest.pos_to_string(pos)
))
return 0
end
local allow_take = def.allow_metadata_inventory_take
def.allow_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
local playername = player:get_player_name()
if playername == owner or
minetest.check_player_privs(playername, "protection_bypass") then
return allow_take and allow_take(pos, listname, index, stack, player) or
stack:get_count()
end
minetest.log("action", S("@1 tried to access a @2 belonging to @3 at @4",
playername, name, owner, minetest.pos_to_string(pos)
))
return 0
end
end
local lockable = inventory.lockable
if lockable then
local locked_def = table.copy(original_def)
locked_def.description = S("@1 (Locked)", def.description or name)
local locked_inventory = locked_def.inventory
locked_inventory.locked = true
locked_inventory.lockable = nil -- avoid loops of locked locked stuff
local locked_name = name .. "_locked"
homedecor.register(locked_name, locked_def)
minetest.register_craft({
type = "shapeless",
output = "homedecor:" .. locked_name,
recipe = { "homedecor:" .. name, "basic_materials:padlock" }
})
end
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
# Blender v2.73 (sub 0) OBJ File: 'cobe+1.001.blend'
# www.blender.org
o Cylinder
v -0.499500 -0.499500 0.499500
v -0.499500 -0.499500 -0.499500
v 0.499500 -0.499500 -0.499500
v 0.499500 -0.499500 0.499500
v -0.499500 0.499500 0.499500
v -0.499500 0.499500 -0.499500
v 0.499500 0.499500 -0.499500
v 0.499500 0.499500 0.499500
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
g Cylinder_Cylinder_None
s off
f 5/1 6/2 2/3 1/4
f 6/1 7/2 3/3 2/4
f 7/1 8/2 4/3 3/4
f 8/1 5/2 1/3 4/4
f 1/1 2/2 3/3 4/4
f 8/1 7/2 6/3 5/4

View File

@ -0,0 +1,26 @@
# Blender v2.73 (sub 0) OBJ File: 'slope_test_slope_onetexture.blend'
# www.blender.org
o Cube_Cube.002
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vn 0.000000 -0.000000 1.000000
vn 0.000000 -1.000000 -0.000000
vn 0.000000 0.707100 -0.707100
vn -1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
g Cube_Cube.002_Cube_Cube.002_front-back-bottom
s off
f 1/1/1 2/2/1 3/3/1 4/4/1
f 4/3/2 3/4/2 5/1/2 6/2/2
f 2/1/3 1/2/3 6/3/3 5/4/3
g Cube_Cube.002_Cube_Cube.002_sides
f 2/1/4 5/3/4 3/4/4
f 1/2/5 4/3/5 6/4/5

View File

@ -0,0 +1,34 @@
# Blender v2.73 (sub 0) OBJ File: 'slope_test_icorner_onetexture.blend'
# www.blender.org
o Cube_Cube.000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v 0.500000 -0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vn 1.000000 -0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 0.707100 -0.707100
vn 0.000000 -0.000000 -1.000000
vn -0.000000 -1.000000 -0.000000
vn -0.000000 -0.000000 1.000000
vn -0.707100 0.707100 -0.000000
g Cube_Cube.000_Cube_Cube.000_None
s off
f 6/1/1 1/2/1 7/3/1 8/4/1
f 2/1/2 5/3/2 3/4/2
f 2/1/3 1/2/3 5/4/3
f 6/2/4 8/3/4 9/4/4
f 9/1/5 8/2/5 7/3/5 3/4/5
f 3/3/6 7/4/6 1/1/6 2/2/6
f 1/1/7 6/2/7 9/3/7
l 1 4
l 3 4

View File

@ -0,0 +1,24 @@
# Blender v2.73 (sub 0) OBJ File: 'slope_test_ocorner_onetexture.blend'
# www.blender.org
o Cube_Cube.002
v 0.500000 0.500000 0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vn 0.000000 -1.000000 -0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 -0.000000 1.000000
vn -0.707100 0.707100 0.000000
vn 0.000000 0.707100 -0.707100
g Cube_Cube.002_Cube_Cube.002_None
s off
f 3/1/1 2/2/1 4/3/1 5/4/1
f 1/2/2 3/3/2 5/4/2
f 1/1/3 2/3/3 3/4/3
f 1/1/4 4/3/4 2/4/4
f 1/2/5 5/3/5 4/4/5

View File

@ -0,0 +1,175 @@
-- This file is a partial copy of functions.lua from minetest_game's beds mod
-- with changes needed for homedecor's beds.
local pi = math.pi
local is_sp = minetest.is_singleplayer()
local enable_respawn = minetest.settings:get_bool("enable_bed_respawn")
if enable_respawn == nil then
enable_respawn = true
end
-- Helper functions
local function get_look_yaw(pos)
local n = minetest.get_node(pos)
local fdir = n.param2 % 4
if fdir == 0 then
return pi / 2, fdir
elseif fdir == 1 then
return -pi / 2, fdir
elseif fdir == 3 then
return pi, fdir
else
return 0, fdir
end
end
local function is_night_skip_enabled()
local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip")
if enable_night_skip == nil then
enable_night_skip = true
end
return enable_night_skip
end
local function check_in_beds(players)
local in_bed = beds.player
if not players then
players = minetest.get_connected_players()
end
for n, player in ipairs(players) do
local name = player:get_player_name()
if not in_bed[name] then
return false
end
end
return #players > 0
end
local function get_player_in_bed()
local player_in_bed = 0
for k,v in pairs(beds.player) do
player_in_bed = player_in_bed + 1
end
return player_in_bed
end
local function lay_down(player, pos, bed_pos, state, skip)
local name = player:get_player_name()
local hud_flags = player:hud_get_flags()
if not player or not name then
return
end
-- stand up
if state ~= nil and not state then
local p = beds.pos[name] or nil
if beds.player[name] ~= nil then
beds.player[name] = nil
end
-- skip here to prevent sending player specific changes (used for leaving players)
if skip then
return
end
if p then
player:setpos(p)
end
-- physics, eye_offset, etc
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
player:set_look_horizontal(math.random(1, 180) / 100)
default.player_attached[name] = false
player:set_physics_override(1, 1, 1)
hud_flags.wielditem = true
default.player_set_animation(player, "stand" , 30)
-- lay down
else
beds.player[name] = 1
beds.pos[name] = pos
-- physics, eye_offset, etc
player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0})
local yaw, fdir = get_look_yaw(bed_pos)
player:set_look_horizontal(yaw)
local offsets = {
[0] = {0.5, 0},
[1] = {-0.5, 0},
[2] = {0, -0.5},
[3] = {0, 0.5}
}
local p = {x = bed_pos.x + offsets[fdir][1], y = bed_pos.y, z = bed_pos.z + offsets[fdir][2]}
player:set_physics_override(0, 0, 0)
player:setpos(p)
default.player_attached[name] = true
hud_flags.wielditem = false
default.player_set_animation(player, "lay" , 0)
end
player:hud_set_flags(hud_flags)
end
local function update_formspecs(finished)
local ges = #minetest.get_connected_players()
local player_in_bed = get_player_in_bed()
local form_n
local is_majority = (ges / 2) < player_in_bed
if finished then
form_n = beds.formspec .. "label[2.7,11; Good morning.]"
else
form_n = beds.formspec .. "label[2.2,11;" .. tostring(player_in_bed) ..
" of " .. tostring(ges) .. " players are in bed]"
if is_majority and is_night_skip_enabled() then
form_n = form_n .. "button_exit[2,8;4,0.75;force;Force night skip]"
end
end
for name,_ in pairs(beds.player) do
minetest.show_formspec(name, "beds_form", form_n)
end
end
-- Public functions
function homedecor.beds_on_rightclick(pos, node, player)
local name = player:get_player_name()
local ppos = player:getpos()
local tod = minetest.get_timeofday()
if tod > 0.2 and tod < 0.805 then
if beds.player[name] then
lay_down(player, nil, nil, false)
end
minetest.chat_send_player(name, "You can only sleep at night.")
return
end
-- move to bed
if not beds.player[name] then
lay_down(player, ppos, pos)
beds.set_spawns() -- save respawn positions when entering bed
else
lay_down(player, nil, nil, false)
end
if not is_sp then
update_formspecs(false)
end
-- skip the night and let all players stand up
if check_in_beds() then
minetest.after(2, function()
if not is_sp then
update_formspecs(is_night_skip_enabled())
end
if is_night_skip_enabled() then
beds.skip_night()
beds.kick_players()
end
end)
end
end

View File

@ -0,0 +1,59 @@
-- please keep any non-generic nodeboxe with its node definition
-- this file should not accumulate any left over nodeboxes
-- but is meant to host any abstractions or calculations based on nodeboxes
-- a box is defined as {x1, y1, z1, x2, y2, z2}
homedecor.box = {
-- slab starting from -x (after rotation: left)
slab_x = function(depth) return { -0.5, -0.5, -0.5, -0.5+depth, 0.5, 0.5 } end,
-- bottom slab (starting from -y) with height optionally shifted upwards
slab_y = function(height, shift) return { -0.5, -0.5+(shift or 0), -0.5, 0.5, -0.5+height+(shift or 0), 0.5 } end,
-- slab starting from -z (+z with negative depth)
slab_z = function(depth)
-- for consistency with the other functions here, we have to assume that a "z" slab starts from -z and extends by depth,
-- but since conventionally a lot of nodes place slabs against +z for player convenience, we define
-- a "negative" depth as a depth extending from the other side, i.e. +z
if depth > 0 then
-- slab starting from -z
return { -0.5, -0.5, -0.5, 0.5, 0.5, -0.5+depth }
else
-- slab starting from +z (z1=0.5-(-depth))
return { -0.5, -0.5, 0.5+depth, 0.5, 0.5, 0.5 }
end
end,
bar_y = function(radius) return {-radius, -0.5, -radius, radius, 0.5, radius} end,
cuboid = function(radius_x, radius_y, radius_z) return {-radius_x, -radius_y, -radius_z, radius_x, radius_y, radius_z} end,
}
homedecor.nodebox = {
-- { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 },
-- can be used in-place as:
-- { type="regular" },
regular = { type="regular" },
null = { type = "fixed", fixed = { 0, 0, 0, 0, 0, 0 } },
corner_xz = function(depth_x, depth_z) return {
type="fixed",
fixed={
homedecor.box.slab_x(depth_x),
homedecor.box.slab_z(depth_z),
-- { -0.5, -0.5, -0.5, 0.5-depth, 0.5, -0.5+depth } -- slab_x without the overlap, but actually looks a bit worse
}
} end,
}
local mt = {}
mt.__index = function(table, key)
local ref = homedecor.box[key]
local ref_type = type(ref)
if ref_type == "function" then
return function(...)
return { type = "fixed", fixed = ref(...) }
end
elseif ref_type == "table" then
return { type = "fixed", fixed = ref }
elseif ref_type == "nil" then
error(key .. "could not be found among nodebox presets and functions")
end
error("unexpected datatype " .. tostring(type(ref)) .. " while looking for " .. key)
end
setmetatable(homedecor.nodebox, mt)

View File

@ -0,0 +1,95 @@
homedecor = homedecor or {}
local placeholder_node = "homedecor:expansion_placeholder"
--wrapper around minetest.register_node that sets sane defaults and interprets some specialized settings
function homedecor.register(name, original_def)
local def = table.copy(original_def)
def.drawtype = def.drawtype
or (def.mesh and "mesh")
or (def.node_box and "nodebox")
def.paramtype = def.paramtype or "light"
-- avoid facedir for some drawtypes as they might be used internally for something else
-- even if undocumented
if not (def.drawtype == "glasslike_framed"
or def.drawtype == "raillike"
or def.drawtype == "plantlike"
or def.drawtype == "firelike") then
def.paramtype2 = def.paramtype2 or "facedir"
end
homedecor.handle_inventory(name, def, original_def)
local infotext = def.infotext
--def.infotext = nil -- currently used to set locked refrigerator infotexts
if infotext then
local on_construct = def.on_construct
def.on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", infotext)
if on_construct then on_construct(pos) end
end
end
local expand = def.expand
def.expand = nil
local after_unexpand = def.after_unexpand
def.after_unexpand = nil
if expand then
-- dissallow rotating only half the expanded node by default
-- unless we know better
def.on_rotate = def.on_rotate
or (def.mesh and expand.top and screwdriver.rotate_simple)
or screwdriver.disallow
def.on_place = def.on_place or function(itemstack, placer, pointed_thing)
if expand.top then
return homedecor.stack_vertically(itemstack, placer, pointed_thing, itemstack:get_name(), expand.top)
elseif expand.right then
return homedecor.stack_sideways(itemstack, placer, pointed_thing, itemstack:get_name(), expand.right, true)
elseif expand.forward then
return homedecor.stack_sideways(itemstack, placer, pointed_thing, itemstack:get_name(), expand.forward, false)
end
end
def.after_dig_node = def.after_dig_node or function(pos, oldnode, oldmetadata, digger)
if expand.top and expand.forward ~= "air" then
local top_pos = { x=pos.x, y=pos.y+1, z=pos.z }
local node = minetest.get_node(top_pos).name
if node == expand.top or node == placeholder_node then
minetest.remove_node(top_pos)
end
end
local fdir = oldnode.param2
if not fdir or fdir > 3 then return end
if expand.right and expand.forward ~= "air" then
local right_pos = { x=pos.x+homedecor.fdir_to_right[fdir+1][1], y=pos.y, z=pos.z+homedecor.fdir_to_right[fdir+1][2] }
local node = minetest.get_node(right_pos).name
if node == expand.right or node == placeholder_node then
minetest.remove_node(right_pos)
end
end
if expand.forward and expand.forward ~= "air" then
local forward_pos = { x=pos.x+homedecor.fdir_to_fwd[fdir+1][1], y=pos.y, z=pos.z+homedecor.fdir_to_fwd[fdir+1][2] }
local node = minetest.get_node(forward_pos).name
if node == expand.forward or node == placeholder_node then
minetest.remove_node(forward_pos)
end
end
if after_unexpand then
after_unexpand(pos)
end
end
end
-- register the actual minetest node
minetest.register_node(":homedecor:" .. name, def)
end

34
homedecor_common/sit.lua Normal file
View File

@ -0,0 +1,34 @@
function homedecor.sit(pos, node, clicker)
return -- delete it when the engine is stabler for the player's physics
--[[
local meta = minetest.get_meta(pos)
local param2 = node.param2
local name = clicker:get_player_name()
if name == meta:get_string("is_sit") then
meta:set_string("is_sit", "")
pos.y = pos.y-0.5
clicker:setpos(pos)
clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
clicker:set_physics_override(1, 1, 1)
default.player_attached[name] = false
default.player_set_animation(clicker, "stand", 30)
else
meta:set_string("is_sit", clicker:get_player_name())
clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
clicker:set_physics_override(0, 0, 0)
clicker:setpos(pos)
default.player_attached[name] = true
default.player_set_animation(clicker, "sit", 30)
if param2 == 0 then
clicker:set_look_yaw(3.15)
elseif param2 == 1 then
clicker:set_look_yaw(7.9)
elseif param2 == 2 then
clicker:set_look_yaw(6.28)
elseif param2 == 3 then
clicker:set_look_yaw(4.75)
else return end
end
--]]
end

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

View File

@ -0,0 +1,24 @@
#! /bin/bash
# To create a new translation:
# msginit --locale=ll_CC -o locale/ll_CC.po -i locale/template.pot
cd "$(dirname "${BASH_SOURCE[0]}")/..";
# Extract translatable strings.
xgettext --from-code=UTF-8 \
--language=Lua \
--sort-by-file \
--keyword=S \
--keyword=NS:1,2 \
--keyword=N_ \
--add-comments='Translators:' \
--add-location=file \
-o locale/template.pot \
$(find .. -name '*.lua')
# Update translations.
find locale -name '*.po' | while read -r file; do
echo $file
msgmerge --update $file locale/template.pot;
done

View File

@ -0,0 +1,115 @@
-- variables taken by the start... function
--
-- pos and node are as usual, from e.g. on_rightclick.
--
-- in the { particledef } table:
--
-- outletx/y/z are the exact coords of the starting point
-- for the spawner, relative to the center of the node
--
-- velocityx/y/z are the speed of the particles,
-- (x and z are relative to a node placed while looking north/facedir 0)
-- negative Y values flow downward.
--
-- spread is the radius from the starting point,
-- along X and Z only, to randomly spawn particles.
--
-- soundname is the filename (without .ogg) of the sound file
-- to be played along with the particle stream
function homedecor.start_particle_spawner(pos, node, particledef, soundname)
local this_spawner_meta = minetest.get_meta(pos)
local id = this_spawner_meta:get_int("active")
local s_handle = this_spawner_meta:get_int("sound")
if id ~= 0 then
if s_handle then
minetest.after(0, function(handle)
minetest.sound_stop(handle)
end, s_handle)
end
minetest.delete_particlespawner(id)
this_spawner_meta:set_int("active", 0)
this_spawner_meta:set_int("sound", 0)
return
end
local fdir = node.param2
if fdir and fdir < 4 and (not id or id == 0) then
local outletx = particledef.outlet.x
local outlety = particledef.outlet.y
local outletz = particledef.outlet.z
local velocityx = particledef.velocity_x
local velocityy = particledef.velocity_y
local velocityz = particledef.velocity_z
local spread = particledef.spread
local minx_t = { outletx - spread, -outletz - spread, outletx - spread, outletz - spread }
local maxx_t = { outletx + spread, -outletz + spread, outletx + spread, outletz + spread }
local minz_t = { -outletz - spread, outletx - spread, outletz - spread, outletx - spread }
local maxz_t = { -outletz + spread, outletx + spread, outletz + spread, outletx + spread }
local minvelx_t = { velocityx.min, velocityz.min, -velocityx.max, -velocityz.max }
local maxvelx_t = { velocityx.max, velocityz.max, -velocityx.min, -velocityz.min }
local minvelz_t = { velocityz.min, velocityx.min, -velocityz.max, velocityx.min }
local maxvelz_t = { velocityz.max, velocityx.max, -velocityz.min, velocityx.max }
local minx = minx_t[fdir + 1]
local maxx = maxx_t[fdir + 1]
local minz = minz_t[fdir + 1]
local maxz = maxz_t[fdir + 1]
local minvelx = minvelx_t[fdir + 1]
local minvelz = minvelz_t[fdir + 1]
local maxvelx = maxvelx_t[fdir + 1]
local maxvelz = maxvelz_t[fdir + 1]
id = minetest.add_particlespawner({
amount = 60,
time = 0,
collisiondetection = true,
collision_removal = particledef.die_on_collision,
minpos = {x=pos.x - minx, y=pos.y + outlety, z=pos.z - minz},
maxpos = {x=pos.x - maxx, y=pos.y + outlety, z=pos.z - maxz},
minvel = {x = minvelx, y = velocityy, z = minvelz},
maxvel = {x = maxvelx, y = velocityy, z = maxvelz},
minacc = {x=0, y=0, z=0},
maxacc = {x=0, y=-0.05, z=0},
minexptime = 2,
maxexptime = 4,
minsize = 0.5,
maxsize = 1,
texture = "homedecor_water_particle.png",
})
s_handle = minetest.sound_play(soundname, {
pos = pos,
max_hear_distance = 5,
loop = true
})
this_spawner_meta:set_int("active", id)
this_spawner_meta:set_int("sound", s_handle)
return
end
end
function homedecor.stop_particle_spawner(pos)
local this_spawner_meta = minetest.get_meta(pos)
local id = this_spawner_meta:get_int("active")
local s_handle = this_spawner_meta:get_int("sound")
if id ~= 0 then
minetest.delete_particlespawner(id)
end
if s_handle then
minetest.after(0, function(handle)
minetest.sound_stop(handle)
end, s_handle)
end
this_spawner_meta:set_int("active", 0)
this_spawner_meta:set_int("sound", 0)
end