mirror of
https://github.com/mt-mods/homedecor_modpack.git
synced 2025-06-28 12:56:01 +02:00
move handlers into subdirectory to split them apart from the actual game content
This commit is contained in:
115
homedecor/handlers/expansion.lua
Normal file
115
homedecor/handlers/expansion.lua
Normal file
@ -0,0 +1,115 @@
|
||||
local S = homedecor.gettext
|
||||
|
||||
-- selects which node was pointed at based on it being known, and either clickable or buildable_to
|
||||
local function select_node(pointed_thing)
|
||||
local pos = pointed_thing.under
|
||||
local def = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||
|
||||
if not def or (not def.on_rightclick and not def.buildable_to) then
|
||||
pos = pointed_thing.above
|
||||
def = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||
end
|
||||
return pos, def
|
||||
end
|
||||
|
||||
-- abstract function checking if 2 given nodes can and may be build to a place
|
||||
local function is_buildable_to(placer_name, pos, def, pos2)
|
||||
local def = def or minetest.registered_nodes[minetest.get_node(pos).name]
|
||||
local def2 = minetest.registered_nodes[minetest.get_node(pos2).name]
|
||||
|
||||
return def and def.buildable_to and def2 and def2.buildable_to
|
||||
and not minetest.is_protected(pos, placer_name)
|
||||
and not minetest.is_protected(pos2, placer_name)
|
||||
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)
|
||||
local placer_name = placer:get_player_name() or ""
|
||||
if is_buildable_to(placer_name, pos, def, pos2) then
|
||||
local fdir = fdir or minetest.dir_to_facedir(placer:get_look_dir())
|
||||
minetest.set_node(pos, { name = node1, param2 = fdir })
|
||||
node2 = node2 or "air" -- this can be used to clear buildable_to nodes even though we are using a multinode mesh
|
||||
minetest.set_node(pos2, { name = node2, param2 = (node2 ~= "air" and fdir) or nil })
|
||||
|
||||
-- temporary check if this is a locked node to set its infotext
|
||||
local nodename = itemstack:get_name()
|
||||
if string.find(nodename, "_locked") then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("owner", placer_name)
|
||||
meta:set_string("infotext", S("Locked %s (owned by %s)"):format(minetest.registered_nodes[nodename].infotext, placer_name))
|
||||
end
|
||||
|
||||
if not homedecor.expect_infinite_stacks then
|
||||
itemstack:take_item()
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
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 pos, def = select_node(pointed_thing)
|
||||
if def.on_rightclick then
|
||||
return def.on_rightclick(pointed_thing.under, minetest.get_node(pos), placer, 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)
|
||||
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
|
||||
local fdir_to_left = {
|
||||
{ -1, 0 },
|
||||
{ 0, 1 },
|
||||
{ 1, 0 },
|
||||
{ 0, -1 },
|
||||
}
|
||||
function homedecor.stack_wing(itemstack, placer, pointed_thing, node1, node2, node1_right, node2_right)
|
||||
local pos, def = select_node(pointed_thing)
|
||||
if def.on_rightclick then
|
||||
return def.on_rightclick(pointed_thing.under, minetest.get_node(pos), placer, 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 + fdir_to_left[fdir+1][1], y=pos.y, z = pos.z + 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)
|
||||
end
|
||||
|
||||
-- Place one node right of or behind another
|
||||
homedecor.fdir_to_right = {
|
||||
{ 1, 0 },
|
||||
{ 0, -1 },
|
||||
{ -1, 0 },
|
||||
{ 0, 1 },
|
||||
}
|
||||
|
||||
homedecor.fdir_to_fwd = {
|
||||
{ 0, 1 },
|
||||
{ 1, 0 },
|
||||
{ 0, -1 },
|
||||
{ -1, 0 },
|
||||
}
|
||||
|
||||
function homedecor.stack_sideways(itemstack, placer, pointed_thing, node1, node2, dir)
|
||||
local pos, def = select_node(pointed_thing)
|
||||
if def.on_rightclick then
|
||||
return def.on_rightclick(pointed_thing.under, minetest.get_node(pos), placer, 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)
|
||||
end
|
347
homedecor/handlers/furnaces.lua
Normal file
347
homedecor/handlers/furnaces.lua
Normal file
@ -0,0 +1,347 @@
|
||||
-- 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 hacky_swap_node(pos,name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta0 = meta:to_table()
|
||||
node.name = name
|
||||
local meta0 = meta:to_table()
|
||||
minetest.set_node(pos,node)
|
||||
meta = minetest.get_meta(pos)
|
||||
meta:from_table(meta0)
|
||||
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;]"
|
||||
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
|
||||
|
||||
function homedecor.register_furnace(name, furnacedef)
|
||||
|
||||
local furnacedef = furnacedef
|
||||
|
||||
local tiles = make_tiles(furnacedef.tiles, furnacedef.tile_format, false)
|
||||
local tiles_active = make_tiles(furnacedef.tiles_active, furnacedef.tile_format, true)
|
||||
|
||||
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 name_active = name.."_active"
|
||||
|
||||
local desc = furnacedef.description or "Furnace"
|
||||
|
||||
local def = {
|
||||
description = furnacedef.description,
|
||||
tiles = tiles,
|
||||
paramtype2 = furnacedef.paramtype2 or "facedir",
|
||||
groups = furnacedef.groups or {cracky=2},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = furnacedef.sounds or default.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", make_formspec(furnacedef, 0))
|
||||
meta:set_string("infotext", desc)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("fuel", 1)
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("dst", furnacedef.output_slots)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("fuel") then
|
||||
return false
|
||||
elseif not inv:is_empty("dst") then
|
||||
return false
|
||||
elseif not inv:is_empty("src") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
allow_metadata_inventory_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("%s is empty"):format(desc))
|
||||
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,
|
||||
allow_metadata_inventory_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("%s is empty"):format(desc))
|
||||
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_active = {
|
||||
description = furnacedef.description.." (active)",
|
||||
tiles = tiles_active,
|
||||
paramtype = furnacedef.paramtype,
|
||||
paramtype2 = furnacedef.paramtype2 or "facedir",
|
||||
light_source = 8,
|
||||
drop = name,
|
||||
groups = furnacedef.groups or {cracky=2, not_in_creative_inventory=1},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = furnacedef.sounds or default.node_sound_stone_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", make_formspec(furnacedef, 0))
|
||||
meta:set_string("infotext", desc)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("fuel", 1)
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("dst", furnacedef.output_slots)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("fuel") then
|
||||
return false
|
||||
elseif not inv:is_empty("dst") then
|
||||
return false
|
||||
elseif not inv:is_empty("src") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
allow_metadata_inventory_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("%s is empty"):format(desc))
|
||||
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,
|
||||
allow_metadata_inventory_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("%s is empty"):format(desc))
|
||||
end
|
||||
return count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif to_list == "src" then
|
||||
return count
|
||||
elseif to_list == "dst" then
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
minetest.register_node(name, def)
|
||||
minetest.register_node(name_active, def_active)
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {name, name_active, name.."_locked", name_active.."_locked"},
|
||||
interval = 1.0,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
for i, name in ipairs({
|
||||
"fuel_totaltime",
|
||||
"fuel_time",
|
||||
"src_totaltime",
|
||||
"src_time"
|
||||
}) do
|
||||
if meta:get_string(name) == "" then
|
||||
meta:set_float(name, 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])
|
||||
else
|
||||
print(S("Could not insert '%s'"):format(cooked.item:to_string()))
|
||||
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[name..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("%s active: %d%%"):format(desc,percent))
|
||||
hacky_swap_node(pos,name_active..locked)
|
||||
meta:set_string("formspec", make_formspec(furnacedef, percent))
|
||||
return
|
||||
end
|
||||
|
||||
local fuel = nil
|
||||
local afterfuel
|
||||
local cooked = nil
|
||||
local fuellist = inv:get_list("fuel")
|
||||
local 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",desc..S(": Out of fuel"))
|
||||
hacky_swap_node(pos,name..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("%s is empty"):format(desc))
|
||||
hacky_swap_node(pos,name..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", desc..S(": output bins are full"))
|
||||
hacky_swap_node(pos, name..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
|
161
homedecor/handlers/locked.lua
Normal file
161
homedecor/handlers/locked.lua
Normal file
@ -0,0 +1,161 @@
|
||||
-- Locked Stuff for Home Decor mod, by Kaeza
|
||||
--
|
||||
-- The code is mostly copypasta from default:chest_locked, with a few
|
||||
-- tidbits to ease creation of new items, should need arise.
|
||||
|
||||
local S = homedecor.gettext
|
||||
|
||||
--[[
|
||||
| create_locked ( name, infotext )
|
||||
|
|
||||
| Description:
|
||||
| This function takes a base node name such as "homedecor:refrigerator",
|
||||
| copies the definition from the original item into a new table, modifies
|
||||
| it a bit, and registers a new node with a "_locked" suffix such as
|
||||
| "homedecor:refrigerator_locked". The new node behaves identically to
|
||||
| the base node, except that moving items to/from the node's inventory
|
||||
| is only allowed for the original placer. In addition, it register a new
|
||||
| shapeless recipe for the node, using the base node plus a steel ingot.
|
||||
|
|
||||
| Arguments:
|
||||
| name The base node name
|
||||
| infotext The infotext description (in case the name is too long).
|
||||
|
|
||||
| Example Usage:
|
||||
| create_locked("homedecor:refrigerator", "Locked Fridge")
|
||||
| ^ This generates a new "Locked Refrigerator" node, whose infotext is
|
||||
| "Locked Fridge (owned by <placer>)".
|
||||
|
|
||||
| Notes:
|
||||
| If <infotext> is not specified (or is nil), the infotext will be the
|
||||
| base node's description prefixed by "Locked ".
|
||||
|
|
||||
| The ABM for the locked oven is defined in oven.lua.
|
||||
]]
|
||||
local function create_locked ( name, infotext )
|
||||
local def = { }
|
||||
for k, v in pairs(minetest.registered_nodes[name]) do
|
||||
def[k] = v
|
||||
end
|
||||
def.type = nil
|
||||
def.name = nil
|
||||
def.description = S("%s (Locked)"):format(def.description)
|
||||
local after_place_node = def.after_place_node
|
||||
def.after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("owner", placer:get_player_name() or "")
|
||||
meta:set_string("infotext", S("%s (owned by %s)"):format(infotext,meta:get_string("owner")))
|
||||
if (after_place_node) then
|
||||
return after_place_node(pos, placer)
|
||||
end
|
||||
end
|
||||
local allow_metadata_inventory_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)
|
||||
if (player:get_player_name() ~= meta:get_string("owner")) then
|
||||
minetest.log("action", S("%s tried to access a %s belonging to %s at %s"):format(
|
||||
player:get_player_name(),
|
||||
infotext,
|
||||
meta:get_string("owner"),
|
||||
minetest.pos_to_string(pos)
|
||||
))
|
||||
return 0
|
||||
end
|
||||
if (allow_metadata_inventory_move) then
|
||||
return allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
else
|
||||
return count
|
||||
end
|
||||
end
|
||||
local allow_metadata_inventory_put = def.allow_metadata_inventory_put;
|
||||
def.allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if (player:get_player_name() ~= meta:get_string("owner")) then
|
||||
minetest.log("action", S("%s tried to access a %s belonging to %s at %s"):format(
|
||||
player:get_player_name(),
|
||||
infotext,
|
||||
meta:get_string("owner"),
|
||||
minetest.pos_to_string(pos)
|
||||
))
|
||||
return 0
|
||||
end
|
||||
if (allow_metadata_inventory_put) then
|
||||
return allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
else
|
||||
return stack:get_count()
|
||||
end
|
||||
end
|
||||
local allow_metadata_inventory_take = def.allow_metadata_inventory_take;
|
||||
def.allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if (player:get_player_name() ~= meta:get_string("owner")) then
|
||||
minetest.log("action", S("%s tried to access a %s belonging to %s at %s"):format(
|
||||
player:get_player_name(),
|
||||
infotext,
|
||||
meta:get_string("owner"),
|
||||
minetest.pos_to_string(pos)
|
||||
))
|
||||
return 0
|
||||
end
|
||||
if (allow_metadata_inventory_take) then
|
||||
return allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
else
|
||||
return stack:get_count()
|
||||
end
|
||||
end
|
||||
minetest.register_node(name.."_locked", def)
|
||||
minetest.register_craft({
|
||||
output = name.."_locked",
|
||||
type = "shapeless",
|
||||
recipe = {
|
||||
name,
|
||||
"default:steel_ingot",
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
local items = {
|
||||
{ "refrigerator_white_bottom",
|
||||
"Refrigerator" },
|
||||
{ "refrigerator_steel_bottom",
|
||||
"Refrigerator (stainless steel)" },
|
||||
{ "kitchen_cabinet",
|
||||
"Cabinet" },
|
||||
{ "kitchen_cabinet_steel",
|
||||
"Cabinet (stainless steel top)" },
|
||||
{ "kitchen_cabinet_granite",
|
||||
"Cabinet (granite top)" },
|
||||
{ "kitchen_cabinet_marble",
|
||||
"Cabinet (marble top)" },
|
||||
{ "kitchen_cabinet_half",
|
||||
"Cabinet" },
|
||||
{ "kitchen_cabinet_with_sink",
|
||||
"Cabinet" },
|
||||
{ "nightstand_oak_one_drawer",
|
||||
"Nightstand" },
|
||||
{ "nightstand_oak_two_drawers",
|
||||
"Nightstand" },
|
||||
{ "nightstand_mahogany_one_drawer",
|
||||
"Nightstand" },
|
||||
{ "nightstand_mahogany_two_drawers",
|
||||
"Nightstand" },
|
||||
{ "filing_cabinet",
|
||||
"Filing cabinet" },
|
||||
{ "oven",
|
||||
"Oven" },
|
||||
{ "oven_active",
|
||||
"Oven (active)" },
|
||||
{ "oven_steel",
|
||||
"Oven (stainless steel)" },
|
||||
{ "oven_steel_active",
|
||||
"Oven (stainless steel, active)" },
|
||||
{ "microwave_oven",
|
||||
"Microwave Oven" },
|
||||
{ "microwave_oven_active",
|
||||
"Microwave Oven (active)" },
|
||||
}
|
||||
|
||||
for _,item in ipairs(items) do
|
||||
local name, info = item[1], item[2];
|
||||
create_locked("homedecor:"..name, S("Locked "..info));
|
||||
end
|
39
homedecor/handlers/nodeboxes.lua
Normal file
39
homedecor/handlers/nodeboxes.lua
Normal file
@ -0,0 +1,39 @@
|
||||
-- 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_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_z = function(depth) return { -0.5, -0.5, -0.5+depth, 0.5, 0.5, 0.5 } 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 } },
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
155
homedecor/handlers/registration.lua
Normal file
155
homedecor/handlers/registration.lua
Normal file
@ -0,0 +1,155 @@
|
||||
homedecor = homedecor or {}
|
||||
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 default_inventory_size = 32
|
||||
local default_inventory_formspecs = {
|
||||
["4"]="size[8,6]"..
|
||||
"list[context;main;2,0;4,1;]"..
|
||||
"list[current_player;main;0,2;8,4;]",
|
||||
|
||||
["6"]="size[8,6]"..
|
||||
"list[context;main;1,0;6,1;]"..
|
||||
"list[current_player;main;0,2;8,4;]",
|
||||
|
||||
["8"]="size[8,6]"..
|
||||
"list[context;main;0,0;8,1;]"..
|
||||
"list[current_player;main;0,2;8,4;]",
|
||||
|
||||
["12"]="size[8,7]"..
|
||||
"list[context;main;1,0;6,2;]"..
|
||||
"list[current_player;main;0,3;8,4;]",
|
||||
|
||||
["16"]="size[8,7]"..
|
||||
"list[context;main;0,0;8,2;]"..
|
||||
"list[current_player;main;0,3;8,4;]",
|
||||
|
||||
["24"]="size[8,8]"..
|
||||
"list[context;main;0,0;8,3;]"..
|
||||
"list[current_player;main;0,4;8,4;]",
|
||||
|
||||
["32"]="size[8,9]".. default.gui_bg .. default.gui_bg_img .. default.gui_slots ..
|
||||
"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]"..
|
||||
default.get_hotbar_bg(0,4.85),
|
||||
|
||||
["50"]="size[10,10]"..
|
||||
"list[context;main;0,0;10,5;]"..
|
||||
"list[current_player;main;1,6;8,4;]",
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
--wrapper around minetest.register_node that sets sane defaults and interprets some specialized settings
|
||||
function homedecor.register(name, def)
|
||||
def.paramtype = def.paramtype or "light"
|
||||
def.paramtype2 = def.paramtype2 or "facedir"
|
||||
|
||||
def.drawtype = def.drawtype
|
||||
or (def.mesh and "mesh")
|
||||
or (def.node_box and "nodebox")
|
||||
|
||||
local infotext = def.infotext
|
||||
--def.infotext = nil -- currently used to set locked refrigerator infotexts
|
||||
|
||||
-- handle inventory setting
|
||||
-- inventory = {
|
||||
-- size = 16
|
||||
-- formspec = …
|
||||
-- }
|
||||
local inventory = def.inventory
|
||||
def.inventory = nil
|
||||
|
||||
if inventory then
|
||||
def.on_construct = def.on_construct or function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if infotext then
|
||||
meta:set_string("infotext", infotext)
|
||||
end
|
||||
local size = inventory.size or default_inventory_size
|
||||
meta:get_inventory():set_size("main", size)
|
||||
meta:set_string("formspec", inventory.formspec or get_formspec_by_size(size))
|
||||
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("%s moves stuff in %s at %s"):format(
|
||||
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("%s moves stuff to %s at %s"):format(
|
||||
player:get_player_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("%s takes stuff from %s at %s"):format(
|
||||
player:get_player_name(), name, minetest.pos_to_string(pos)
|
||||
))
|
||||
end
|
||||
elseif infotext and not def.on_construct then
|
||||
def.on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", infotext)
|
||||
end
|
||||
end
|
||||
|
||||
local expand = def.expand
|
||||
def.expand = nil
|
||||
local after_unexpand = def.after_unexpand
|
||||
def.after_unexpand = nil
|
||||
|
||||
if expand then
|
||||
def.on_place = def.on_place or function(itemstack, placer, pointed_thing)
|
||||
if expand.top then
|
||||
homedecor.stack_vertically(itemstack, placer, pointed_thing, itemstack:get_name(), expand.top)
|
||||
end
|
||||
if expand.right then
|
||||
homedecor.stack_sideways(itemstack, placer, pointed_thing, itemstack:get_name(), expand.right, true)
|
||||
end
|
||||
if expand.forward then
|
||||
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 }
|
||||
if minetest.get_node(top_pos).name == expand.top 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] }
|
||||
if minetest.get_node(right_pos).name == expand.right 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] }
|
||||
if minetest.get_node(forward_pos).name == expand.forward 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
|
Reference in New Issue
Block a user