475 lines
14 KiB
Lua
475 lines
14 KiB
Lua
local workbench = {}
|
||
local workbench_label, workbench_back = "", ""
|
||
|
||
-- Nodes allowed to be cut
|
||
-- Only the regular, solid blocks without metas or explosivity can be cut
|
||
local nodes = {}
|
||
for node, def in pairs(minetest.registered_nodes) do
|
||
if (def.drawtype == "normal" or def.drawtype:sub(1,5) == "glass" or def.drawtype:sub(1,8) == "allfaces") and
|
||
(def.tiles and type(def.tiles[1]) == "string") and
|
||
not def.on_rightclick and
|
||
not def.on_blast and
|
||
not def.on_metadata_inventory_put and
|
||
not (def.groups.not_in_creative_inventory == 1) and
|
||
not (def.groups.not_cuttable) and
|
||
not def.groups.colorglass and
|
||
not def.mesecons
|
||
then
|
||
nodes[#nodes+1] = node
|
||
end
|
||
end
|
||
|
||
setmetatable(nodes, {
|
||
__concat = function(t1, t2)
|
||
for i=1, #t2 do
|
||
t1[#t1+1] = t2[i]
|
||
end
|
||
return t1
|
||
end
|
||
})
|
||
|
||
local valid_block = {}
|
||
for _, v in pairs(nodes) do
|
||
valid_block[v] = true
|
||
end
|
||
|
||
-- Nodeboxes definitions
|
||
workbench.defs = {
|
||
-- Name Yield X Y Z W H L
|
||
{"micropanel", 8, { 0, 0, 0, 16, 1, 8 }},
|
||
{"microslab", 4, { 0, 0, 0, 16, 1, 16 }},
|
||
{"thinstair", 4, { 0, 7, 0, 16, 1, 8 },
|
||
{ 0, 15, 8, 16, 1, 8 }},
|
||
{"cube", 4, { 0, 0, 0, 8, 8, 8 }},
|
||
{"panel", 4, { 0, 0, 0, 16, 8, 8 }},
|
||
{"slab", 2, { 0, 0, 0, 16, 8, 16 }},
|
||
{"doublepanel", 2, { 0, 0, 0, 16, 8, 8 },
|
||
{ 0, 8, 8, 16, 8, 8 }},
|
||
{"halfstair", 2, { 0, 0, 0, 8, 8, 16 },
|
||
{ 0, 8, 8, 8, 8, 8 }},
|
||
{"outerstair", 1, { 0, 0, 0, 16, 8, 16 },
|
||
{ 0, 8, 8, 8, 8, 8 }},
|
||
{"innerstair", 1, { 0, 0, 0, 16, 8, 16 },
|
||
{ 0, 8, 8, 16, 8, 8 },
|
||
{ 0, 8, 0, 8, 8, 8 }},
|
||
{"stair", 1, { 0, 0, 0, 16, 8, 16 },
|
||
{ 0, 8, 8, 16, 8, 8 }},
|
||
{"slope", 2, nil }
|
||
}
|
||
|
||
local repairable_tools = {"pick", "axe", "shovel", "sword", "hoe", "armor", "shield"}
|
||
|
||
-- Tools allowed to be repaired
|
||
function workbench:repairable(stack)
|
||
for _, t in pairs(repairable_tools) do
|
||
if stack:find(t) then
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
|
||
function workbench:get_output(inv, input, name)
|
||
local output = {}
|
||
for i = 1, #self.defs do
|
||
local nbox = self.defs[i]
|
||
local count = math.min(nbox[2] * input:get_count(), input:get_stack_max())
|
||
local item = "stairs:" .. nbox[1] .. "_" .. name:gsub(":", "_")
|
||
output[#output+1] = item .. " " .. count
|
||
end
|
||
inv:set_list("forms", output)
|
||
end
|
||
|
||
-- Thanks to kaeza for this function
|
||
function workbench:pixelbox(size, boxes)
|
||
local fixed = {}
|
||
for _, box in pairs(boxes) do
|
||
-- `unpack` has been changed to `table.unpack` in newest Lua versions
|
||
local x, y, z, w, h, l = unpack(box)
|
||
fixed[#fixed+1] = {
|
||
(x / size) - 0.5,
|
||
(y / size) - 0.5,
|
||
(z / size) - 0.5,
|
||
((x + w) / size) - 0.5,
|
||
((y + h) / size) - 0.5,
|
||
((z + l) / size) - 0.5
|
||
}
|
||
end
|
||
return {type = "fixed", fixed = fixed}
|
||
end
|
||
|
||
-- You can't place 'image' on top of 'item_image'
|
||
minetest.register_craftitem("workbench:saw", {
|
||
description = "Hammer",
|
||
inventory_image = "workbench_saw.png",
|
||
groups = {not_in_creative_inventory = 1}
|
||
})
|
||
|
||
if PLATFORM ~= "Android" and PLATFORM ~= "iOS" then
|
||
workbench_label = "label[0.9,0.1;" .. Sl("Workbench") .. "]"
|
||
workbench_back = "label[0.1,0.7;" .. Sl("< Back") .. "]"
|
||
end
|
||
|
||
-- Workbench formspec
|
||
local workbench_fs = [[
|
||
background[-0.2,-0.26;9.41,9.49;formspec_workbench_crafting.png]
|
||
|
||
item_image[0,-0.1;1,1;workbench:workbench]
|
||
]] .. workbench_label .. [[
|
||
|
||
image_button[0.2,0.8;1.5,1.5;blank.png;creating;;true;false;workbench_button_back.png]
|
||
item_image[0.25,0.85;1.5,1.5;stairs:stair_default_wood]
|
||
item_image[0.25,0.95;1.4,1.4;workbench:saw]
|
||
tooltip[creating;]] .. Sl("Сutting") .. [[;#000;#FFF]
|
||
|
||
image_button[0.2,2.15;1.5,1.5;blank.png;anvil;;true;false;workbench_button_back.png]
|
||
image[0.25,2.2;1.5,1.5;workbench_anvil.png]
|
||
tooltip[anvil;]] .. Sl("Anvil") .. [[;#000;#FFF]
|
||
|
||
list[current_player;craft;2,0.5;3,3;]
|
||
list[current_player;craftpreview;7,1.505;1,1;]
|
||
]]
|
||
|
||
-- Creating formspec
|
||
local creating_fs = [[
|
||
background[-0.2,-0.26;9.41,9.49;formspec_workbench_creating.png]
|
||
|
||
item_image[0,-0.1;1,1;workbench:workbench]
|
||
]] .. workbench_back .. [[
|
||
image_button[-0.1,-0.2;1.2,1.2;blank.png;back;;true;false;workbench_button_back.png]
|
||
|
||
item_image[0.1,1.15;1.75,1.75;workbench:saw]
|
||
list[context;craft;2,1.505;1,1;]
|
||
list[context;forms;4.01,0.51;4,3;]
|
||
]]
|
||
|
||
-- Repair formspec
|
||
local repair_fs = [[
|
||
background[-0.2,-0.26;9.41,9.49;formspec_workbench_anvil.png]
|
||
|
||
item_image[0,-0.1;1,1;workbench:workbench]
|
||
]] .. workbench_back .. [[
|
||
image_button[-0.1,-0.2;1.2,1.2;blank.png;back;;true;false;workbench_button_back.png]
|
||
|
||
image[0.1,1.15;1.75,1.75;workbench_anvil.png]
|
||
item_image[2,2.5;1,1;default:pick_stone]
|
||
list[context;tool;2,1.5;1,1;]
|
||
item_image[6,2.5;1,1;workbench:hammer]
|
||
list[context;hammer;6,1.5;1,1;]
|
||
]]
|
||
|
||
local formspecs = {
|
||
-- Workbench formspec
|
||
workbench_fs,
|
||
|
||
-- Crafting formspec
|
||
creating_fs,
|
||
|
||
-- Repair formspec
|
||
repair_fs
|
||
}
|
||
|
||
function workbench:set_formspec(meta, id)
|
||
meta:set_string("formspec",
|
||
default.gui ..
|
||
formspecs[id])
|
||
end
|
||
|
||
function workbench.construct(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
local inv = meta:get_inventory()
|
||
|
||
inv:set_size("tool", 1)
|
||
inv:set_size("craft", 1)
|
||
inv:set_size("hammer", 1)
|
||
inv:set_size("forms", 4*3)
|
||
inv:set_size("storage", 9*3)
|
||
|
||
meta:set_string("infotext", Sl("Workbench"))
|
||
meta:set_string("version", "2")
|
||
workbench:set_formspec(meta, 1)
|
||
end
|
||
|
||
function workbench.fields(pos, _, fields, sender)
|
||
local meta = minetest.get_meta(pos)
|
||
local id = fields.back and 1 or fields.creating and 2 or fields.anvil and 3
|
||
if not id then
|
||
if pos and sender then
|
||
local inv = sender:get_inventory()
|
||
if inv then
|
||
for i, stack in ipairs(inv:get_list("craft")) do
|
||
minetest.item_drop(stack, nil, pos)
|
||
stack:clear()
|
||
inv:set_stack("craft", i, stack)
|
||
end
|
||
end
|
||
inv = meta:get_inventory()
|
||
if inv then
|
||
for _, name in pairs({"craft", "tool", "hammer"}) do
|
||
local stack = inv:get_stack(name, 1)
|
||
minetest.item_drop(stack, nil, pos)
|
||
stack:clear()
|
||
inv:set_stack(name, 1, stack)
|
||
end
|
||
for i, stack in pairs(inv:get_list("forms")) do
|
||
stack:clear()
|
||
inv:set_stack("forms", i, stack)
|
||
end
|
||
end
|
||
end
|
||
return
|
||
end
|
||
|
||
workbench:set_formspec(meta, id)
|
||
end
|
||
|
||
function workbench.timer(pos)
|
||
local timer = minetest.get_node_timer(pos)
|
||
local inv = minetest.get_meta(pos):get_inventory()
|
||
local tool = inv:get_stack("tool", 1)
|
||
local hammer = inv:get_stack("hammer", 1)
|
||
|
||
if tool:is_empty() or hammer:is_empty() or tool:get_wear() == 0 then
|
||
timer:stop()
|
||
return
|
||
end
|
||
|
||
-- Tool's wearing range: 0-65535; 0 = new condition
|
||
tool:add_wear(-500)
|
||
hammer:add_wear(700)
|
||
|
||
inv:set_stack("tool", 1, tool)
|
||
inv:set_stack("hammer", 1, hammer)
|
||
return true
|
||
end
|
||
|
||
function workbench.put(_, listname, _, stack)
|
||
local stackname = stack:get_name()
|
||
if (listname == "tool" and stack:get_wear() > 0 and
|
||
workbench:repairable(stackname)) or
|
||
(listname == "craft" and valid_block[stackname]) or
|
||
(listname == "hammer" and stackname == "workbench:hammer") or
|
||
listname == "storage" then
|
||
return stack:get_count()
|
||
end
|
||
return 0
|
||
end
|
||
|
||
function workbench.move(_, from_list, _, to_list, _, count)
|
||
return (to_list == "storage" and from_list ~= "forms") and count or 0
|
||
end
|
||
|
||
function workbench.on_put(pos, listname, _, stack)
|
||
local inv = minetest.get_meta(pos):get_inventory()
|
||
if listname == "craft" then
|
||
local input = inv:get_stack("craft", 1)
|
||
workbench:get_output(inv, input, stack:get_name())
|
||
elseif listname == "tool" or listname == "hammer" then
|
||
local timer = minetest.get_node_timer(pos)
|
||
timer:start(0.5)
|
||
end
|
||
end
|
||
|
||
function workbench.on_take(pos, listname, index, stack, player)
|
||
local inv = minetest.get_meta(pos):get_inventory()
|
||
local input = inv:get_stack("craft", 1)
|
||
local inputname = input:get_name()
|
||
local stackname = stack:get_name()
|
||
if listname == "craft" then
|
||
if stackname == inputname and valid_block[stackname] then
|
||
workbench:get_output(inv, input, stackname)
|
||
else
|
||
inv:set_list("forms", {})
|
||
end
|
||
elseif listname == "forms" then
|
||
local fromstack = inv:get_stack(listname, index)
|
||
if not fromstack:is_empty() and fromstack:get_name() ~= stackname then
|
||
local player_inv = player:get_inventory()
|
||
if player_inv:room_for_item("main", fromstack) then
|
||
player_inv:add_item("main", fromstack)
|
||
end
|
||
end
|
||
|
||
input:take_item(math.ceil(stack:get_count() / workbench.defs[index][2]))
|
||
inv:set_stack("craft", 1, input)
|
||
workbench:get_output(inv, input, inputname)
|
||
end
|
||
end
|
||
|
||
minetest.register_node("workbench:workbench", {
|
||
description = "Workbench",
|
||
paramtype = "light",
|
||
paramtype2 = "facedir",
|
||
groups = {cracky = 2, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
|
||
sounds = default.node_sound_wood_defaults(),
|
||
tiles = {"workbench_top.png", "workbench_top.png",
|
||
"workbench_sides.png", "workbench_sides.png",
|
||
"workbench_front.png", "workbench_front.png"},
|
||
on_timer = workbench.timer,
|
||
on_construct = workbench.construct,
|
||
on_receive_fields = workbench.fields,
|
||
on_metadata_inventory_put = workbench.on_put,
|
||
on_metadata_inventory_take = workbench.on_take,
|
||
allow_metadata_inventory_put = workbench.put,
|
||
allow_metadata_inventory_move = workbench.move
|
||
})
|
||
|
||
minetest.register_lbm({
|
||
label = "Workbench updater",
|
||
name = "workbench:updater",
|
||
nodenames = "workbench:workbench",
|
||
action = function(pos)
|
||
if minetest.get_meta(pos):get_string("version") ~= "2" then
|
||
minetest.set_node(pos, {name = "workbench:workbench"})
|
||
end
|
||
end
|
||
})
|
||
|
||
for _, d in pairs(workbench.defs) do
|
||
for i = 1, #nodes do
|
||
local node = nodes[i]
|
||
local def = minetest.registered_nodes[node]
|
||
local groups, tiles, mesh, collision_box = {}, {}, {}, {}
|
||
local drawtype = "nodebox"
|
||
|
||
if not d[3] then
|
||
drawtype = "mesh"
|
||
mesh = "workbench_slope.obj"
|
||
collision_box = {
|
||
type = "fixed",
|
||
fixed = {
|
||
{-0.5, -0.5, -0.5, 0.5, -0.1875, 0.5},
|
||
{-0.5, -0.1875, -0.1875, 0.5, 0.1875, 0.5},
|
||
{-0.5, 0.1875, 0.1875, 0.5, 0.5, 0.5}
|
||
},
|
||
}
|
||
end
|
||
|
||
groups.stairs = 1
|
||
|
||
for k, v in pairs(def.groups) do
|
||
if k ~= "wood" and k ~= "stone" and k ~= "wool" and k ~= "level" then
|
||
groups[k] = v
|
||
end
|
||
end
|
||
|
||
if def.tiles then
|
||
if #def.tiles > 1 and (def.drawtype:sub(1,5) ~= "glass") then
|
||
tiles = def.tiles
|
||
else
|
||
tiles = {def.tiles[1]}
|
||
end
|
||
else
|
||
tiles = {def.tiles[1]}
|
||
end
|
||
|
||
if def.drop ~= "" then
|
||
drop = "stairs:"..d[1].."_"..node:gsub(":", "_")
|
||
else
|
||
drop = ""
|
||
end
|
||
|
||
minetest.register_node(":stairs:"..d[1].."_"..node:gsub(":", "_"), {
|
||
description = def.description.." " ..Sl(d[1]:gsub("^%l", string.upper)),
|
||
drawtype = drawtype,
|
||
tiles = tiles,
|
||
mesh = mesh,
|
||
paramtype = "light",
|
||
paramtype2 = "facedir",
|
||
drop = drop,
|
||
groups = groups,
|
||
light_source = def.light_source / 2,
|
||
sunlight_propagates = true,
|
||
walkable = def.walkable,
|
||
is_ground_content = false,
|
||
sounds = def.sounds,
|
||
use_texture_alpha = def.use_texture_alpha,
|
||
on_place = minetest.rotate_node,
|
||
node_box = workbench:pixelbox(16, {unpack(d, 3)}),
|
||
collision_box = collision_box
|
||
})
|
||
end
|
||
end
|
||
|
||
-- Aliases. A lot of aliases...
|
||
local stairs_aliases = {
|
||
{"corner", "outerstair"},
|
||
{"invcorner", "outerstair"},
|
||
{"stair_outer", "innerstair"},
|
||
{"stair_inner", "innerstair"},
|
||
{"nanoslab", "microslab"}
|
||
}
|
||
|
||
for i = 1, #nodes do
|
||
local node = nodes[i]
|
||
for _, d in pairs(workbench.defs) do
|
||
minetest.register_alias("stairs:"..d[1].."_"..node:match(":(.*)"), "stairs:"..d[1].."_"..node:gsub(":", "_"))
|
||
minetest.register_alias(node.."_"..d[1], "stairs:"..d[1].."_"..node:gsub(":", "_"))
|
||
end
|
||
|
||
for _, e in pairs(stairs_aliases) do
|
||
minetest.register_alias("stairs:"..e[1].."_"..node:match(":(.*)"), "stairs:"..e[2].."_"..node:gsub(":", "_"))
|
||
minetest.register_alias("stairs:"..e[1].."_"..node:gsub(":", "_"), "stairs:"..e[2].."_"..node:gsub(":", "_"))
|
||
minetest.register_alias(node.."_"..e[1], "stairs:"..e[2].."_"..node:gsub(":", "_"))
|
||
end
|
||
end
|
||
|
||
for _, d in pairs(workbench.defs) do
|
||
minetest.register_alias("stairs:"..d[1].."_coal", "stairs:"..d[1].."_default_coalblock")
|
||
minetest.register_alias("stairs:"..d[1].."_lapis_block", "stairs:"..d[1].."_default_lapisblock")
|
||
end
|
||
|
||
for _, e in pairs(stairs_aliases) do
|
||
minetest.register_alias("stairs:"..e[1].."_coal", "stairs:"..e[2].."_default_coalblock")
|
||
minetest.register_alias("stairs:"..e[1].."_lapis_block", "stairs:"..e[2].."_default_lapisblock")
|
||
end
|
||
|
||
minetest.register_alias("stairs:stair_steel", "stairs:stair_default_steelblock")
|
||
minetest.register_alias("stairs:slab_steel", "stairs:slab_default_steelblock")
|
||
minetest.register_alias("stairs:corner_steel", "stairs:corner_default_steelblock")
|
||
minetest.register_alias("stairs:stair_gold", "stairs:stair_default_goldblock")
|
||
minetest.register_alias("stairs:slab_gold", "stairs:slab_default_goldblock")
|
||
minetest.register_alias("stairs:corner_gold", "stairs:corner_default_goldblock")
|
||
minetest.register_alias("stairs:stair_diamond", "stairs:stair_default_diamondblock")
|
||
minetest.register_alias("stairs:slab_diamond", "stairs:slab_default_diamondblock")
|
||
minetest.register_alias("stairs:corner_diamond", "stairs:corner_default_diamondblock")
|
||
|
||
|
||
-- Workbench
|
||
minetest.register_alias("crafting:workbench", "workbench:workbench")
|
||
minetest.register_alias("default:workbench", "workbench:workbench")
|
||
|
||
-- Craft items
|
||
|
||
minetest.register_tool("workbench:hammer", {
|
||
description = "Hammer",
|
||
inventory_image = "workbench_hammer.png",
|
||
tool_capabilities = {
|
||
full_punch_interval = 1.5,
|
||
max_drop_level = 0,
|
||
damage_groups = {fleshy = 6}
|
||
},
|
||
sound = {breaks = "default_tool_breaks"}
|
||
})
|
||
|
||
minetest.register_craft({
|
||
output = "workbench:workbench",
|
||
recipe = {
|
||
{"group:wood", "group:wood"},
|
||
{"group:wood", "group:wood"}
|
||
}
|
||
})
|
||
|
||
minetest.register_craft({
|
||
output = "workbench:hammer",
|
||
recipe = {
|
||
{"default:steel_ingot", "group:stick", "default:steel_ingot"},
|
||
{"", "group:stick", ""}
|
||
}
|
||
})
|
||
|
||
minetest.register_craft({
|
||
type = "fuel",
|
||
recipe = "workbench:workbench",
|
||
burntime = 30
|
||
})
|