From c20514d305f41281fa04c0ec6da8e99fc5f6a7ca Mon Sep 17 00:00:00 2001
From: Zefram <[email protected]>
Date: Mon, 4 Aug 2014 13:56:15 +0100
Subject: [PATCH] Define digiline chest from scratch
The digiline chest was attempting to work by adding to the default:chest
definition, as modified by pipeworks, but this didn't really work. As no
dependency on pipeworks was declared, it was not predictable whether
digilines would see the version of default:chest that had been modified
by pipeworks or not. The addition of the channel field to the chest form
depended on the default:chest form having a particular layout, with the
specific gap onto which digilines would superimpose the channel field.
This layout assumption got broken by a recent change to the default mod,
which shifted inventory slots around and reduced the size of the gap, and
also more drastically by technic_chests's redefinition of default:chest,
which shifted all the inventory slots down to accommodate a title line.
This is all fixed by defining the digiline chest from scratch. This is
feasible because the behaviour that is shared with the default chest is
a fixed and small quantity, in fact taking up only about the same amount
of space as the code that was needed to defer to the default definition.
This change incidentally makes the digiline chest be registered even if
pipeworks is not also loaded. The chest still works without pipeworks:
it emits digiline signals describing manual inventory operations.
---
digilines_inventory/init.lua | 142 ++++++++++++++++++++----------------------
1 file changed, 68 insertions(+), 74 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",
- digiline = {
- receptor = {},
- effector = {
- action = function(pos,node,channel,msg) end
- }
+ 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)
- 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}]")
+ 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)
- 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.
+ digiline = {
+ receptor = {},
+ effector = {
+ action = function(pos,node,channel,msg) end
+ }
+ },
+ 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)
--
1.7.10.4