370 lines
10 KiB
Lua
370 lines
10 KiB
Lua
-- Facade Shaper
|
|
-- This machine serves the same purpose as the circular saw from moreblocks or the milling
|
|
-- maching from mymillwork. Namely, it provides a tool for creating shaped blocks that does
|
|
-- not rely on using recipes.
|
|
|
|
|
|
-- Balancing output per 1 input block with respect to apparent volume of output shape.
|
|
-- All current shapes are added, but shapes not present in this table will still be produced
|
|
-- one at a time — if that is the desired quantity, adding them is not required.
|
|
local output_ratios = {
|
|
bannerstone = 1,
|
|
bannerstone_corner = 1,
|
|
centerstone = 1,
|
|
column = 1,
|
|
column_corner = 1,
|
|
corbel = 1,
|
|
corbel_corner = 1,
|
|
corbel_corner_inner = 1,
|
|
carved_stone_a = 1,
|
|
carved_stone_a_corner = 1,
|
|
rgspro = 2,
|
|
rgspro_inner_corner = 1,
|
|
rgspro_outer_corner = 1,
|
|
corner_bricks = 2,
|
|
columnia_mid = 4,
|
|
columnia_bottom = 1,
|
|
columnia_top = 1,
|
|
columnia_crosslink = 1,
|
|
columnia_link = 4,
|
|
columnia_linkdown = 4,
|
|
}
|
|
|
|
-- The material to be used for buttons when no material is actually loaded.
|
|
-- It should be a generic material for which all the facade shapes are defined.
|
|
local demo_material = "default:stone"
|
|
|
|
-- Whether the facade should obey area protection for the inventories (as machines in technic mod)
|
|
-- or allow anybody to use them, but disallow the removal of machine itself (like circular saw in moreblocks)
|
|
local protect_inventories = false
|
|
|
|
|
|
|
|
local function prepare_formspec (material_name)
|
|
|
|
local output = string.gsub(material_name, "^.*:", "facade:")
|
|
|
|
local shaper_formspec =
|
|
|
|
"size[8,11;]"..
|
|
"label[0,0;" .. "Choose shape to produce:" .. "]"..
|
|
|
|
-- row 1, blocky shapes
|
|
"item_image_button[0,0.5;1,1;" .. output .. "_bannerstone" .. ";bannerstone; ]"..
|
|
"item_image_button[1,0.5;1,1;" .. output .. "_bannerstone_corner" .. ";bannerstone_corner; ]"..
|
|
"item_image_button[2,0.5;1,1;" .. output .. "_centerstone" .. ";centerstone; ]"..
|
|
"item_image_button[3,0.5;1,1;" .. output .. "_carved_stone_a" .. ";carved_stone_a; ]"..
|
|
"item_image_button[4,0.5;1,1;" .. output .. "_carved_stone_a_corner" .. ";carved_stone_a_corner; ]"..
|
|
"item_image_button[5,0.5;1,1;" .. output .. "_column" .. ";column; ]"..
|
|
"item_image_button[6,0.5;1,1;" .. output .. "_column_corner" .. ";column_corner; ]"..
|
|
|
|
-- row 2, corbel
|
|
"item_image_button[0,1.5;1,1;" .. output .. "_corbel" .. ";corbel; ]"..
|
|
"item_image_button[1,1.5;1,1;" .. output .. "_corbel_corner_inner" .. ";corbel_corner_inner; ]"..
|
|
"item_image_button[2,1.5;1,1;" .. output .. "_corbel_corner" .. ";corbel_corner; ]"..
|
|
|
|
-- row 3, cornice
|
|
"item_image_button[0,2.5;1,1;" .. output .. "_rgspro" .. ";rgspro; ]"..
|
|
"item_image_button[1,2.5;1,1;" .. output .. "_rgspro_inner_corner" .. ";rgspro_inner_corner; ]"..
|
|
"item_image_button[2,2.5;1,1;" .. output .. "_rgspro_outer_corner" .. ";rgspro_outer_corner; ]"
|
|
|
|
-- row 4, columnia
|
|
if not minetest.get_modpath("columnia") then
|
|
shaper_formspec = shaper_formspec ..
|
|
"item_image_button[0,3.5;1,1;" .. output .. "_columnia_mid" .. ";columnia_mid; ]"..
|
|
"item_image_button[1,3.5;1,1;" .. output .. "_columnia_bottom" .. ";columnia_bottom; ]"..
|
|
"item_image_button[2,3.5;1,1;" .. output .. "_columnia_crosslink" .. ";columnia_crosslink; ]"..
|
|
"item_image_button[3,3.5;1,1;" .. output .. "_columnia_link" .. ";columnia_link; ]"..
|
|
"item_image_button[4,3.5;1,1;" .. output .. "_columnia_linkdown" .. ";columnia_linkdown; ]"
|
|
|
|
-- this code is a provision in case top column pieces enter service
|
|
if minetest.registered_nodes[output .. "_columnia_top"] then
|
|
shaper_formspec = shaper_formspec ..
|
|
"item_image_button[5,3.5;1,1;" .. output .. "_columnia_top" .. ";columnia_top; ]"
|
|
end
|
|
|
|
end
|
|
|
|
-- row 5 for shapes which are not available for all materials
|
|
-- only one such shape exists so far, but more should be easy to add here
|
|
|
|
if minetest.registered_nodes[output .. "_corner_bricks"] then
|
|
shaper_formspec = shaper_formspec ..
|
|
"item_image_button[0,4.5;1,1;" .. output .. "_corner_bricks" .. ";corner_bricks; ]"
|
|
end
|
|
|
|
-- inventory part
|
|
|
|
shaper_formspec = shaper_formspec ..
|
|
|
|
"label[0, 5.5;".."In:".."]"..
|
|
"list[current_name;src;1,5.5;1,1;]"..
|
|
"label[3, 5.5;".."Out:".."]"..
|
|
"list[current_name;dst;4,5.5;4,1;]"..
|
|
|
|
"list[current_player;main;0,7;8,4;]"..
|
|
"listring[current_name;dst]"..
|
|
"listring[current_player;main]"..
|
|
"listring[current_name;src]"..
|
|
"listring[current_player;main]"
|
|
|
|
return(shaper_formspec)
|
|
|
|
end
|
|
|
|
|
|
-- a simple check for compatibile materials
|
|
local function check_material_applicability (material)
|
|
-- using centerstone node here, since it appears to be both one of the oldest
|
|
-- and defined for all materials as well, making it suitable for a quick check
|
|
if minetest.registered_nodes[string.gsub(material, "^.*:", "facade:") .. "_centerstone"] then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
|
|
-- update the buttons to show shapes made from the actual material
|
|
local function update_formspec_put (pos, listname, index, stack, player)
|
|
|
|
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
|
|
return
|
|
end
|
|
|
|
if listname ~= "src" then
|
|
return
|
|
end
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
local material_name = stack:get_name()
|
|
|
|
if check_material_applicability(material_name) then
|
|
meta:set_string("formspec", prepare_formspec(material_name))
|
|
else
|
|
return
|
|
end
|
|
|
|
end
|
|
|
|
|
|
-- update the buttons to show shapes made from demo material if all material is removed
|
|
local function update_formspec_take (pos, listname, index, stack, player)
|
|
|
|
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
|
|
return
|
|
end
|
|
|
|
if listname ~= "src" then
|
|
return
|
|
end
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
|
|
if inv:is_empty("src") then
|
|
meta:set_string("formspec", prepare_formspec(demo_material))
|
|
end
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
-- disallow putting in materials which are not supported
|
|
local function check_inventory_put (pos, listname, index, stack, player)
|
|
|
|
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
|
|
return 0
|
|
end
|
|
|
|
if listname ~= "src" then
|
|
return 0
|
|
end
|
|
|
|
local material_name = stack:get_name()
|
|
|
|
if check_material_applicability(material_name) then
|
|
return(stack:get_count())
|
|
else
|
|
return 0
|
|
end
|
|
end
|
|
|
|
|
|
local function check_inventory_take (pos, listname, index, stack, player)
|
|
|
|
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
|
|
return 0
|
|
end
|
|
|
|
if listname ~= "src" and listname ~= "dst" then
|
|
return 0
|
|
end
|
|
|
|
return(stack:get_count())
|
|
|
|
end
|
|
|
|
local function check_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
|
|
|
|
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
|
|
return 0
|
|
end
|
|
|
|
return(stack:get_count())
|
|
|
|
end
|
|
|
|
-- process the form fields and convert source material to desired shapes
|
|
local function form_handler(pos, formname, fields, sender)
|
|
|
|
if protect_inventories and minetest.is_protected(pos, sender:get_player_name()) then
|
|
return
|
|
end
|
|
|
|
if fields.quit then
|
|
return
|
|
end
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
|
|
if inv:is_empty("src") then
|
|
return
|
|
end
|
|
|
|
local inputstack = inv:get_stack("src", 1)
|
|
local inputname = inputstack:get_name()
|
|
|
|
for shape,_ in pairs(fields) do
|
|
|
|
local result = string.gsub(inputname, "^.*:", "facade:") .. "_" .. shape
|
|
|
|
-- one can never be overly paranoid, unlike the quick check before, this one is precise
|
|
if not minetest.registered_nodes[result] then
|
|
return
|
|
end
|
|
|
|
-- output quantities are adjusted to preserve roughly same mass of resulting products
|
|
if output_ratios[shape] then
|
|
result = result .. " " .. output_ratios[shape]
|
|
end
|
|
|
|
if not inv:room_for_item("dst", result) then
|
|
return
|
|
end
|
|
|
|
inputstack:take_item(1)
|
|
inv:set_stack("src", 1, inputstack)
|
|
inv:add_item("dst", result)
|
|
|
|
end
|
|
return
|
|
end
|
|
|
|
local function check_removability (pos, player)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
local owner = meta:set_string("owner")
|
|
local pname = player:get_player_name()
|
|
local inv = meta:get_inventory()
|
|
|
|
-- owner may always remove the device
|
|
if owner and owner ~= "" and pname and pname ~= "" and owner == pname then
|
|
if inv:is_empty("src") and inv:is_empty("dst") then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
if minetest.is_protected(pos, player:get_player_name()) then
|
|
return false
|
|
end
|
|
|
|
if inv:is_empty("src") and inv:is_empty("dst") then
|
|
return true
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
minetest.register_node("facade:shaper", {
|
|
description = "Shaper Machine",
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
-- base
|
|
{-1/2, -1/2, -1/2, 1/2, -14/32, 1/2},
|
|
-- back
|
|
{-8/32, -1/2, 12/32, 8/32, 1/2, 16/32},
|
|
-- table
|
|
{-8/32, -4/32, -16/32, 8/32, 4/32, 16/32},
|
|
-- rear table sliding support
|
|
{-16/32, -4/32, 12/32, 16/32, 4/32, 16/32},
|
|
-- front table sliding support
|
|
{-8/32, -14/32, -12/32, 8/32, -4/32, -16/32},
|
|
-- top tool beam
|
|
{-4/32, 16/32, -8/32, 4/32, 12/32, 12/32},
|
|
-- cutter holder
|
|
{-2/32, 7/32, -2/32, 2/32, 14/32, 2/32},
|
|
-- cutter
|
|
{-1/128, 6/32, -1/32, 1/128, 7/32, 1/32},
|
|
},
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-1/2, -1/2, -1/2, 1/2, 1/2, 1/2},
|
|
},
|
|
},
|
|
tiles = { "facade_shaper_top.png",
|
|
"facade_shaper_bottom.png",
|
|
"facade_shaper_right.png",
|
|
"facade_shaper_left.png",
|
|
"facade_shaper_back.png",
|
|
"facade_shaper_front.png"},
|
|
groups = { oddly_breakable_by_hand=2, cracky=3, dig_immediate=1 },
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
legacy_facedir_simple = true,
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("formspec", prepare_formspec(demo_material))
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("src", 1)
|
|
inv:set_size("dst", 4)
|
|
end,
|
|
after_place_node = function(pos, placer)
|
|
local meta = minetest.get_meta(pos)
|
|
local owner = placer and placer:get_player_name() or ""
|
|
meta:set_string("owner", owner)
|
|
if owner then
|
|
meta:set_string("infotext", ("Facade Shaper (owned by %s)"):format(owner))
|
|
else
|
|
meta:set_string("infotext", "Facade Shaper")
|
|
end
|
|
end,
|
|
can_dig = check_removability,
|
|
allow_metadata_inventory_put = check_inventory_put,
|
|
allow_metadata_inventory_take = check_inventory_take,
|
|
allow_metadata_inventory_move = check_inventory_move,
|
|
on_metadata_inventory_put = update_formspec_put,
|
|
on_metadata_inventory_take = update_formspec_take,
|
|
on_receive_fields = form_handler,
|
|
})
|
|
|
|
|
|
minetest.register_craft({
|
|
output = 'facade:shaper',
|
|
recipe = {
|
|
{'', 'default:diamond', '' },
|
|
{'default:steel_ingot', 'default:steelblock', 'default:steel_ingot' },
|
|
{'', 'default:steelblock' , '' },
|
|
|
|
},
|
|
})
|