From 6994e82f4c69c6712f30dd4b2f35518ace239dde Mon Sep 17 00:00:00 2001 From: Sokomine Date: Fri, 5 Sep 2014 04:21:26 +0200 Subject: [PATCH] initial commit --- README.md | 1 + init.lua | 302 ++++++++++++++++++++++++ textures/chesttools_blue_chest_lock.png | Bin 0 -> 742 bytes textures/chesttools_blue_chest_side.png | Bin 0 -> 642 bytes textures/chesttools_blue_chest_top.png | Bin 0 -> 643 bytes 5 files changed, 303 insertions(+) create mode 100644 README.md create mode 100644 init.lua create mode 100644 textures/chesttools_blue_chest_lock.png create mode 100644 textures/chesttools_blue_chest_side.png create mode 100644 textures/chesttools_blue_chest_top.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..9db2f84 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +This is work in progress. diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..303de23 --- /dev/null +++ b/init.lua @@ -0,0 +1,302 @@ + +chesttools = {} + +chesttools.chest_add = {}; +chesttools.chest_add.tiles = { + "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.chest_add.groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}; +chesttools.chest_add.tube = {}; + +-- additional/changed definitions for pipeworks; +-- taken from pipeworks/compat.lua +if( minetest.get_modpath( 'pipeworks' )) then + chesttools.chest_add.tiles = { + "chesttools_blue_chest_top.png^pipeworks_tube_connection_wooden.png", + "chesttools_blue_chest_top.png^pipeworks_tube_connection_wooden.png", + "chesttools_blue_chest_side.png^pipeworks_tube_connection_wooden.png", + "chesttools_blue_chest_side.png^pipeworks_tube_connection_wooden.png", + "chesttools_blue_chest_side.png^pipeworks_tube_connection_wooden.png"}; + chesttools.chest_add.groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, + tubedevice = 1, tubedevice_receiver = 1 }; + chesttools.chest_add.tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left=1, right=1, back=1, front=1, bottom=1, top=1} + }; +end + +chesttools.formspec = "size[9,10]".. + "list[current_name;main;0.5,0.3;8,4;]".. + "label[0.0,4.4;Main]".. + "button[1.0,4.5;1,0.5;craft;Craft]".. + "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[8.0,4.5;0.5,0.5;swap_all;SA]".. + "button[8.5,4.5;0.5,0.5;filter_all;FA]"; + +if( minetest.get_modpath( 'unified_inventory')) then + chesttools.formspec = chesttools.formspec.. + "button[2.0,4.5;1,0.5;bag1;Bag 1]".. + "button[3.0,4.5;1,0.5;bag2;Bag 2]".. + "button[4.0,4.5;1,0.5;bag3;Bag 3]".. + "button[5.0,4.5;1,0.5;bag4;Bag 4]"; +end + + +chesttools.may_use = function( pos, player ) + local name = player:get_player_name(); + local meta = minetest.get_meta( pos ); + local owner = meta:get_string( 'owner' ) + -- the owner can access the chest + if( onwer == name or owner == "" ) then + return true; + end + -- the shared function only kicks in if the area is protected + if( not( minetest.is_protected(pos, player:get_player_name())) + and minetest.is_protected(pos, ' _DUMMY_PLAYER_ ')) then + return true; + end + return true; +end + + +chesttools.on_receive_fields = function(pos, formname, fields, player) + if( fields.quit ) then + return; + end + local formspec = "size[9,10]".. + "list[current_name;main;0.5,0.3;8,4;]".. + "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[8.0,4.5;0.5,0.5;swap_all;SA]".. + "button[8.5,4.5;0.5,0.5;filter_all;FA]"; + local bm = "button[0.0,4.5;1,0.5;main;Mail]"; + 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 b2 = "button[3.0,4.5;1,0.5;bag2;Bag 2]"; + 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 selected = ''; + 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 + local node = minetest.get_node( pos ); + local meta = minetest.get_meta( pos ); + -- deny access for unsupported chests + if( not( node ) + 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 + 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.'); + return; + end + end + selected = fields.selected; + if( not( selected ) or selected == '' ) then + selected = 'main'; + end + local inv_list = 'main'; + if( selected == 'main' ) then + inv_list = 'main'; + elseif( selected == 'craft' ) then + inv_list = 'craft'; + elseif( selected == 'bag1' or selected == 'bag2' or selected == 'bag3' or selected=='bag4') then + inv_list = selected.."contents"; + end + + local player_inv = player:get_inventory(); + local chest_inv = meta:get_inventory(); + if( fields.drop_all ) then + for i,v in ipairs( player_inv:get_list( inv_list )) do + if( chest_inv:room_for_item('main', v)) then + local leftover = chest_inv:add_item( 'main', v ); + player_inv:remove_item( inv_list, v ); + if( leftover and not( leftover:is_empty() )) then + player_inv:add_item( inv_list, v ); + end + end + end + elseif( fields.take_all ) then + for i,v in ipairs( chest_inv:get_list( 'main' )) do + if( player_inv:room_for_item( inv_list, v)) then + local leftover = player_inv:add_item( inv_list, v ); + chest_inv:remove_item( 'main', v ); + if( leftover and not( leftover:is_empty() )) then + chest_inv:add_item( 'main', v ); + end + end + end +-- TODO: swap_all, filter_all +-- TODO: buttons for those combined operations + end + end + + local meta = minetest.get_meta( pos ); + local bag_nr = 0; + if( fields[ 'main'] or selected=='main') then + bag_nr = 0; + formspec = formspec.. + "list[current_player;main;0.5,5.5;8,4;]"; + bm = "label[0.0,4.4;Main]"; + selected = 'main'; + + elseif( fields[ 'craft'] or selected=='craft') then + bag_nr = 0; + formspec = formspec.. + "label[0,5.5;Crafting]".. + "list[current_player;craftpreview;6.5,6.5;1,1;]".. + "list[current_player;craft;2.5,6.5;3,3;]"; + bc = "label[1.0,4.4;Craft]"; + selected = 'craft'; + + elseif( fields[ 'bag1' ] or selected=='bag1') then + bag_nr = 1; + b1 = "label[2.0,4.4;Bag 1]"; + selected = 'bag1'; + elseif( fields[ 'bag2' ] or selected=='bag2') then + bag_nr = 2; + b2 = "label[3.0,4.4;Bag 2]"; + selected = 'bag2'; + elseif( fields[ 'bag3' ] or selected=='bag3') then + bag_nr = 3; + b3 = "label[4.0,4.4;Bag 3]"; + selected = 'bag3'; + elseif( fields[ 'bag4' ] or selected=='bag4') then + bag_nr = 4; + b4 = "label[5.0,4.4;Bag 4]"; + selected = 'bag4'; + end + + if( bag_nr >= 1 and bag_nr <= 4 ) then + formspec = formspec.. + "label[0.5,5.5;Bag "..bag_nr.."]"; + local stack = player:get_inventory():get_stack( "bag"..bag_nr, 1) + if( stack and not( stack:is_empty())) then + local image = stack:get_definition().inventory_image + if( image ) then + formspec = formspec.. + "image[7.5,5.5;1,1;"..image.."]"; + end + local slots = stack:get_definition().groups.bagslots + if( slots and slots>0 ) then -- no bag present? + formspec = formspec.. + "list[current_player;bag"..bag_nr.."contents;0.5,6.5;8,"..tostring(slots/8)..";]"; + end + end + end + + + formspec = formspec..bm..bc..b1..b2..b3..b4.. + -- provide the position of the chest + "field[20,20;0.1,0.1;pos2str;Pos;"..minetest.pos_to_string( pos ).."]".. + -- which inventory was selected? + "field[20,20;0.1,0.1;selected;selected;"..selected.."]"; + + -- instead of updating the formspec of the chest - which would be slow - we display + -- the new formspec directly to the player who asked for it; + -- this is also necessary because players may have bags with diffrent sizes + minetest.show_formspec( player:get_player_name(), "chesttools:shared_chest", formspec ); +end + + +-- translate general formspec calls back to specific chests/locations +chesttools.form_input_handler = function( player, formname, fields) + if( formname == "chesttools:shared_chest" and fields.pos2str ) then + local pos = minetest.string_to_pos( fields.pos2str ); + chesttools.on_receive_fields(pos, formname, fields, player); + return; + end +end + +-- establish a callback so that input from the player-specific formspec gets handled +minetest.register_on_player_receive_fields( chesttools.form_input_handler ); + + +minetest.register_node( 'chesttools:shared_chest', { + description = 'Shared chest which can be used by all who can build at that spot', + name = 'shared chest', + tiles = chesttools.chest_add.tiles, + groups = chesttools.chest_add.groups, + tube = chesttools.chest_add.tube, + paramtype2 = "facedir", + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_wood_defaults(), + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + meta:set_string("infotext", "Shared Chest (owned by "..meta:get_string("owner")..")") + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Shared Chest") + meta:set_string("owner", "") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + meta:set_string("formspec", chesttools.formspec.. + "list[current_player;main;0.5,5.5;8,4;]"); + end, + + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") and player:get_player_name() == meta:get_string('owner'); + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, + to_list, to_index, count, player) + + -- the shared function only kicks in if the area is protected + if( not( chesttools.may_use( pos, player ))) then + return 0; + end + return count; + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + + if( not( chesttools.may_use( pos, player ))) then + return 0; + end + return stack:get_count(); + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + + if( not( chesttools.may_use( pos, player ))) then + return 0; + end + return stack:get_count(); + end, + + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " puts "..tostring( stack:to_string() ).." to shared chest at "..minetest.pos_to_string(pos)) + end, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " takes "..tostring( stack:to_string() ).." from shared chest at "..minetest.pos_to_string(pos)) + end, + + + on_receive_fields = function(pos, formname, fields, sender) + + if( not( chesttools.may_use( pos, sender ))) then + return; + end + chesttools.on_receive_fields( pos, formname, fields, sender); + end, +}) diff --git a/textures/chesttools_blue_chest_lock.png b/textures/chesttools_blue_chest_lock.png new file mode 100644 index 0000000000000000000000000000000000000000..96f5080921f2060720998f9a0bc9df932e40c1a4 GIT binary patch literal 742 zcmV^TA0WheU1TGSys;Z*&{e&nw4_w{&_%+Xt%%oqPBCrF9sF60XHxnY) zXx$4V(Kt^}=J8pUJ06_MiRk%GP^RqO!GRJ1`1Rpopv+9n#LQH2@-(vdzVF8?<;JiY zua;-;AMoAj#p$ECKjUw|e{p}tOXcdYv$j->2gO)KXtv*+9HqQ;DXP!tmmmLr^{q1^ zvREvJ!{HYn{Bhypc~zvSz2z*m=6}2M@bK`sTUDxBUiX zSbOL7eRZ?tBfD`-vdYUbGyQw9JenJbyxWc0$jZ`}7TUtd~Rg=h@y zBRL}S&iS(P0021l033%_7URJRlgr4NMF0W>4rZoe9BTz&CL$&p0l*xA)r2W)G=d~a z!{j`XiZLbg{s}ZdjJ3c07*qoM6N<$f47p6h^=ObI$#l zzZj2Yu$6)qo`fgh9nvOGkhcg01udeYODaT5528W{kg$bGJf1uEoO|}(6vL|5k{12& z%^zLXVU_07!ptc%3n6G}?eM<#yi$+%kLH0DF6gK!ZP;_)!p4O z=(eGnPnpNB-+ZAg6k*%(g1`b0QL!bnMi`M4pEr4LUZ?hcs!ypC-d%J=bhaCuDP>kC z0+3|Llp-v`BElWV$EvEj)tjr~Imjr|YUD6FoQfu45^K&v0ncTvbTl)%`?(w+S~p0m zu8AZwGfoH7j>_bDpgOrbTJ_CkYD?%(@BX~MKdi^m-TN+eS=(ZVY3_6W``-_jyG?6t zn(NRd5!vt8di&|_)$6ylob4%?U!2Srs!{;eGH&_<1i=j zSUT>D&mH$fG_^*01VoCr&mSpH< zQ0XG#+_=NMDv^^Ak&5sz>UmjM0SIUF7Vz0li6l?~7?3$fgj;Z(9YBPcg?R;l5CVG` zQz~9T)~qmz61fEv!(#yuXvJsqx?oNu5mvkc2#34J8HWOhh)w>ewt0zVl{TY0ksZom zl}CV2ZF2WP$2;6>BKq;GyI+3&>uSI4v;OliEmq3xpM8G&`)?1YI$vGxj>l5VvRZZF cxc+4G9|o{es_7WN;s5{u07*qoM6N<$f=a_A5C8xG literal 0 HcmV?d00001 diff --git a/textures/chesttools_blue_chest_top.png b/textures/chesttools_blue_chest_top.png new file mode 100644 index 0000000000000000000000000000000000000000..5596ffb081a6f586e0e08b2a67ed7e87cd92e4fe GIT binary patch literal 643 zcmV-}0(||6P)(4(>)P&5zo6GkIiUA_R=7Xk%%rhd!7AtSsGajAS2`{%Bbuskm zc|oJxizk6frD-8V0H}7RNhQ;do46$ZT{~JzA#Ddvf`X!An4FQAq!uCvB8Eq25&)24ss`F=i=o>((E}ioyS#K9@aXsda*!a2 z0~UqML`4MC3#KQ?O4CLh-oL6)shBoKCPgn0E2@RaMAd|Pj0Nlzw$!^DirVS(sPqeRbB=5NA-8X3nN~EJw*`k9u z)3-f~w7r2Sj6-TN*