From 33641e331dcec34a617a844526be01be6e5acd85 Mon Sep 17 00:00:00 2001 From: TenPlus1 Date: Sun, 18 Feb 2018 11:22:37 +0000 Subject: [PATCH] tidy code, reduce inventory fluff --- init.lua | 13 +++++++++ inventory.lua | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index 3401f56..067f058 100644 --- a/init.lua +++ b/init.lua @@ -1,11 +1,14 @@ + creative = {} + minetest.register_privilege("creative", { description = "Allow player to use creative inventory", give_to_singleplayer = false, give_to_admin = false }) + local creative_mode_cache = minetest.settings:get_bool("creative_mode") function creative.is_enabled_for(name) @@ -13,8 +16,10 @@ function creative.is_enabled_for(name) minetest.check_player_privs(name, {creative = true}) end + dofile(minetest.get_modpath("creative") .. "/inventory.lua") + if creative_mode_cache then -- Dig time is modified according to difference (leveldiff) between tool -- 'maxlevel' and node 'level'. Digtime is divided by the larger of @@ -45,6 +50,7 @@ if creative_mode_cache then }) end + -- Unlimited node placement minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) if placer and placer:is_player() then @@ -52,17 +58,24 @@ minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack end end) + -- Don't pick up if the item is already in the inventory local old_handle_node_drops = minetest.handle_node_drops + function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() or -- not creative.is_enabled_for(digger:get_player_name()) then not creative_mode_cache then return old_handle_node_drops(pos, drops, digger) end + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + if not inv:contains_item("main", item, true) then inv:add_item("main", item) end diff --git a/inventory.lua b/inventory.lua index f16e566..0f98fc3 100644 --- a/inventory.lua +++ b/inventory.lua @@ -1,22 +1,32 @@ + local player_inventory = {} local inventory_cache = {} + local function init_creative_cache(items) + inventory_cache[items] = {} + local i_cache = inventory_cache[items] for name, def in pairs(items) do + if def.groups.not_in_creative_inventory ~= 1 and def.description and def.description ~= "" then i_cache[name] = def end end + table.sort(i_cache) + return i_cache end + function creative.init_creative_inventory(player) + local player_name = player:get_player_name() + player_inventory[player_name] = { size = 0, filter = "", @@ -24,27 +34,39 @@ function creative.init_creative_inventory(player) } minetest.create_detached_inventory("creative_" .. player_name, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + local name = player2 and player2:get_player_name() or "" + if not creative.is_enabled_for(name) or to_list == "main" then return 0 end + return count end, + allow_put = function(inv, listname, index, stack, player2) return 0 end, + allow_take = function(inv, listname, index, stack, player2) + local name = player2 and player2:get_player_name() or "" + if not creative.is_enabled_for(name) then return 0 end + return -1 end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player2) end, + on_take = function(inv, listname, index, stack, player2) + if stack and stack:get_count() > 0 then minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory") end @@ -54,15 +76,24 @@ function creative.init_creative_inventory(player) return player_inventory[player_name] end + function creative.update_creative_inventory(player_name, tab_content) + local creative_list = {} + local inv = player_inventory[player_name] or creative.init_creative_inventory(minetest.get_player_by_name(player_name)) - local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) - local items = inventory_cache[tab_content] or init_creative_cache(tab_content) + local player_inv = minetest.get_inventory({ + type = "detached", + name = "creative_" .. player_name + }) + + local items = inventory_cache[tab_content] or + init_creative_cache(tab_content) for name, def in pairs(items) do + if def.name:find(inv.filter, 1, true) or def.description:lower():find(inv.filter, 1, true) then creative_list[#creative_list+1] = name @@ -75,6 +106,7 @@ function creative.update_creative_inventory(player_name, tab_content) inv.size = #creative_list end + -- Create the trash field local trash = minetest.create_detached_inventory("creative_trash", { -- Allow the stack to be placed and remove it in on_put() @@ -82,27 +114,48 @@ local trash = minetest.create_detached_inventory("creative_trash", { allow_put = function(inv, listname, index, stack, player) return stack:get_count() end, + on_put = function(inv, listname) inv:set_list(listname, {}) end, }) + trash:set_size("main", 1) creative.formspec_add = "" + function creative.register_tab(name, title, items) + + -- remove item fluff and only keep name, description and groups + for name, def in pairs(items) do + items[name] = { + name = name, + description = def.description, + groups = def.groups, + } + end + + -- register sfinv tab sfinv.register_page("creative:" .. name, { + title = title, + is_in_nav = function(self, player, context) return creative.is_enabled_for(player:get_player_name()) end, + get = function(self, player, context) + local player_name = player:get_player_name() + creative.update_creative_inventory(player_name, items) + local inv = player_inventory[player_name] local start_i = inv.start_i or 0 local pagenum = math.floor(start_i / (3*8) + 1) local pagemax = math.ceil(inv.size / (3*8)) + return sfinv.make_formspec(player, context, "label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" .. [[ @@ -128,60 +181,83 @@ function creative.register_tab(name, title, items) default.gui_bg .. default.gui_bg_img .. default.gui_slots .. creative.formspec_add, false) end, + on_enter = function(self, player, context) + local player_name = player:get_player_name() local inv = player_inventory[player_name] + if inv then inv.start_i = 0 end end, + on_player_receive_fields = function(self, player, context, fields) + local player_name = player:get_player_name() local inv = player_inventory[player_name] + assert(inv) if fields.creative_clear then + inv.start_i = 0 inv.filter = "" creative.update_creative_inventory(player_name, items) sfinv.set_player_inventory_formspec(player, context) + elseif fields.creative_search or fields.key_enter_field == "creative_filter" then + inv.start_i = 0 inv.filter = fields.creative_filter:lower() creative.update_creative_inventory(player_name, items) sfinv.set_player_inventory_formspec(player, context) + elseif not fields.quit then + local start_i = inv.start_i or 0 if fields.creative_prev then + start_i = start_i - 3*8 + if start_i < 0 then + start_i = inv.size - (inv.size % (3*8)) + if inv.size == start_i then start_i = math.max(0, inv.size - (3*8)) end end + elseif fields.creative_next then + start_i = start_i + 3*8 + if start_i >= inv.size then start_i = 0 end end inv.start_i = start_i + sfinv.set_player_inventory_formspec(player, context) end end }) end + -- Only add a single 'Creative' tab with search ability for all items creative.register_tab("all", "Creative", minetest.registered_items) + -- Set player homepage to 'Creative' tab if game mode or priv set local old_homepage_name = sfinv.get_homepage_name + function sfinv.get_homepage_name(player) + if creative.is_enabled_for(player:get_player_name()) then return "creative:all" else