Compare commits

24 Commits

Author SHA1 Message Date
435b8cdda5 Merge pull request #5 from fluxionary/pipeworks_connect
trigger pipeworks visual connection when placing a shared chest next to a pipe
2023-01-22 22:37:29 +01:00
543144c693 Merge pull request #4 from fluxionary/infotext_tweak
set infotext after swapping node
2023-01-22 22:36:10 +01:00
7d32cb06c7 merged flux' PRs 2023-01-22 22:35:01 +01:00
054b9e62a2 Merge pull request #3 from fluxionary/shared_removal
Shared removal
2023-01-22 22:32:51 +01:00
470774008a trigger pipeworks visual connection when placing a shared chest next to a pipe 2022-12-31 09:27:35 -08:00
9289a1ae9d set infotext after swapping node 2022-12-21 10:06:11 -08:00
eefeb09d8a fixed crash 2022-08-25 03:37:01 +02:00
80d4ce0d84 added right textures when pipeworks is installed 2022-08-24 23:49:50 +02:00
81b601b374 added colorwallmounted variant of chest 2022-08-24 22:11:55 +02:00
d335f5cf03 prepared for colored chests (8 colors) 2022-08-21 21:07:38 +02:00
c851ab7e16 fix crash (fixes #2) 2022-04-01 13:39:49 -07:00
6d2bfe336a allow players who can access the chest to dig it 2022-04-01 13:31:24 -07:00
a532518d61 added mod.conf 2022-01-06 00:13:05 +01:00
d1093fe448 fixed listring for first right-click 2021-04-11 22:19:02 +02:00
31366d3fc9 added listrings 2021-04-05 23:35:45 +02:00
06f4befded renamed obsolete functions to new name 2019-03-11 23:51:45 +01:00
e7a1f8fd86 removed pipeworks overlay from front side 2018-07-30 17:14:38 +02:00
7a4d7c4a67 works with newest unified_inventory 2018-07-28 04:11:25 +02:00
fa0ff79ddb handled switichng of chest with larger inv to smaller inv 2018-07-28 03:16:02 +02:00
73c69f2eed support for technic chests 2018-07-28 02:57:22 +02:00
89beb85a6d added support for shared locked chest; uses set_node instead of swap_node for cleaner operation; preparation for more versatile support of other chest types 2018-07-27 19:08:41 +02:00
4125be6ba4 added description.txt 2018-07-15 14:06:37 +02:00
5cb641e2e5 fixed bug in upgrade process 2018-07-15 14:06:07 +02:00
c0b9abb034 works with newer versions of mt again 2018-07-15 13:44:58 +02:00
10 changed files with 313 additions and 136 deletions

29
description.txt Normal file
View File

@ -0,0 +1,29 @@
This mod adds a shared locked chest with additional features to Minetest.
Who can access the chest?
- If placed in an area that is not protected: The owner of the chest.
- If the place is protected: Anyone who is allowed to build or dig at the place where the chest is standing.
Quick access buttons:
- Main: Acces your main inventory. This is all normal chests and locked chests can do.
- Craft: Access your crafting area directly. Take items out of your chest, put them directly into your crafting grid, craft something, and put the result back into the chest if you like. This can save a lot of clicks!
- Bag1: Directly access the inventory of your first bag. No need to put what you collected in your bags into your main inventory first and from there to the chests. It's much faster to do it directly!
- Bag2: Same for your second bag.
- Bag3: And the third.
- Bag4: Four bags are supported.
- DA: Drop All of your currently selected inventory (main, craft, or one of the bags) directly into the chest with one click.
- TA: Take All of the chest's inventory and put it into your currently selected inventory (main, craft or one of the bags).
- SA: Swap All - take all inventory out of the chest and put it into your currently selected inventory - and put all from your currently selected inventory into the bag. Just one click.
- FA: Filter All - Filter your currently selected inventory and put those items of which there's already at least one in the chest from your inventory into the chest. Good for i.e. quickly putting all ores, wood or farming products into one chest. Just put a sample inside the chest and no longer worry about having to put anything you gathered in the right chest - it'll automaticly get added if it belongs to that particular chest.
Supports:
- unified_inventory with its bags
Additional features:
- Add a label for the chest in the "Title/Content:" field. You'll now see that title when you hover over the chest with your mouse.
- Wield the blue chest and click on a normal, locked or other blue shared chest. You can now change the type of the chest - i.e. turn your locked chests into shared ones. Upgrades cost one steel ingot each.

409
init.lua
View File

@ -1,33 +1,68 @@
-- 30.07.18 Removed pipeworks overlay on front side of chest.
-- 28.07.18 Works with newer unified_inventory as well.
-- 28.07.18 Added support for technic chests.
-- 27.07.18 Added support for shared locked chests and moved to set_node
-- with inventory copying for cleaner operation.
-- 05.10.14 Fixed bug in protection/access -- 05.10.14 Fixed bug in protection/access
chesttools = {} chesttools = {}
-- data structure: new_node_name = { item_that_acts_as_price,
-- amount_of_price_item,
-- name_for_field_in_menu,
-- index_for_display_in_menu,
-- name of price item for showing the player,
-- new formspec string}
-- prices always refer to upgrading a default:chest to the desired new model
chesttools.update_price = {
{'default:chest', 'default:steel_ingot', 0, 'normal', 1, 'nothing'},
{'default:chest_locked', 'default:steel_ingot', 1, 'locked', 2, 'steel ingot'},
{'chesttools:shared_chest', 'default:steel_ingot', 2, 'shared', 3, 'steel ingot(s)'},
{'chesttools:shared_chest_wall', 'default:steel_ingot', 2, 'shared', 3, 'steel ingot(s)'},
{'locks:shared_locked_chest', 'default:steel_ingot', 3, 'locks', 4, 'steel ingot(s)'},
{'technic:iron_chest', 'technic:iron_chest', 1, 'iron', 5, 'Iron chest'},
{'technic:iron_locked_chest', 'technic:iron_locked_chest', 1, 'iron_locked', 6, 'Iron locked chest'},
{'technic:copper_chest', 'technic:copper_chest', 1, 'copper', 7, 'Copper chest'},
{'technic:copper_locked_chest', 'technic:copper_locked_chest', 1, 'copper_locked', 8, 'Copper locked chest'},
{'technic:silver_chest', 'technic:silver_chest', 1, 'silver', 9, 'Silver chest'},
{'technic:silver_locked_chest', 'technic:silver_locked_chest', 1, 'silver_locked',10, 'Silver locked chest'},
{'technic:gold_chest', 'technic:gold_chest', 1, 'gold', 11, 'Gold chest'},
{'technic:gold_locked_chest', 'technic:gold_locked_chest', 1, 'gold_locked', 12, 'Gold locked chest'},
{'technic:mithril_chest', 'technic:mithril_chest', 1, 'mithril', 13, 'Mithril chest'},
{'technic:mithril_locked_chest','technic:mithril_locked_chest',1, 'mithril_locked',14, 'Mithril locked chest'},
};
chesttools.chest_add = {}; chesttools.chest_add = {};
chesttools.chest_add.tiles = { chesttools.chest_add.tiles = {
"chesttools_blue_chest_top.png", "chesttools_blue_chest_top.png", "chesttools_blue_chest_side.png", -- "chesttools_blue_chest_top.png", "chesttools_blue_chest_top.png", "chesttools_blue_chest_side.png",
"chesttools_blue_chest_side.png", "chesttools_blue_chest_side.png", "chesttools_blue_chest_lock.png"}; -- "chesttools_blue_chest_side.png", "chesttools_blue_chest_side.png", "chesttools_blue_chest_lock.png"};
"chesttools_white_chest_top.png", "chesttools_white_chest_top.png", "chesttools_white_chest_side.png",
"chesttools_white_chest_side.png", "chesttools_white_chest_side.png", "chesttools_white_chest_lock.png"};
chesttools.chest_add.groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}; chesttools.chest_add.groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2};
chesttools.chest_add.tube = {}; chesttools.chest_add.tube = {};
-- additional/changed definitions for pipeworks; -- additional/changed definitions for pipeworks;
-- taken from pipeworks/compat.lua -- taken from pipeworks/compat.lua
if( minetest.get_modpath( 'pipeworks' )) then local has_pipeworks = minetest.get_modpath( 'pipeworks' )
if( has_pipeworks ) then
chesttools.chest_add.tiles = { chesttools.chest_add.tiles = {
"chesttools_blue_chest_top.png^pipeworks_tube_connection_wooden.png", chesttools.chest_add.tiles[1].."^pipeworks_tube_connection_wooden.png",
"chesttools_blue_chest_top.png^pipeworks_tube_connection_wooden.png", chesttools.chest_add.tiles[1].."^pipeworks_tube_connection_wooden.png",
"chesttools_blue_chest_side.png^pipeworks_tube_connection_wooden.png", chesttools.chest_add.tiles[3].."^pipeworks_tube_connection_wooden.png",
"chesttools_blue_chest_side.png^pipeworks_tube_connection_wooden.png", chesttools.chest_add.tiles[3].."^pipeworks_tube_connection_wooden.png",
"chesttools_blue_chest_side.png^pipeworks_tube_connection_wooden.png"}; chesttools.chest_add.tiles[3].."^pipeworks_tube_connection_wooden.png",
chesttools.chest_add.tiles[6]};
chesttools.chest_add.groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, chesttools.chest_add.groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,
tubedevice = 1, tubedevice_receiver = 1 }; tubedevice = 1, tubedevice_receiver = 1 };
chesttools.chest_add.tube = { chesttools.chest_add.tube = {
insert_object = function(pos, node, stack, direction) insert_object = function(pos, node, stack, direction)
local meta = minetest.env:get_meta(pos) local meta = minetest.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
return inv:add_item("main", stack) return inv:add_item("main", stack)
end, end,
can_insert = function(pos, node, stack, direction) can_insert = function(pos, node, stack, direction)
local meta = minetest.env:get_meta(pos) local meta = minetest.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
return inv:room_for_item("main", stack) return inv:room_for_item("main", stack)
end, end,
@ -38,15 +73,18 @@ end
chesttools.formspec = "size[9,10]".. chesttools.formspec = "size[9,10]"..
"list[current_name;main;0.5,0.3;8,4;]".. "list[current_name;main;0.5,0.3;8,4;]"..
"label[0.0,9.7;Title/Content:]".. "label[0.5,9.7;Name:]"..
"field[1.8,10.0;6,0.5;chestname;;]".. "field[1.8,10.0;6,0.5;chestname;;]"..
"button[7.5,9.7;1,0.5;set_chestname;Store]".. "button[7.5,9.7;1,0.5;set_chestname;Store\nName]"..
-- "button[8.6,9.7;0.5,0.5;change_color;C]"..
"image_button[8.4,9.7;0.5,0.5;chesttools_palette.png;change_color;]"..
"label[0.0,4.4;Main]".. "label[0.0,4.4;Main]"..
"button[1.0,4.5;1,0.5;craft;Craft]".. "button[1.0,4.5;1,0.5;craft;Craft]"..
"button[7.0,4.5;0.5,0.5;drop_all;DA]".. "button[7.0,4.5;0.5,0.5;drop_all;DA]"..
"button[7.5,4.5;0.5,0.5;take_all;TA]".. "button[7.5,4.5;0.5,0.5;take_all;TA]"..
"button[8.0,4.5;0.5,0.5;swap_all;SA]".. "button[8.0,4.5;0.5,0.5;swap_all;SA]"..
"button[8.5,4.5;0.5,0.5;filter_all;FA]"; "button[8.5,4.5;0.5,0.5;filter_all;FA]"..
"list[current_player;main;0.5,5.5;8,4;]";
if( minetest.get_modpath( 'unified_inventory')) then if( minetest.get_modpath( 'unified_inventory')) then
chesttools.formspec = chesttools.formspec.. chesttools.formspec = chesttools.formspec..
@ -58,11 +96,14 @@ end
chesttools.may_use = function( pos, player ) chesttools.may_use = function( pos, player )
if( not( player )) then if not (pos and player and player.is_player and player:is_player() and not player.is_fake_player) then
return false; return false;
end end
local name = player:get_player_name(); local name = player:get_player_name();
local meta = minetest.get_meta( pos ); local meta = minetest.get_meta( pos );
if(not(meta)) then
return false
end
local owner = meta:get_string( 'owner' ) local owner = meta:get_string( 'owner' )
-- the owner can access the chest -- the owner can access the chest
if( owner == name or owner == "" ) then if( owner == name or owner == "" ) then
@ -78,31 +119,50 @@ end
chesttools.on_receive_fields = function(pos, formname, fields, player) chesttools.on_receive_fields = function(pos, formname, fields, player)
if( fields.quit ) then if( fields.quit and fields.quit ~= "") then
return; return;
end end
if( fields.change_color ) then
local node = minetest.get_node( pos )
local add = 0
if(node and node.name and minetest.registered_nodes[node.name]) then
local def = minetest.registered_nodes[node.name]
if(def and def.paramtype2 == "colorfacedir") then
add = 32
elseif(def and def.paramtype2 == "colorwallmounted") then
add = 8
end
minetest.swap_node(pos, {name=node.name, param2=(node.param2 + add) % 256})
return
end
end
local meta = minetest.get_meta( pos ); local meta = minetest.get_meta( pos );
local chestname = meta:get_string( 'chestname' ); local chestname = meta:get_string( 'chestname' );
if( fields.set_chestname and fields.chestname ) then local spos = pos.x .. "," .. pos.y .. "," .. pos.z
if( fields.set_chestname and fields.chestname and fields.chestname ~= chestname) then
chestname = tostring( fields.chestname ); chestname = tostring( fields.chestname );
meta:set_string( 'chestname', chestname ); meta:set_string( 'chestname', chestname );
meta:set_string("infotext", "\""..chestname.."\" Chest (owned by "..meta:get_string("owner")..")") meta:set_string("infotext", "\""..chestname.."\" Chest (owned by "..meta:get_string("owner")..")")
-- update the normal formspec -- update the normal formspec
meta:set_string("formspec", chesttools.formspec.. meta:set_string("formspec", chesttools.formspec..
"field[1.8,10.0;6,0.5;chestname;;"..chestname.."]".. "listring[current_name;main]"..
"list[current_player;main;0.5,5.5;8,4;]"); "listring[current_player;main]"..
"field[1.8,10.0;6,0.5;chestname;;"..chestname.."]");
end end
local formspec = "size[9,10]".. local formspec = "size[9,10]"..
"label[0.0,9.7;Title/Content:]".. "label[0.5,9.7;Name:]"..
"field[1.8,10.0;6,0.5;chestname;;"..tostring( chestname or "unconfigured").."]".. "field[1.8,10.0;6,0.5;chestname;;"..tostring( chestname or "unconfigured").."]"..
"button[7.5,9.7;1,0.5;set_chestname;Store]".. "button[7.5,9.7;1,0.5;set_chestname;Store\nName]"..
-- "button[8.6,9.7;0.5,0.5;change_color;C]"..
"image_button[8.4,9.7;0.5,0.5;chesttools_palette.png;change_color;]"..
"list[current_name;main;0.5,0.3;8,4;]".. "list[current_name;main;0.5,0.3;8,4;]"..
"button[7.0,4.5;0.5,0.5;drop_all;DA]".. "button[7.0,4.5;0.5,0.5;drop_all;DA]"..
"button[7.5,4.5;0.5,0.5;take_all;TA]".. "button[7.5,4.5;0.5,0.5;take_all;TA]"..
"button[8.0,4.5;0.5,0.5;swap_all;SA]".. "button[8.0,4.5;0.5,0.5;swap_all;SA]"..
"button[8.5,4.5;0.5,0.5;filter_all;FA]"; "button[8.5,4.5;0.5,0.5;filter_all;FA]"
local bm = "button[0.0,4.5;1,0.5;main;Main]"; local bm = "button[0.0,4.5;1,0.5;main;Main]";
local bc = "button[1.0,4.5;1,0.5;craft;Craft]"; local bc = "button[1.0,4.5;1,0.5;craft;Craft]";
local b1 = "button[2.0,4.5;1,0.5;bag1;Bag 1]"; local b1 = "button[2.0,4.5;1,0.5;bag1;Bag 1]";
@ -110,16 +170,19 @@ chesttools.on_receive_fields = function(pos, formname, fields, player)
local b3 = "button[4.0,4.5;1,0.5;bag3;Bag 3]"; local b3 = "button[4.0,4.5;1,0.5;bag3;Bag 3]";
local b4 = "button[5.0,4.5;1,0.5;bag4;Bag 4]"; local b4 = "button[5.0,4.5;1,0.5;bag4;Bag 4]";
local selected = ''; local selected = '';
if( fields.drop_all or fields.take_all or fields.swap_all or fields.filter_all ) then if( fields.drop_all or fields.take_all or fields.swap_all or fields.filter_all ) then
-- check if the player has sufficient access to the chest -- check if the player has sufficient access to the chest
local node = minetest.get_node( pos ); local node = minetest.get_node( pos );
local pname = player:get_player_name();
-- deny access for unsupported chests -- deny access for unsupported chests
if( not( node ) if( not( node )
or (node.name == 'chesttools:shared_chest' and not( chesttools.may_use( pos, player ))) or (node.name == 'chesttools:shared_chest' and not( chesttools.may_use( pos, player )))
or (node.name == 'default:chest_locked'and player:get_player_name() ~= meta:get_string('owner' ))) then or (node.name == 'locks:shared_locked_chest'and pname ~= meta:get_string('owner' ))
or (node.name == 'default:chest_locked'and pname ~= meta:get_string('owner' ))) then
if( node.name ~= 'default:chest' ) then if( node.name ~= 'default:chest' ) then
minetest.chat_send_player( player:get_player_name(), 'Sorry, you do not have access to the content of this chest.'); minetest.chat_send_player( pname, 'Sorry, you do not have access to the content of this chest.');
return; return;
end end
end end
@ -186,7 +249,9 @@ chesttools.on_receive_fields = function(pos, formname, fields, player)
if( fields[ 'main'] or selected=='main' or fields['set_chestname']) then if( fields[ 'main'] or selected=='main' or fields['set_chestname']) then
bag_nr = 0; bag_nr = 0;
formspec = formspec.. formspec = formspec..
"list[current_player;main;0.5,5.5;8,4;]"; "list[current_player;main;0.5,5.5;8,4;]"..
"listring[nodemeta:" .. spos .. ";main]"..
"listring[current_player;main]"
bm = "label[0.0,4.4;Main]"; bm = "label[0.0,4.4;Main]";
selected = 'main'; selected = 'main';
@ -195,7 +260,9 @@ chesttools.on_receive_fields = function(pos, formname, fields, player)
formspec = formspec.. formspec = formspec..
"label[0,5.5;Crafting]".. "label[0,5.5;Crafting]"..
"list[current_player;craftpreview;6.5,6.5;1,1;]".. "list[current_player;craftpreview;6.5,6.5;1,1;]"..
"list[current_player;craft;2.5,6.5;3,3;]"; "list[current_player;craft;2.5,6.5;3,3;]"..
"listring[nodemeta:" .. spos .. ";main]"..
"listring[current_player;craft]"
bc = "label[1.0,4.4;Craft]"; bc = "label[1.0,4.4;Craft]";
selected = 'craft'; selected = 'craft';
@ -221,16 +288,20 @@ chesttools.on_receive_fields = function(pos, formname, fields, player)
formspec = formspec.. formspec = formspec..
"label[0.5,5.5;Bag "..bag_nr.."]"; "label[0.5,5.5;Bag "..bag_nr.."]";
local stack = player:get_inventory():get_stack( "bag"..bag_nr, 1) local stack = player:get_inventory():get_stack( "bag"..bag_nr, 1)
if( stack and not( stack:is_empty())) then if( stack ) then
local image = stack:get_definition().inventory_image local pname_esc = minetest.formspec_escape(player:get_player_name());
if( image ) then formspec = formspec.."list[detached:"..pname_esc.."_bags;bag"..
tostring(bag_nr)..";1.5,5.5;1,1;]";
local bag = minetest.get_inventory({type="detached", name=pname_esc.."_bags"},"bag"..tostring(bag_nr))
local slots = 4*8;
if( bag and not(bag:get_stack("bag"..tostring(bag_nr),1):is_empty())) then -- no bag present?
formspec = formspec.. formspec = formspec..
"image[7.5,5.5;1,1;"..image.."]"; "list[current_player;bag"..tostring(bag_nr).."contents;0.5,6.5;8,"..tostring(slots/8)..";]"..
end "listring[nodemeta:" .. spos .. ";main]"..
local slots = stack:get_definition().groups.bagslots "listring[current_player;bag"..tostring(bag_nr).."contents]"
if( slots and slots>0 ) then -- no bag present? else
formspec = formspec.. formspec = formspec..
"list[current_player;bag"..bag_nr.."contents;0.5,6.5;8,"..tostring(slots/8)..";]"; "label[0.5,6.5;You have no bag in this slot.]"
end end
end end
end end
@ -254,96 +325,119 @@ chesttools.update_chest = function(pos, formname, fields, player)
if( not( pos ) or not( pos.x ) or not( pos.y ) or not( pos.z )) then if( not( pos ) or not( pos.x ) or not( pos.y ) or not( pos.z )) then
return; return;
end end
local node = minetest.get_node( pos ); if( fields.abort and fields.abort ~= "") then
local price = 1;
if( node.name=='default:chest' ) then
if( fields.normal) then
return;
end
if( fields.locked ) then
price = 1;
elseif( fields.shared ) then
price = 2;
end
elseif( node.name=='default:chest_locked' ) then
if( fields.locked) then
return;
end
if( fields.normal ) then
price = -1;
elseif( fields.shared ) then
price = 1;
end
elseif( node.name=='chesttools:shared_chest') then
if( fields.shared) then
return;
end
if( fields.normal ) then
price = -2;
elseif( fields.locked ) then
price = -1;
end
else
return; return;
end end
local node = minetest.get_node( pos );
local player_inv = player:get_inventory(); local old_nr = -1;
if( price>0 and not( player_inv:contains_item( 'main', 'default:steel_ingot '..tostring( price )))) then local new_nr = -1;
minetest.chat_send_player( pname, 'Sorry. You do not have '..tostring( price )..' steel ingots for the update.'); for nr, update_data in ipairs( chesttools.update_price ) do
local link = tostring(update_data[4]);
local chest_node_name = update_data[1];
if( chest_node_name == node.name ) then
old_nr = nr;
elseif( fields[ link ] and fields[ link ] ~= "") then
new_nr = nr;
end
end
-- no change necessary
if( old_nr == -1 or new_nr == -1 or old_nr == new_nr ) then
return; return;
end end
local new_node_name= chesttools.update_price[ new_nr ][1];
local price_item = chesttools.update_price[ new_nr ][2];
local price_amount = chesttools.update_price[ new_nr ][3];
local price_name = chesttools.update_price[ new_nr ][6];
-- do they both use the same price?
if( chesttools.update_price[ old_nr ][2] == price_item ) then
-- the price for the old chest type gets substracted
price_amount = price_amount - chesttools.update_price[ old_nr ][3];
end
-- only work on chests owned by the player (or unlocked ones) -- only work on chests owned by the player (or unlocked ones)
local meta = minetest.get_meta( pos ); local meta = minetest.get_meta( pos );
if( node.name ~= 'default:chest' and meta:get_string( 'owner' ) ~= pname ) then local owner = meta:get_string( 'owner' );
if( node.name ~= 'default:chest' and owner and owner ~= pname and owner ~= "") then
minetest.chat_send_player( pname, 'You can only upgrade your own chests.'); minetest.chat_send_player( pname, 'You can only upgrade your own chests.');
return; return;
end end
-- check if steel ingot is present -- can the player build here (and thus change this chest)?
if( minetest.is_protected(pos, pname )) then if( minetest.is_protected(pos, pname )) then
minetest.chat_send_player( pname, 'This chest is protected from digging.'); minetest.chat_send_player( pname, 'This chest is protected from digging.');
return; return;
end end
if( price > 0 ) then local player_inv = player:get_inventory();
player_inv:remove_item( 'main', 'default:steel_ingot '..tostring( price )); if( price_amount>0 and not( player_inv:contains_item( 'main', price_item..' '..price_amount))) then
elseif( price < 0 ) then minetest.chat_send_player( pname, 'Sorry. You do not have '..tostring( price_amount )..
price = price * -1; ' '..price_name..' for the update.');
player_inv:add_item( 'main', 'default:steel_ingot '..tostring( price )); return;
end end
-- set the owner field if( price_amount > 0 ) then
meta:set_string( 'owner', pname ); player_inv:remove_item( 'main', price_item..' '..tostring(price_amount));
elseif( price_amount < 0 ) then
price_amount = price_amount * -1;
player_inv:add_item( 'main', price_item..' '..tostring(price_amount));
end
-- if the old chest type had a diffrent price: return that price
if( chesttools.update_price[ old_nr ][2] ~= price_item ) then
local old_price_item = chesttools.update_price[ old_nr ][2];
local old_price_amount = chesttools.update_price[ old_nr ][3];
player_inv:add_item( 'main', old_price_item..' '..tostring(old_price_amount));
end
-- copy the old inventory
local inv = meta:get_inventory();
local main_inv = {};
local inv_size = inv:get_size("main");
for i=1, inv_size do
main_inv[ i ] = inv:get_stack( "main", i);
-- print("Found: "..tostring( main_inv[ i ]:get_name()));
end
-- actually change and initialize the new chest
minetest.set_node( pos, { name = new_node_name, param2 = node.param2 });
-- make sure the player owns the new chest
meta:set_string("owner", pname);
target = node.name;
if( fields.locked ) then if( fields.locked ) then
target = 'default:chest_locked'; meta:set_string("infotext", "Locked Chest (owned by "..pname..")")
meta:set_string("infotext", "Locked Chest (owned by "..meta:get_string("owner")..")")
elseif( fields.shared ) then elseif( fields.shared ) then
target = 'chesttools:shared_chest'; meta:set_string("infotext", "Shared Chest (owned by "..pname..")")
meta:set_string("infotext", "Shared Chest (owned by "..meta:get_string("owner")..")")
else else
target = 'default:chest';
meta:set_string("infotext", "Chest") meta:set_string("infotext", "Chest")
end end
if( not( fields.shared )) then -- put the inventory back
meta:set_string("formspec", "size[9,10]".. local new_inv = meta:get_inventory();
"list[current_name;main;0.5,0.3;8,4;]".. local new_inv_size = inv:get_size("main");
"list[current_player;main;0.5,5.5;8,4;]"); for i=1, math.min( inv_size, new_inv_size ) do
else new_inv:set_stack( "main", i, main_inv[ i ]);
meta:set_string("formspec", chesttools.formspec..
"field[1.8,10.0;6,0.5;chestname;;"..tostring( meta:get_string("chestname") or "unconfigured").."]"..
"list[current_player;main;0.5,5.5;8,4;]");
end end
minetest.swap_node( pos, { name = target, param2 = node.param2 });
minetest.chat_send_player( pname, 'Chest changed to '..tostring( minetest.registered_nodes[ target].description ).. -- if the new chest has fewer slots than the old one had...
' for '..tostring( price )..' steel ingots.'); if( new_inv_size < inv_size ) then
-- try to put the inventory into the new chest anyway (there
-- might be free slots or stacks that can take a bit more)
for i=new_inv_size+1, inv_size do
-- try to find free space elsewhere in the chest
if( new_inv:room_for_item( "main", main_inv[ i ])) then
new_inv:add_item( "main", main_inv[ i ]);
-- ..or in the player's inventory
elseif( player_inv:room_for_item( "main", main_inv[ i ])) then
player_inv:add_item( "main", main_inv[ i ]);
-- drop the item above the chest
else
minetest.add_item({x=pos.x,y=pos.y+1,z=pos.z}, main_inv[i]);
end
end
end
minetest.chat_send_player( pname, 'Chest changed to '..tostring( minetest.registered_nodes[ new_node_name].description )..
' for '..tostring( price_amount )..' '..price_name..'.');
end end
@ -356,8 +450,10 @@ chesttools.form_input_handler = function( player, formname, fields)
end end
if( formname == "chesttools:shared_chest") then if( formname == "chesttools:shared_chest") then
chesttools.on_receive_fields(pos, formname, fields, player); chesttools.on_receive_fields(pos, formname, fields, player);
return true; -- this function was responsible for handling the input
elseif( formname == "chesttools:update") then elseif( formname == "chesttools:update") then
chesttools.update_chest( pos, formname, fields, player); chesttools.update_chest( pos, formname, fields, player);
return true; -- this function was responsible for handling the input
end end
return; return;
@ -369,13 +465,15 @@ end
minetest.register_on_player_receive_fields( chesttools.form_input_handler ); minetest.register_on_player_receive_fields( chesttools.form_input_handler );
minetest.register_node( 'chesttools:shared_chest', { chesttools.register_chest = function(node_name, desc, name, paramtype2, palette, tiles)
description = 'Shared chest which can be used by all who can build at that spot', minetest.register_node( node_name, {
name = 'shared chest', description = desc,
tiles = chesttools.chest_add.tiles, name = name,
tiles = tiles,
groups = chesttools.chest_add.groups, groups = chesttools.chest_add.groups,
tube = chesttools.chest_add.tube, tube = chesttools.chest_add.tube,
paramtype2 = "facedir", paramtype2 = paramtype2,
palette = palette,
legacy_facedir_simple = true, legacy_facedir_simple = true,
is_ground_content = false, is_ground_content = false,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
@ -384,6 +482,9 @@ minetest.register_node( 'chesttools:shared_chest', {
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "") meta:set_string("owner", placer:get_player_name() or "")
meta:set_string("infotext", "Shared Chest (owned by "..meta:get_string("owner")..")") meta:set_string("infotext", "Shared Chest (owned by "..meta:get_string("owner")..")")
if has_pipeworks then
pipeworks.after_place(pos)
end
end, end,
on_construct = function(pos) on_construct = function(pos)
@ -393,13 +494,15 @@ minetest.register_node( 'chesttools:shared_chest', {
local inv = meta:get_inventory() local inv = meta:get_inventory()
inv:set_size("main", 8*4) inv:set_size("main", 8*4)
meta:set_string("formspec", chesttools.formspec.. meta:set_string("formspec", chesttools.formspec..
"list[current_player;main;0.5,5.5;8,4;]"); "listring[current_name;main]"..
"listring[current_player;main]")
end, end,
can_dig = function(pos,player) can_dig = function(pos, player)
local meta = minetest.get_meta(pos); local player_name = (player and player.get_player_name and player:get_player_name()) or ""
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
return inv:is_empty("main") and player:get_player_name() == meta:get_string('owner'); return player_name and inv:is_empty("main") and not minetest.is_protected(pos, player_name)
end, end,
allow_metadata_inventory_move = function(pos, from_list, from_index, allow_metadata_inventory_move = function(pos, from_list, from_index,
@ -447,6 +550,7 @@ minetest.register_node( 'chesttools:shared_chest', {
chesttools.on_receive_fields( pos, formname, fields, sender); chesttools.on_receive_fields( pos, formname, fields, sender);
end, end,
-- show chest upgrade formspec
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if( user == nil or pointed_thing == nil or pointed_thing.type ~= 'node') then if( user == nil or pointed_thing == nil or pointed_thing.type ~= 'node') then
return nil; return nil;
@ -454,49 +558,88 @@ minetest.register_node( 'chesttools:shared_chest', {
local name = user:get_player_name(); local name = user:get_player_name();
local pos = minetest.get_pointed_thing_position( pointed_thing, mode ); local pos = minetest.get_pointed_thing_position( pointed_thing, mode );
local node = minetest.env:get_node_or_nil( pos ); local node = minetest.get_node_or_nil( pos );
if( node == nil or not( node.name )) then if( node == nil or not( node.name )) then
return nil; return nil;
end end
if( node.name=='default:chest' local formspec = "label[2,0.4;Change chest type:]"..
or node.name=='default:chest_locked' "field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]"..
or node.name=='chesttools:shared_chest') then "button_exit[2,6.0;1.5,0.5;abort;Abort]";
local formspec = "size[8,4]".. local can_be_upgraded = false;
"label[2,0.4;Change chest type:]".. local offset = 0.5;
"field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]".. local row_offset = 0;
"button_exit[2,3.5;1.5,0.5;abort;Abort]"; for nr, update_data in ipairs( chesttools.update_price ) do
if( node.name ~= 'default:chest' ) then local link = tostring(update_data[4]);
formspec = formspec..'item_image_button[1,1;1.5,1.5;default:chest;normal;]'.. local chest_node_name = update_data[1];
'button_exit[1,2.5;1.5,0.5;normal;normal]'; -- only offer possible updates
else if( minetest.registered_nodes[ chest_node_name ]) then
formspec = formspec..'item_image[1,1;1.5,1.5;default:chest]'.. if( node.name ~= chest_node_name ) then
'label[1,2.5;normal]'; formspec = formspec..'item_image_button['..tostring(offset)..','..
end tostring(1+row_offset)..';1.5,1.5;'..
if( node.name ~= 'default:chest_locked' ) then chest_node_name..';'..link..';]'..
formspec = formspec..'item_image_button[3,1;1.5,1.5;default:chest_locked;locked;]'.. 'button_exit['..tostring(offset)..','..
'button_exit[3,2.5;1.5,0.5;locked;locked]'; tostring(2.5+row_offset)..';1.5,0.5;'..
else link..';'..link..']';
formspec = formspec..'item_image[3,1;1.5,1.5;default:chest_locked]'.. else
'label[3,2.5;locked]'; can_be_upgraded = true;
end formspec = formspec..'item_image['..tostring(offset)..','..
if( node.name ~= 'chesttools:shared_chest' ) then tostring(1+row_offset)..';1.5,1.5;'..
formspec = formspec..'item_image_button[5,1;1.5,1.5;chesttools:shared_chest;shared;]'.. chest_node_name..']'..
'button_exit[5,2.5;1.5,0.5;shared;shared]'; 'label['..tostring(offset)..','..
else tostring(2.5+row_offset)..';'..link..']';
formspec = formspec..'item_image[5,1;1.5,1.5;chesttools:shared_chest]'.. end
'label[5,2.5;shared]'; offset = offset + 2;
if( offset >= 15.5 ) then
row_offset = 2.5;
offset = 0.5;
end
end end
end
offset = 16;
-- make the formspec wide enough to show all chests centered
formspec = 'size['..tostring(offset)..',6.5]'..formspec;
-- only show the formspec if it really is a chest that can be updated
if( can_be_upgraded ) then
minetest.show_formspec( name, "chesttools:update", formspec ); minetest.show_formspec( name, "chesttools:update", formspec );
end end
return nil; return nil;
end, end,
}) })
end
chesttools.register_chest("chesttools:shared_chest",
'Shared chest which can be used by all who can build at that spot',
'shared chest',
'colorfacedir',
'chesttools_palette.png',
chesttools.chest_add.tiles)
minetest.register_craft({ minetest.register_craft({
output = 'chesttools:shared_chest', output = 'chesttools:shared_chest',
type = 'shapeless', type = 'shapeless',
recipe = { 'default:steel_ingot', 'default:chest_locked' }, recipe = { 'default:steel_ingot', 'default:chest_locked' },
}) })
chesttools.register_chest("chesttools:shared_chest_wall",
'Shared chest which can be used by all who can build at that spot (wallmounted)',
'shared chest (wallmounted)',
'colorwallmounted',
'chesttools_palette_wallmounted.png',
{chesttools.chest_add.tiles[6],
chesttools.chest_add.tiles[3].."^[transformR180",
chesttools.chest_add.tiles[3].."^[transformR270",
chesttools.chest_add.tiles[3].."^[transformR90",
chesttools.chest_add.tiles[1].."^[transformR90",
chesttools.chest_add.tiles[1].."^[transformR90",
chesttools.chest_add.tiles[1],
})
minetest.register_craft({
output = 'chesttools:shared_chest_wall',
type = 'shapeless',
recipe = { 'default:steel_ingot', 'chesttools:shared_chest' },
})

5
mod.conf Normal file
View File

@ -0,0 +1,5 @@
name = chesttools
description = With these chests, you can access your bags and craft inventory with one click and move items between bag and chest. Other buttons speed up inventory movement even more: "DA": drop all from the selected inventory to the chest, "TA": take all from the chest and move it to your selected inventory, "SA": swap all items between chest and selected inventory and "FA": filter all - drop those items form your selected inventory to the chest of which there is already at least one in the chest. If the place where the chest stands is protected, everyone who can build there can access the chest (shared chest). You can also set a description text for the chests. Interaction with tubes is possible.
depends = default
author = Sokomine
title = Very useful chests which allow quick access to your bags.

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 742 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B