From 93135be10c51b41b692cafea6f22358587a34b4f Mon Sep 17 00:00:00 2001 From: Jeija Date: Wed, 19 Nov 2014 19:27:42 +0100 Subject: [PATCH] Define digiline chest from scratch by Zefram, posted in #16 --- digilines_inventory/init.lua | 148 +++++++++++++++++------------------ 1 file changed, 71 insertions(+), 77 deletions(-) diff --git a/digilines_inventory/init.lua b/digilines_inventory/init.lua index 4fe9397..e44359a 100644 --- a/digilines_inventory/init.lua +++ b/digilines_inventory/init.lua @@ -1,77 +1,92 @@ -if not minetest.get_modpath("pipeworks") then - print("[Digilines] Install pipeworks if you want to use the digilines chest") - return -end - -local defaultChest = minetest.registered_nodes['default:chest'] - -local sendMessage = function (pos, msg, channel) +local function sendMessage(pos, msg, channel) if channel == nil then channel = minetest.get_meta(pos):get_string("channel") end digiline:receptor_send(pos,digiline.rules.default,channel,msg) end -tableMerge = function(first_table,second_table) - if second_table == nil then return end - for k,v in pairs(second_table) do first_table[k] = v end -end - -tableMergeImmutable = function(first_table, second_table) - if first_table == nil then return second_table end - if second_table == nil then return first_table end - copy = digiline:tablecopy(first_table) - for k,v in pairs(second_table) do copy[k] = v end - return copy -end - -local mychest = digiline:tablecopy(defaultChest) - -function defer(what,...) - if what then - return what(...) - end -end - -function maybeString(stack) +local function maybeString(stack) if type(stack)=='string' then return stack elseif type(stack)=='table' then return dump(stack) else return stack:to_string() end end -mychest = tableMergeImmutable(defaultChest,{ +local function can_insert(pos, stack) + local can = minetest.get_meta(pos):get_inventory():room_for_item("main", stack) + if can then + sendMessage(pos,"put "..maybeString(stack)) + else + -- overflow and lost means that items are gonna be out as entities :/ + sendMessage(pos,"lost "..maybeString(stack)) + end + return can +end + +local tubeconn = minetest.get_modpath("pipeworks") and "^pipeworks_tube_connection_wooden.png" or "" +local tubescan = minetest.get_modpath("pipeworks") and function(pos) pipeworks.scan_for_tube_objects(pos) end or nil + +minetest.register_node("digilines_inventory:chest", { description = "Digiline Chest", + tiles = { + "default_chest_top.png"..tubeconn, + "default_chest_top.png"..tubeconn, + "default_chest_side.png"..tubeconn, + "default_chest_side.png"..tubeconn, + "default_chest_side.png"..tubeconn, + "default_chest_front.png", + }, + paramtype2 = "facedir", + legacy_facedir_simple = true, + groups = {choppy=2, oddly_breakable_by_hand=2, tubedevice=1, tubedevice_receiver=1}, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Digiline Chest") + meta:set_string("formspec", "size[8,10]".. + ((default and default.gui_bg) or "").. + ((default and default.gui_bg_img) or "").. + ((default and default.gui_slots) or "").. + "label[0,0;Digiline Chest]".. + "list[current_name;main;0,1;8,4;]".. + "field[2,5.5;5,1;channel;Channel;${channel}]".. + ((default and default.get_hotbar_bg) and default.get_hotbar_bg(0,6) or "").. + "list[current_player;main;0,6;8,4;]") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + after_place_node = tubescan, + after_dig_node = tubescan, + can_dig = function(pos, player) + return minetest.get_meta(pos):get_inventory():is_empty("main") + end, + on_receive_fields = function(pos, formname, fields, sender) + if fields.channel ~= nil then + minetest.get_meta(pos):set_string("channel",fields.channel) + end + end, digiline = { receptor = {}, effector = { action = function(pos,node,channel,msg) end } }, - on_construct = function(pos) - defaultChest.on_construct(pos) - local meta = minetest.get_meta(pos) - -- we'll sneak into row 4 thanks - meta:set_string("formspec",meta:get_string("formspec").."\nfield[2,4.5;5,1;channel;Channel;${channel}]") - end, - on_receive_fields = function(pos, formname, fields, sender) - if fields.channel ~= nil then - minetest.get_meta(pos):set_string("channel",fields.channel) - return defer(defaultChest.on_receive_fields, pos, formname, fields, sender) - end - end, - tube = tableMergeImmutable(defaultChest.tube, { - -- note: mese filters cannot put part of a stack in the destination. - -- space for 50 coal with 99 added will pop out 99, not 49. + tube = { + connect_sides = {left=1, right=1, back=1, front=1, bottom=1, top=1}, connects = function(i,param2) return not pipeworks.connects.facingFront(i,param2) end, + input_inventory = "main", + can_insert = function(pos, node, stack, direction) + return can_insert(pos, stack) + end, insert_object = function(pos, node, stack, direction) - local leftover = defaultChest.tube.insert_object(pos,node,stack,direction) + local inv = minetest.get_meta(pos):get_inventory() + local leftover = inv:add_item("main", stack) local count = leftover:get_count() if count == 0 then local derpstack = stack:get_name()..' 1' - if not defaultChest.tube.can_insert(pos, node, derpstack, direction) then + if not inv:room_for_item("main", derpstack) then -- when you can't put a single more of whatever you just put, -- you'll get a put for it, then a full sendMessage(pos,"full "..maybeString(stack)..' '..tostring(count)) @@ -86,25 +101,16 @@ mychest = tableMergeImmutable(defaultChest,{ end return leftover end, - can_insert = function(pos, node, stack, direction) - local can = defaultChest.tube.can_insert(pos, node, stack, direction) - if can then - sendMessage(pos,"put "..maybeString(stack)) - else - -- overflow and lost means that items are gonna be out as entities :/ - sendMessage(pos,"lost "..maybeString(stack)) - end - return can - end, - }), + }, allow_metadata_inventory_put = function(pos, listname, index, stack, player) - if not mychest.tube.can_insert(pos,nil,stack,nil) then + if not can_insert(pos, stack) then sendMessage(pos,"uoverflow "..maybeString(stack)) end - local ret = defer(defaultChest.allow_metadata_inventory_put, pos, listname, index, stack, player) - if ret then return ret end return stack:get_count() end, + on_metadata_inventory_move = function(pos, fromlistname, fromindex, tolistname, toindex, count, player) + minetest.log("action", player:get_player_name().." moves stuff in chest at "..minetest.pos_to_string(pos)) + end, on_metadata_inventory_put = function(pos, listname, index, stack, player) local channel = minetest.get_meta(pos):get_string("channel") local send = function(msg) @@ -113,27 +119,15 @@ mychest = tableMergeImmutable(defaultChest,{ -- direction is only for furnaces -- as the item has already been put, can_insert should return false if the chest is now full. local derpstack = stack:get_name()..' 1' - if mychest.tube.can_insert(pos,nil,derpstack,nil) then + if can_insert(pos,derpstack) then send("uput "..maybeString(stack)) else send("ufull "..maybeString(stack)) end - return defer(defaultChest.on_metadata_inventory_put, pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().." puts stuff into chest at "..minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) sendMessage(pos,"utake "..maybeString(stack)) - return defaultChest.on_metadata_inventory_take(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().." takes stuff from chest at "..minetest.pos_to_string(pos)) end }) - -if mychest.tube.can_insert == nil then - -- we can use the can_insert function from pipeworks, but will duplicate if not found. - mychest.tube.can_insert = function(pos,node,stack,direction) - local meta=minetest.get_meta(pos) - local inv=meta:get_inventory() - return inv:room_for_item("main",stack) - end -end - --- minetest.register_node(":default:chest", mychest) -minetest.register_node("digilines_inventory:chest", mychest)