copybooks/src/copybooks.lua

209 lines
6.1 KiB
Lua

local S = minetest.get_translator("copybooks")
local F = minetest.formspec_escape
local status_idle = S("Book Copier Idle")
local status_active = S("Book Copier Active")
local status_full = S("Book Copier Full")
local status_nopaper = S("Book Copier No Paper")
local copybooks_formspec = function(status)
return "" ..
"size[8,9]"..
"label[0,0;"..S("Inputs").."]"..
"list[context;input;0,0.5;3,3;]" ..
"listring[current_player;main]"..
"label[2.9,0;"..S("Master").."]"..
"list[context;master;3,0.5;1,1;]"..
"label[0.25,4;" .. status .. "]" ..
"button_exit[3,1.5;1,1;quit;" .. S("Quit") .. "]"..
"label[6.7,0;"..S("Copies").."]"..
"list[context;output;4,0.5;4,4;]"..
"list[current_player;main;0,5;8,4;]" ..
"listring[context;input]"
end
local on_construct = function( pos )
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
inv:set_size("input", 9)
inv:set_size("output", 16)
inv:set_size("master", 1)
meta:set_string('formspec', copybooks_formspec(status_idle))
meta:set_string('infotext', status_idle)
end
local mfu_allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local iname = stack:get_name()
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "input" then
if iname == "default:book" or iname == "default:paper" then
return inv:room_for_item("input", stack) and stack:get_count() or 0
else
return 0
end
elseif listname == "output" then
return 0
elseif listname == "master" then
if iname == "default:book_written" and inv:room_for_item("master", stack) then
return 1
else
return 0
end
end
return 0
end
local mfu_allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
if to_list == "input" then
return -1
else
return 0
end
end
local mfu_can_dig = function(pos, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return false
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return (inv:is_empty("input") and inv:is_empty("output") and inv:is_empty("master"))
end
local mfu_tube = minetest.get_modpath("pipeworks") and {
-- using a different stack from defaut when inserting
insert_object = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:add_item("input", stack)
end,
can_insert = function(pos, node, stack, direction)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if stack:get_name() == "default:paper" or stack:get_name() == "default:book" then
return inv:room_for_item("input", stack)
else
return false
end
end,
-- the default stack, from which objects will be taken
input_inventory = "output",
connect_sides = {left = 1, right = 1, back = 1, bottom = 1,}
} or nil
minetest.register_node("copybooks:copybooks_active", {
description = S("Book Copier"),
tiles = { {name="mfu_top_active.png",
animation={type="vertical_frames",
aspect_w=32,
aspect_h=32,
length=3}},
"mfu_bottom.png",
"mfu_side.png",
"mfu_side.png",
"mfu_back.png",
"mfu_front_active.png",
},
groups = {cracky = 1, not_in_creative_inventory = 1, tubedevice = 1, tubedevice_receiver = 1, copybooks = 1},
light_source = 3,
allow_metadata_inventory_put = mfu_allow_metadata_inventory_put,
allow_metadata_inventory_move = mfu_allow_metadata_inventory_move,
paramtype = "light",
paramtype2 = "facedir",
drop = "copybooks:copybooks",
can_dig = mfu_can_dig,
tube = mfu_tube,
})
minetest.register_node("copybooks:copybooks", {
description = S("Book Copier"),
tiles = { "mfu_top.png",
"mfu_bottom.png",
"mfu_side.png",
"mfu_side.png",
"mfu_back.png",
"mfu_front.png",
},
groups = {cracky = 1, tubedevice = 1, tubedevice_receiver = 1, copybooks = 1},
allow_metadata_inventory_put = mfu_allow_metadata_inventory_put,
allow_metadata_inventory_move = mfu_allow_metadata_inventory_move,
paramtype = "light",
paramtype2 = "facedir",
drop = "copybooks:copybooks",
can_dig = mfu_can_dig,
tube = mfu_tube,
on_construct = on_construct,
})
local function inactive_state(pos,meta,state)
minetest.swap_node(pos,{name="copybooks:copybooks"})
meta:set_string("infotext",state or status_idle)
meta:set_string("formspec",copybooks_formspec(state or status_idle))
end
local function active_state(pos,meta)
minetest.swap_node(pos,{name="copybooks:copybooks_active"})
meta:set_string("infotext",status_active)
meta:set_string("formspec",copybooks_formspec(status_active))
end
minetest.register_abm({
label = "copybooks:copy",
nodenames = {"group:copybooks"},
interval = 1.0,
chance = 1,
catch_up = true,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("master") then
inactive_state(pos,meta)
return
elseif inv:is_empty("input") then
inactive_state(pos,meta,status_nopaper)
return
end
local input = inv:get_list("input")
local output = inv:get_list("output")
local master = inv:get_list("master")
local master_copy = inv:get_stack("master", 1)
local master_contents = master_copy:get_meta():to_table()
master_contents.fields.owner = S("@1 (copy)",master_contents.fields.owner or "???")
local copy = ItemStack({name = "default:book_written", count = 1})
copy:get_meta():from_table(master_contents)
if inv:room_for_item("output", copy) then
if inv:contains_item("input", {name = "default:book", count = 1}) then
inv:remove_item("input", {name = "default:book", count = 1})
inv:add_item("output", copy)
elseif inv:contains_item("input", {name = "default:paper", count = 3}) then
inv:remove_item("input", {name = "default:paper", count = 3})
inv:add_item("output", copy)
else
inactive_state(pos,meta,status_nopaper)
return
end
active_state(pos,meta)
else
inactive_state(pos,meta,status_full)
end
end,
})