forked from mtcontrib/chesttools
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
This commit is contained in:
parent
4125be6ba4
commit
89beb85a6d
209
init.lua
209
init.lua
@ -1,7 +1,23 @@
|
|||||||
|
-- 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)'},
|
||||||
|
{'locks:shared_locked_chest', 'default:steel_ingot', 3, 'locks', 4, 'steel ingot(s)'},
|
||||||
|
};
|
||||||
|
|
||||||
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",
|
||||||
@ -9,6 +25,7 @@ chesttools.chest_add.tiles = {
|
|||||||
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
|
if( minetest.get_modpath( 'pipeworks' )) then
|
||||||
@ -46,7 +63,8 @@ chesttools.formspec = "size[9,10]"..
|
|||||||
"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..
|
||||||
@ -90,8 +108,7 @@ chesttools.on_receive_fields = function(pos, formname, fields, player)
|
|||||||
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.."]"..
|
"field[1.8,10.0;6,0.5;chestname;;"..chestname.."]");
|
||||||
"list[current_player;main;0.5,5.5;8,4;]");
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local formspec = "size[9,10]"..
|
local formspec = "size[9,10]"..
|
||||||
@ -114,12 +131,14 @@ chesttools.on_receive_fields = function(pos, formname, fields, player)
|
|||||||
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
|
||||||
@ -259,94 +278,103 @@ chesttools.update_chest = function(pos, formname, fields, player)
|
|||||||
end
|
end
|
||||||
local node = minetest.get_node( pos );
|
local node = minetest.get_node( pos );
|
||||||
|
|
||||||
local price = 1;
|
local old_nr = -1;
|
||||||
if( node.name=='default:chest' ) then
|
local new_nr = -1;
|
||||||
if( fields.normal) then
|
for nr, update_data in ipairs( chesttools.update_price ) do
|
||||||
return;
|
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
|
||||||
if( fields.locked ) then
|
end
|
||||||
price = 1;
|
-- no change necessary
|
||||||
elseif( fields.shared ) then
|
if( old_nr == -1 or new_nr == -1 or old_nr == new_nr ) 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 new_node_name= chesttools.update_price[ new_nr ][1];
|
||||||
local player_inv = player:get_inventory();
|
local price_item = chesttools.update_price[ new_nr ][2];
|
||||||
if( price>0 and not( player_inv:contains_item( 'main', 'default:steel_ingot '..tostring( price )))) then
|
local price_amount = chesttools.update_price[ new_nr ][3];
|
||||||
minetest.chat_send_player( pname, 'Sorry. You do not have '..tostring( price )..' steel ingots for the update.');
|
local price_name = chesttools.update_price[ new_nr ][6];
|
||||||
return;
|
-- 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
|
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
|
||||||
|
|
||||||
|
if( price_amount > 0 ) then
|
||||||
|
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
|
end
|
||||||
|
|
||||||
-- set the owner field
|
-- set the owner field
|
||||||
meta:set_string( 'owner', pname );
|
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 "..meta:get_string("owner")..")")
|
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 "..meta:get_string("owner")..")")
|
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
|
-- copy the old inventory
|
||||||
meta:set_string("formspec", "size[9,10]"..
|
local inv = meta:get_inventory();
|
||||||
"list[current_name;main;0.5,0.3;8,4;]"..
|
local main_inv = {};
|
||||||
"list[current_player;main;0.5,5.5;8,4;]");
|
local inv_size = inv:get_size("main");
|
||||||
else
|
for i=1, inv_size do
|
||||||
meta:set_string("formspec", chesttools.formspec..
|
main_inv[ i ] = inv:get_stack( "main", i);
|
||||||
"field[1.8,10.0;6,0.5;chestname;;"..tostring( meta:get_string("chestname") or "unconfigured").."]"..
|
print("Found: "..tostring( main_inv[ i ]:get_name()));
|
||||||
"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 )..
|
-- actually change and initialize the new chest
|
||||||
' for '..tostring( price )..' steel ingots.');
|
minetest.set_node( pos, { name = new_node_name, param2 = node.param2 });
|
||||||
|
-- make sure the player owns the new chest
|
||||||
|
meta:set_string("owner", pname);
|
||||||
|
|
||||||
|
-- put the inventory back
|
||||||
|
local new_inv = meta:get_inventory();
|
||||||
|
local new_inv_size = inv:get_size("main");
|
||||||
|
for i=1, math.min( inv_size, new_inv_size ) do
|
||||||
|
new_inv:set_stack( "main", i, main_inv[ i ]);
|
||||||
|
end
|
||||||
|
|
||||||
|
if( new_inv_size < inv_size ) then
|
||||||
|
-- TODO: problem here...where to put all that surplus inventory?
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
@ -450,6 +478,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;
|
||||||
@ -463,35 +492,35 @@ minetest.register_node( 'chesttools:shared_chest', {
|
|||||||
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,3.5;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 = 1;
|
||||||
"field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]"..
|
for nr, update_data in ipairs( chesttools.update_price ) do
|
||||||
"button_exit[2,3.5;1.5,0.5;abort;Abort]";
|
local link = tostring(update_data[4]);
|
||||||
if( node.name ~= 'default:chest' ) then
|
local chest_node_name = update_data[1];
|
||||||
formspec = formspec..'item_image_button[1,1;1.5,1.5;default:chest;normal;]'..
|
-- only offer possible updates
|
||||||
'button_exit[1,2.5;1.5,0.5;normal;normal]';
|
if( minetest.registered_nodes[ chest_node_name ]) then
|
||||||
else
|
if( node.name ~= chest_node_name ) then
|
||||||
formspec = formspec..'item_image[1,1;1.5,1.5;default:chest]'..
|
formspec = formspec..'item_image_button['..tostring(offset)..',1;1.5,1.5;'..
|
||||||
'label[1,2.5;normal]';
|
chest_node_name..';'..link..';]'..
|
||||||
end
|
'button_exit['..tostring(offset)..',2.5;1.5,0.5;'..
|
||||||
if( node.name ~= 'default:chest_locked' ) then
|
link..';'..link..']';
|
||||||
formspec = formspec..'item_image_button[3,1;1.5,1.5;default:chest_locked;locked;]'..
|
else
|
||||||
'button_exit[3,2.5;1.5,0.5;locked;locked]';
|
can_be_upgraded = true;
|
||||||
else
|
formspec = formspec..'item_image['..tostring(offset)..',1;1.5,1.5;'..
|
||||||
formspec = formspec..'item_image[3,1;1.5,1.5;default:chest_locked]'..
|
chest_node_name..']'..
|
||||||
'label[3,2.5;locked]';
|
'label['..tostring(offset)..',2.5;'..link..']';
|
||||||
end
|
end
|
||||||
if( node.name ~= 'chesttools:shared_chest' ) then
|
offset = offset + 2;
|
||||||
formspec = formspec..'item_image_button[5,1;1.5,1.5;chesttools:shared_chest;shared;]'..
|
|
||||||
'button_exit[5,2.5;1.5,0.5;shared;shared]';
|
|
||||||
else
|
|
||||||
formspec = formspec..'item_image[5,1;1.5,1.5;chesttools:shared_chest]'..
|
|
||||||
'label[5,2.5;shared]';
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
-- make the formspec wide enough to show all chests centered
|
||||||
|
formspec = 'size['..tostring(offset)..',4]'..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;
|
||||||
|
Loading…
Reference in New Issue
Block a user