From 62bcff22e4e786bc61486d6fabf915bcc7148605 Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Mon, 22 Jul 2019 22:03:21 -0500 Subject: [PATCH] Add scroll buttons to chests. --- init.lua | 139 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 22 deletions(-) diff --git a/init.lua b/init.lua index 0753db2..30c0be5 100644 --- a/init.lua +++ b/init.lua @@ -16,15 +16,6 @@ mod.dat = {} local worn_inv = 'worn' local sorted_items -mod.form_size = 'size[11.25,7.75]' -mod.main_inventory = 'list[current_player;main;0,4;8,4;' -mod.craft_inventory = 'list[current_player;craft;3,0;3,3;]' -mod.craft_preview = 'list[current_player;craftpreview;6,1;1,1;]' -mod.main_inventory_scroll_up = 'image_button[8,4;1,1;transparent_button.png;dinv_main_inventory_up;Up]' -mod.main_inventory_scroll_down = 'image_button[8,7;1,1;transparent_button.png;dinv_main_inventory_down;Down]' -mod.recipe_buttons = 'image_button[3,3;1,1;transparent_button.png;dinv_recipe_back;Back]image_button[5,3;1,1;transparent_button.png;dinv_recipe_fore;Fore]' -mod.worn_items_inv = 'list[current_player;worn;9.25,4;2,4;]' - minetest.register_craftitem(mod_name..':bag_small', { inventory_image = 'bags_small.png', @@ -333,6 +324,16 @@ end local worn_items = mod.worn_items +mod.form_size = 'size[11.25,7.75]' +mod.main_inventory = 'list[current_player;main;0,4;8,4;' +mod.craft_inventory = 'list[current_player;craft;3,0;3,3;]' +mod.craft_preview = 'list[current_player;craftpreview;6,1;1,1;]' +mod.main_inventory_scroll_up = 'image_button[8,4;1,1;transparent_button.png;dinv_main_inventory_up;Up]' +mod.main_inventory_scroll_down = 'image_button[8,7;1,1;transparent_button.png;dinv_main_inventory_down;Down]' +mod.recipe_buttons = 'image_button[3,3;1,1;transparent_button.png;dinv_recipe_back;Back]image_button[5,3;1,1;transparent_button.png;dinv_recipe_fore;Fore]' +mod.worn_items_inv = 'list[current_player;worn;9.25,4;2,4;]' + + function mod.make_inventory_spec(player) if not player then return @@ -359,6 +360,91 @@ function mod.make_inventory_spec(player) end +function default.chest.get_chest_formspec(pos, player) + local scroll_to = 8 + if player and player.get_player_name then + local player_name = player:get_player_name() + if mod.dat[player_name].scroll_main_to then + scroll_to = mod.dat[player_name].scroll_main_to + end + end + + local spos = pos.x .. ',' .. pos.y .. ',' .. pos.z + local formspec = + 'size[9,9]' .. + 'list[nodemeta:' .. spos .. ';main;0,0.3;8,4;]' .. + 'list[current_player;main;0,4.85;8,1;]' .. + 'list[current_player;main;0,6.08;8,3;' .. scroll_to .. ']' .. + 'listring[nodemeta:' .. spos .. ';main]' .. + 'listring[current_player;main]' .. + 'image_button[8,6.08;1,1;transparent_button.png;dinv_chest_main_inventory_up;Up]' .. + 'image_button[8,8.08;1,1;transparent_button.png;dinv_chest_main_inventory_down;Down]' .. + default.get_hotbar_bg(0,4.85) + return formspec +end + + +local original_chest_functions = {} +for _, nd in pairs({ 'default:chest', 'default:chest_locked' }) do + original_chest_functions[nd] = {} + original_chest_functions[nd].on_rightclick = minetest.registered_items[nd].on_rightclick + + minetest.override_item(nd, { + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if clicker.get_player_name then + local player_name = clicker:get_player_name() + local dat = mod.dat[player_name] + if dat then + dat.chest_opened = pos + end + end + + original_chest_functions[nd].on_rightclick(pos, node, clicker, itemstack, pointed_thing) + end + }) +end + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= 'default:chest' then + return + end + + if not (player and fields) then + return + end + + if not ( + fields['dinv_chest_main_inventory_up'] + or fields['dinv_chest_main_inventory_down'] + ) then + return + end + + local player_name = player:get_player_name() + + local dat = mod.dat[player_name] or {} + local pos = dat.chest_opened + if not pos then + return + end + + local pinv = player:get_inventory() + local main_inventory_size = pinv:get_size('main') + + if fields['dinv_chest_main_inventory_up'] then + dat['scroll_main_to'] = math.max(8, (dat['scroll_main_to'] or 8) - 16) + minetest.show_formspec(player_name, 'default:chest', default.chest.get_chest_formspec(pos, player)) + elseif fields['dinv_chest_main_inventory_down'] then + dat['scroll_main_to'] = (dat['scroll_main_to'] or 8) + 16 + if dat['scroll_main_to'] >= main_inventory_size then + dat['scroll_main_to'] = 8 + end + minetest.show_formspec(player_name, 'default:chest', default.chest.get_chest_formspec(pos, player)) + end +end) + + function mod.recipe_grid(player) local player_name = player:get_player_name() local dat = mod.dat[player_name] @@ -474,20 +560,14 @@ function mod.scroll_main(player, amount, max) return end - local fs = player:get_inventory_formspec() - --print('.*' .. mod.main_inventory:gsub('%[', '%%[') .. '(%d+)%].*') - local scroll = fs:gsub('.*%' .. mod.main_inventory:gsub('%[', '%%[') .. '(%d+)%].*', '%1') - --print(scroll) - if scroll then - local scroll_n = tonumber(scroll) - if scroll_n and scroll_n % 8 == 0 then - scroll_n = (scroll_n + amount) - if scroll_n > max or scroll_n < 0 then - scroll_n = 0 - end - mod.dat[player_name].scroll_main_to = scroll_n - player:set_inventory_formspec(mod.make_inventory_spec(player)) + local scroll = mod.dat[player_name].scroll_main_to or 0 + if scroll and scroll % 8 == 0 then + scroll = (scroll + amount) + if scroll > max or scroll < 0 then + scroll = 0 end + mod.dat[player_name].scroll_main_to = scroll + player:set_inventory_formspec(mod.make_inventory_spec(player)) end end @@ -505,6 +585,7 @@ function mod.get_main_size_by_bags(player) return isize end + function mod.set_main_size_by_bags(player) if not player then return @@ -592,6 +673,20 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) + if not (player and fields) then + return + end + + if not ( + fields['dinv_main_inventory_up'] + or fields['dinv_main_inventory_down'] + or fields['dinv_recipe_list'] + or fields['dinv_recipe_back'] + or fields['dinv_recipe_fore'] + ) then + return + end + local pinv = player:get_inventory() local main_inventory_size = pinv:get_size('main')