Compare commits
	
		
			20 Commits
		
	
	
		
			master
			...
			9649c0ed0e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9649c0ed0e | |||
| 4633a276a2 | |||
| 1ac54a017d | |||
| 4c4fb3ba88 | |||
| 9d66a21271 | |||
| 15a84bdbf4 | |||
| 838c67ae86 | |||
| 132a362f85 | |||
| 03b077cd1b | |||
| 829b38c6fc | |||
| 70fdb8556b | |||
| 497c632b24 | |||
| 46eeb36784 | |||
| 9a31609cfd | |||
| 8e6a3740ae | |||
| 1fd87f5c51 | |||
| e5dc9ed53a | |||
| 
						 | 
					4bf5f22696 | ||
| 
						 | 
					4f666f93d0 | ||
| 
						 | 
					264833ed41 | 
@@ -1,6 +1,6 @@
 | 
			
		||||
unused_args = false
 | 
			
		||||
allow_defined_top = true
 | 
			
		||||
max_line_length = 131
 | 
			
		||||
max_line_length = 999
 | 
			
		||||
 | 
			
		||||
globals = {
 | 
			
		||||
	"unified_inventory",
 | 
			
		||||
@@ -10,10 +10,8 @@ read_globals = {
 | 
			
		||||
	string = {fields = {"split", "trim"}},
 | 
			
		||||
	table = {fields = {"copy", "getn"}},
 | 
			
		||||
 | 
			
		||||
	"dump",
 | 
			
		||||
	"core", "minetest",
 | 
			
		||||
	"minetest", "vector",
 | 
			
		||||
	"ItemStack", "datastorage",
 | 
			
		||||
	"vector",
 | 
			
		||||
 | 
			
		||||
	"hb",
 | 
			
		||||
	"doors",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@@ -71,9 +71,6 @@ From http://www.clker.com (Public Domain, CC-BY-4.0):
 | 
			
		||||
  * [`ui_pencil_icon.pnc`](http://www.clker.com/clipart-2256.html)
 | 
			
		||||
  * [`ui_waypoint_set_icon.png`](http://www.clker.com/clipart-larger-flag.html)
 | 
			
		||||
 | 
			
		||||
From https://www.svgrepo.com (CC-BY)
 | 
			
		||||
  * [`ui_teleport.png`](https://www.svgrepo.com/svg/321565/teleport)
 | 
			
		||||
 | 
			
		||||
Everaldo Coelho (YellowIcon) (LGPL v2.1+):
 | 
			
		||||
 | 
			
		||||
  * [`ui_craftguide_icon.png` / `ui_craft_icon.png`](http://commons.wikimedia.org/wiki/File:Advancedsettings.png)
 | 
			
		||||
@@ -105,16 +102,3 @@ Other files from Wikimedia Commons:
 | 
			
		||||
RealBadAngel: (CC-BY-4.0)
 | 
			
		||||
 | 
			
		||||
  * Everything else.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Sounds
 | 
			
		||||
 | 
			
		||||
 * [`bell.ogg`](https://freesound.org/people/bennstir/sounds/81072/) by bennstir, CC 4.0
 | 
			
		||||
 * [`electricity.ogg`](https://freesound.org/people/Halleck/sounds/19486/) by Halleck, CC 4.0 (cut)
 | 
			
		||||
 * [`pageflip1.ogg`](https://freesound.org/people/themfish/sounds/45823/) by themfish, CC 4.0 (cut, slowed down)
 | 
			
		||||
 * `pageflip2.ogg` (derived from `pageflip1.ogg`)
 | 
			
		||||
 * [`trash.ogg`](https://freesound.org/people/OwlStorm/sounds/151231/) by OwlStorm, CC 0 (speed up)
 | 
			
		||||
 * [`trash_all.ogg`](https://freesound.org/people/abel_K/sounds/68280/) by abel_K, Sampling Plus 1.0 (speed up)
 | 
			
		||||
 * [`ui_click.ogg`](https://freesound.org/people/lartti/sounds/527569/) by lartti, CC 0 (cut)
 | 
			
		||||
 * [`ui_morning.ogg`](https://freesound.org/people/InspectorJ/sounds/439472/) by InspectorJ, CC 4.0
 | 
			
		||||
 * [`ui_owl.ogg`](https://freesound.org/people/manda_g/sounds/54987/) by manda_g, Sampling Plus 1.0 (cut)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										149
									
								
								api.lua
									
									
									
									
									
								
							
							
						
						@@ -2,61 +2,48 @@ local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
local function is_recipe_craftable(recipe)
 | 
			
		||||
	-- Ensure the ingedients exist
 | 
			
		||||
	for _, itemname in pairs(recipe.items) do
 | 
			
		||||
		local groups = string.find(itemname, "group:")
 | 
			
		||||
		if groups then
 | 
			
		||||
			if not ui.get_group_item(string.sub(groups, 8)).item then
 | 
			
		||||
				return false
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			-- Possibly an item
 | 
			
		||||
			local itemname_cleaned = ItemStack(itemname):get_name()
 | 
			
		||||
			if not minetest.registered_items[itemname_cleaned]
 | 
			
		||||
					or minetest.get_item_group(itemname_cleaned, "not_in_craft_guide") ~= 0 then
 | 
			
		||||
				return false
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return true
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Create detached creative inventory after loading all mods
 | 
			
		||||
minetest.after(0.01, function()
 | 
			
		||||
	local rev_aliases = {}
 | 
			
		||||
	for original, newname in pairs(minetest.registered_aliases) do
 | 
			
		||||
		if not rev_aliases[newname] then
 | 
			
		||||
			rev_aliases[newname] = {}
 | 
			
		||||
		end
 | 
			
		||||
		table.insert(rev_aliases[newname], original)
 | 
			
		||||
	for source, target in pairs(minetest.registered_aliases) do
 | 
			
		||||
		if not rev_aliases[target] then rev_aliases[target] = {} end
 | 
			
		||||
		table.insert(rev_aliases[target], source)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Filtered item list
 | 
			
		||||
	ui.items_list = {}
 | 
			
		||||
	for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
		if ui.is_itemdef_listable(def) then
 | 
			
		||||
		if (not def.groups.not_in_creative_inventory or
 | 
			
		||||
		   def.groups.not_in_creative_inventory == 0) and
 | 
			
		||||
		   def.description and def.description ~= "" then
 | 
			
		||||
			table.insert(ui.items_list, name)
 | 
			
		||||
 | 
			
		||||
			-- Alias processing: Find recipes that belong to the current item name
 | 
			
		||||
			local all_names = rev_aliases[name] or {}
 | 
			
		||||
			table.insert(all_names, name)
 | 
			
		||||
			for _, itemname in ipairs(all_names) do
 | 
			
		||||
				local recipes = minetest.get_all_craft_recipes(itemname)
 | 
			
		||||
				for _, recipe in ipairs(recipes or {}) do
 | 
			
		||||
					if is_recipe_craftable(recipe) then
 | 
			
		||||
						ui.register_craft(recipe)
 | 
			
		||||
			for _, player_name in ipairs(all_names) do
 | 
			
		||||
				local recipes = minetest.get_all_craft_recipes(player_name)
 | 
			
		||||
				if recipes then
 | 
			
		||||
					for _, recipe in ipairs(recipes) do
 | 
			
		||||
 | 
			
		||||
						local unknowns
 | 
			
		||||
 | 
			
		||||
						for _,chk in pairs(recipe.items) do
 | 
			
		||||
							local groupchk = string.find(chk, "group:")
 | 
			
		||||
							if (not groupchk and not minetest.registered_items[chk])
 | 
			
		||||
							  or (groupchk and not ui.get_group_item(string.gsub(chk, "group:", "")).item)
 | 
			
		||||
							  or minetest.get_item_group(chk, "not_in_craft_guide") ~= 0 then
 | 
			
		||||
								unknowns = true
 | 
			
		||||
							end
 | 
			
		||||
						end
 | 
			
		||||
 | 
			
		||||
						if not unknowns then
 | 
			
		||||
							ui.register_craft(recipe)
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	table.sort(ui.items_list)
 | 
			
		||||
	ui.items_list_size = #ui.items_list
 | 
			
		||||
	print("Unified Inventory. Inventory size: "..ui.items_list_size)
 | 
			
		||||
 | 
			
		||||
	-- Analyse dropped items -> custom "digging" recipes
 | 
			
		||||
	print("Unified Inventory. inventory size: "..ui.items_list_size)
 | 
			
		||||
	for _, name in ipairs(ui.items_list) do
 | 
			
		||||
		local def = minetest.registered_items[name]
 | 
			
		||||
		-- Simple drops
 | 
			
		||||
@@ -146,73 +133,24 @@ minetest.after(0.01, function()
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Step 1: Initialize cache for looking up groups
 | 
			
		||||
	unified_inventory.init_matching_cache()
 | 
			
		||||
 | 
			
		||||
	-- Step 2: Find all matching items for the given spec (groups)
 | 
			
		||||
	local get_matching_spec_items = unified_inventory.get_matching_items
 | 
			
		||||
 | 
			
		||||
	for outputitemname, recipes in pairs(ui.crafts_for.recipe) do
 | 
			
		||||
		-- List of crafts that return this item string (variable "_")
 | 
			
		||||
 | 
			
		||||
		-- Problem: The group cache must be initialized after all mods finished loading
 | 
			
		||||
		-- thus, invalid recipes might be indexed. Hence perform filtering with `new_recipe_list`
 | 
			
		||||
		local new_recipe_list = {}
 | 
			
		||||
	for _, recipes in pairs(ui.crafts_for.recipe) do
 | 
			
		||||
		for _, recipe in ipairs(recipes) do
 | 
			
		||||
			local ingredient_items = {}
 | 
			
		||||
			for _, spec in pairs(recipe.items) do
 | 
			
		||||
				-- Get items that fit into this spec (group or item name)
 | 
			
		||||
				local specname = ItemStack(spec):get_name()
 | 
			
		||||
				for item_name, _ in pairs(get_matching_spec_items(specname)) do
 | 
			
		||||
					ingredient_items[item_name] = true
 | 
			
		||||
				local matches_spec = ui.canonical_item_spec_matcher(spec)
 | 
			
		||||
				for _, name in ipairs(ui.items_list) do
 | 
			
		||||
					if matches_spec(name) then
 | 
			
		||||
						ingredient_items[name] = true
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			for name, _ in pairs(ingredient_items) do
 | 
			
		||||
				if not ui.crafts_for.usage[name] then
 | 
			
		||||
				if ui.crafts_for.usage[name] == nil then
 | 
			
		||||
					ui.crafts_for.usage[name] = {}
 | 
			
		||||
				end
 | 
			
		||||
				table.insert(ui.crafts_for.usage[name], recipe)
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			if next(ingredient_items) then
 | 
			
		||||
				-- There's at least one known ingredient: mark as good recipe
 | 
			
		||||
				-- PS: What whatll be done about partially incomplete recipes?
 | 
			
		||||
				table.insert(new_recipe_list, recipe)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		ui.crafts_for.recipe[outputitemname] = new_recipe_list
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Remove unknown items from all categories
 | 
			
		||||
	local total_removed = 0
 | 
			
		||||
	for cat_name, cat_def in pairs(ui.registered_category_items) do
 | 
			
		||||
		for itemname, _ in pairs(cat_def) do
 | 
			
		||||
			local idef = minetest.registered_items[itemname]
 | 
			
		||||
			if not idef then
 | 
			
		||||
				total_removed = total_removed + 1
 | 
			
		||||
				--[[
 | 
			
		||||
				-- For analysis
 | 
			
		||||
				minetest.log("warning", "[unified_inventory] Removed item '"
 | 
			
		||||
					.. itemname .. "' from category '" .. cat_name
 | 
			
		||||
					.. "'. Reason: item not registered")
 | 
			
		||||
				]]
 | 
			
		||||
				cat_def[itemname] = nil
 | 
			
		||||
			elseif not ui.is_itemdef_listable(idef) then
 | 
			
		||||
				total_removed = total_removed + 1
 | 
			
		||||
				--[[
 | 
			
		||||
				-- For analysis
 | 
			
		||||
				minetest.log("warning", "[unified_inventory] Removed item '"
 | 
			
		||||
					.. itemname .. "' from category '" .. cat_name
 | 
			
		||||
					.. "'. Reason: item is in 'not_in_creative_inventory' group")
 | 
			
		||||
				]]
 | 
			
		||||
				cat_def[itemname] = nil
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	if total_removed > 0 then
 | 
			
		||||
		minetest.log("info", "[unified_inventory] Removed " .. total_removed ..
 | 
			
		||||
			" items from the categories.")
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	for _, callback in ipairs(ui.initialized_callbacks) do
 | 
			
		||||
@@ -220,8 +158,8 @@ minetest.after(0.01, function()
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
---------------- Home API ----------------
 | 
			
		||||
 | 
			
		||||
-- load_home
 | 
			
		||||
local function load_home()
 | 
			
		||||
	local input = io.open(ui.home_filename, "r")
 | 
			
		||||
	if not input then
 | 
			
		||||
@@ -238,7 +176,6 @@ local function load_home()
 | 
			
		||||
	end
 | 
			
		||||
	io.close(input)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
load_home()
 | 
			
		||||
 | 
			
		||||
function ui.set_home(player, pos)
 | 
			
		||||
@@ -267,8 +204,7 @@ function ui.go_home(player)
 | 
			
		||||
	return false
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
---------------- Crafting API ----------------
 | 
			
		||||
 | 
			
		||||
-- register_craft
 | 
			
		||||
function ui.register_craft(options)
 | 
			
		||||
	if not options.output then
 | 
			
		||||
		return
 | 
			
		||||
@@ -291,12 +227,14 @@ function ui.register_craft(options)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local craft_type_defaults = {
 | 
			
		||||
	width = 3,
 | 
			
		||||
	height = 3,
 | 
			
		||||
	uses_crafting_grid = false,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function ui.craft_type_defaults(name, options)
 | 
			
		||||
	if not options.description then
 | 
			
		||||
		options.description = name
 | 
			
		||||
@@ -307,7 +245,8 @@ end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function ui.register_craft_type(name, options)
 | 
			
		||||
	ui.registered_craft_types[name] = ui.craft_type_defaults(name, options)
 | 
			
		||||
	ui.registered_craft_types[name] =
 | 
			
		||||
			ui.craft_type_defaults(name, options)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -364,8 +303,6 @@ ui.register_craft_type("digging_chance", {
 | 
			
		||||
	height = 1,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
---------------- GUI registrations ----------------
 | 
			
		||||
 | 
			
		||||
function ui.register_page(name, def)
 | 
			
		||||
	ui.pages[name] = def
 | 
			
		||||
end
 | 
			
		||||
@@ -381,8 +318,6 @@ function ui.register_button(name, def)
 | 
			
		||||
	table.insert(ui.buttons, def)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
---------------- Callback registrations ----------------
 | 
			
		||||
 | 
			
		||||
function ui.register_on_initialized(callback)
 | 
			
		||||
	if type(callback) ~= "function" then
 | 
			
		||||
		error(("Initialized callback must be a function, %s given."):format(type(callback)))
 | 
			
		||||
@@ -397,8 +332,6 @@ function ui.register_on_craft_registered(callback)
 | 
			
		||||
	table.insert(ui.craft_registered_callbacks, callback)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
---------------- List getters ----------------
 | 
			
		||||
 | 
			
		||||
function ui.get_recipe_list(output)
 | 
			
		||||
	return ui.crafts_for.recipe[output]
 | 
			
		||||
end
 | 
			
		||||
@@ -411,15 +344,11 @@ function ui.get_registered_outputs()
 | 
			
		||||
	return outputs
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
---------------- Player utilities ----------------
 | 
			
		||||
 | 
			
		||||
function ui.is_creative(playername)
 | 
			
		||||
	return minetest.check_player_privs(playername, {creative=true})
 | 
			
		||||
		or minetest.settings:get_bool("creative_mode")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
---------------- Formspec helpers ----------------
 | 
			
		||||
 | 
			
		||||
function ui.single_slot(xpos, ypos, bright)
 | 
			
		||||
	return string.format("background9[%f,%f;%f,%f;ui_single_slot%s.png;false;16]",
 | 
			
		||||
	xpos, ypos, ui.imgscale, ui.imgscale, (bright and "_bright" or "") )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										143
									
								
								bags.lua
									
									
									
									
									
								
							
							
						
						@@ -10,26 +10,25 @@ local F = minetest.formspec_escape
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
ui.register_page("bags", {
 | 
			
		||||
	get_formspec = function(player, perplayer_formspec)
 | 
			
		||||
	get_formspec = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		local std_inv_x = perplayer_formspec.std_inv_x
 | 
			
		||||
		local formspec = {
 | 
			
		||||
			perplayer_formspec.standard_inv_bg,
 | 
			
		||||
			"label[", perplayer_formspec.form_header_x, ",",
 | 
			
		||||
				perplayer_formspec.form_header_y, ";", F(S("Bags")), "]",
 | 
			
		||||
		return { formspec = table.concat({
 | 
			
		||||
			ui.style_full.standard_inv_bg,
 | 
			
		||||
			ui.single_slot(0.925, 1.5),
 | 
			
		||||
			ui.single_slot(3.425, 1.5),
 | 
			
		||||
			ui.single_slot(5.925, 1.5),
 | 
			
		||||
			ui.single_slot(8.425, 1.5),
 | 
			
		||||
			"label["..ui.style_full.form_header_x..","..ui.style_full.form_header_y..";" .. F(S("Bags")) .. "]",
 | 
			
		||||
			"button[0.6125,2.75;1.875,0.75;bag1;" .. F(S("Bag @1", 1)) .. "]",
 | 
			
		||||
			"button[3.1125,2.75;1.875,0.75;bag2;" .. F(S("Bag @1", 2)) .. "]",
 | 
			
		||||
			"button[5.6125,2.75;1.875,0.75;bag3;" .. F(S("Bag @1", 3)) .. "]",
 | 
			
		||||
			"button[8.1125,2.75;1.875,0.75;bag4;" .. F(S("Bag @1", 4)) .. "]",
 | 
			
		||||
			"listcolors[#00000000;#00000000]",
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for i = 1, 4 do
 | 
			
		||||
			local x = std_inv_x + i * 2.5
 | 
			
		||||
			formspec[#formspec + 1] = ui.single_slot(x - 1.875, 1.5)
 | 
			
		||||
			formspec[#formspec + 1] = string.format("list[detached:%s_bags;bag%i;%.3f,1.65;1,1;]",
 | 
			
		||||
				F(player_name), i, x - 1.725)
 | 
			
		||||
			formspec[#formspec + 1] = string.format("button[%.4f,2.75;1.875,0.75;bag%i;%s]",
 | 
			
		||||
				x - 2.1875, i, F(S("Bag @1", i)))
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		return { formspec = table.concat(formspec) }
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag1;1.075,1.65;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag2;3.575,1.65;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag3;6.075,1.65;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag4;8.575,1.65;1,1;]"
 | 
			
		||||
		}) }
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -37,6 +36,7 @@ ui.register_button("bags", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_bags_icon.png",
 | 
			
		||||
	tooltip = S("Bags"),
 | 
			
		||||
	hide_lite=true
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
local function get_player_bag_stack(player, i)
 | 
			
		||||
@@ -48,38 +48,23 @@ end
 | 
			
		||||
 | 
			
		||||
for bag_i = 1, 4 do
 | 
			
		||||
	ui.register_page("bag" .. bag_i, {
 | 
			
		||||
		get_formspec = function(player, perplayer_formspec)
 | 
			
		||||
		get_formspec = function(player)
 | 
			
		||||
			local stack = get_player_bag_stack(player, bag_i)
 | 
			
		||||
			local image = stack:get_definition().inventory_image
 | 
			
		||||
			local slots = stack:get_definition().groups.bagslots
 | 
			
		||||
			local std_inv_x = perplayer_formspec.std_inv_x
 | 
			
		||||
			local lite_mode = perplayer_formspec.is_lite_mode
 | 
			
		||||
 | 
			
		||||
			local bag_inv_y, header_x, header_y = 1.5, 0.3, 0.65
 | 
			
		||||
			if lite_mode then
 | 
			
		||||
				bag_inv_y = 0.5
 | 
			
		||||
				header_x = perplayer_formspec.form_header_x
 | 
			
		||||
				header_y = perplayer_formspec.form_header_y
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			local formspec = {
 | 
			
		||||
				perplayer_formspec.standard_inv_bg,
 | 
			
		||||
				ui.make_inv_img_grid(std_inv_x, bag_inv_y, 8, slots/8),
 | 
			
		||||
				"label[", header_x, ",", header_y, ";", F(S("Bag @1", bag_i)), "]",
 | 
			
		||||
				ui.style_full.standard_inv_bg,
 | 
			
		||||
				ui.make_inv_img_grid(0.3, 1.5, 8, slots/8),
 | 
			
		||||
				"image[9.2,0.4;1,1;" .. image .. "]",
 | 
			
		||||
				"label[0.3,0.65;" .. F(S("Bag @1", bag_i)) .. "]",
 | 
			
		||||
				"listcolors[#00000000;#00000000]",
 | 
			
		||||
				"listring[current_player;main]",
 | 
			
		||||
				string.format("list[current_player;bag%icontents;%f,%f;8,3;]",
 | 
			
		||||
				    bag_i, std_inv_x + ui.list_img_offset, bag_inv_y + ui.list_img_offset),
 | 
			
		||||
				"listring[current_name;bag", bag_i, "contents]",
 | 
			
		||||
				    bag_i, 0.3 + ui.list_img_offset, 1.5 + ui.list_img_offset),
 | 
			
		||||
				"listring[current_name;bag" .. bag_i .. "contents]",
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if lite_mode then
 | 
			
		||||
				return { formspec = table.concat(formspec) }
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			local n = #formspec + 1
 | 
			
		||||
			formspec[n] = "image[" .. std_inv_x + 8.9 .. ",0.4;1,1;" .. image .. "]"
 | 
			
		||||
			n = n + 1
 | 
			
		||||
 | 
			
		||||
			local player_name = player:get_player_name() -- For if statement.
 | 
			
		||||
			if ui.trash_enabled
 | 
			
		||||
@@ -129,8 +114,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- Player slots are preserved when unified_inventory is disabled. Do not allow modification.
 | 
			
		||||
-- Fix: use a detached inventory and store the data separately.
 | 
			
		||||
local function save_bags_metadata(player, bags_inv)
 | 
			
		||||
	local is_empty = true
 | 
			
		||||
	local bags = {}
 | 
			
		||||
@@ -144,7 +127,7 @@ local function save_bags_metadata(player, bags_inv)
 | 
			
		||||
	end
 | 
			
		||||
	local meta = player:get_meta()
 | 
			
		||||
	if is_empty then
 | 
			
		||||
		meta:set_string("unified_inventory:bags", "")
 | 
			
		||||
		meta:set_string("unified_inventory:bags", nil)
 | 
			
		||||
	else
 | 
			
		||||
		meta:set_string("unified_inventory:bags",
 | 
			
		||||
			minetest.serialize(bags))
 | 
			
		||||
@@ -180,7 +163,7 @@ local function load_bags_metadata(player, bags_inv)
 | 
			
		||||
		save_bags_metadata(player, bags_inv)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Legacy: Clean up old player lists
 | 
			
		||||
	-- Clean up deprecated garbage after saving
 | 
			
		||||
	for i = 1, 4 do
 | 
			
		||||
		local bag = "bag" .. i
 | 
			
		||||
		player_inv:set_size(bag, 0)
 | 
			
		||||
@@ -189,29 +172,46 @@ end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local bags_inv = minetest.create_detached_inventory(player_name .. "_bags", {
 | 
			
		||||
		allow_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			local new_slots = stack:get_definition().groups.bagslots
 | 
			
		||||
			if not new_slots then
 | 
			
		||||
				return 0 -- ItemStack is not a bag.
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			-- The execution order of `allow_put`/`allow_take` is not defined.
 | 
			
		||||
			-- We do not know the replacement ItemStack if the items are swapped.
 | 
			
		||||
			-- Hence, bag slot upgrades and downgrades are not possible with the
 | 
			
		||||
			-- current API.
 | 
			
		||||
 | 
			
		||||
			if not player:get_inventory():is_empty(listname .. "contents") then
 | 
			
		||||
				-- Legacy: in case `allow_take` is not executed on old Minetest versions.
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
			return 1
 | 
			
		||||
		end,
 | 
			
		||||
	local bags_inv = minetest.create_detached_inventory(player_name .. "_bags",{
 | 
			
		||||
		on_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			player:get_inventory():set_size(listname .. "contents",
 | 
			
		||||
					stack:get_definition().groups.bagslots)
 | 
			
		||||
			save_bags_metadata(player, inv)
 | 
			
		||||
		end,
 | 
			
		||||
		allow_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			local new_slots = stack:get_definition().groups.bagslots
 | 
			
		||||
			if not new_slots then
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
			local player_inv = player:get_inventory()
 | 
			
		||||
			local old_slots = player_inv:get_size(listname .. "contents")
 | 
			
		||||
 | 
			
		||||
			if new_slots >= old_slots then
 | 
			
		||||
				return 1
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			-- using a smaller bag, make sure it fits
 | 
			
		||||
			local old_list = player_inv:get_list(listname .. "contents")
 | 
			
		||||
			local new_list = {}
 | 
			
		||||
			local slots_used = 0
 | 
			
		||||
			local use_new_list = false
 | 
			
		||||
 | 
			
		||||
			for i, v in ipairs(old_list) do
 | 
			
		||||
				if v and not v:is_empty() then
 | 
			
		||||
					slots_used = slots_used + 1
 | 
			
		||||
					use_new_list = i > new_slots
 | 
			
		||||
					new_list[slots_used] = v
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			if new_slots >= slots_used then
 | 
			
		||||
				if use_new_list then
 | 
			
		||||
					player_inv:set_list(listname .. "contents", new_list)
 | 
			
		||||
				end
 | 
			
		||||
				return 1
 | 
			
		||||
			end
 | 
			
		||||
			-- New bag is smaller: Disallow inserting
 | 
			
		||||
			return 0
 | 
			
		||||
		end,
 | 
			
		||||
		allow_take = function(inv, listname, index, stack, player)
 | 
			
		||||
			if player:get_inventory():is_empty(listname .. "contents") then
 | 
			
		||||
				return stack:get_count()
 | 
			
		||||
@@ -221,11 +221,6 @@ minetest.register_on_joinplayer(function(player)
 | 
			
		||||
		on_take = function(inv, listname, index, stack, player)
 | 
			
		||||
			player:get_inventory():set_size(listname .. "contents", 0)
 | 
			
		||||
			save_bags_metadata(player, inv)
 | 
			
		||||
			if listname == ui.current_page[player:get_player_name()] then
 | 
			
		||||
				-- Bag is currently open: avoid follow-up issues by navigating back
 | 
			
		||||
				-- Trick: the list name is the same as the registered page name
 | 
			
		||||
				ui.set_inventory_formspec(player, "bags")
 | 
			
		||||
			end
 | 
			
		||||
		end,
 | 
			
		||||
		allow_move = function()
 | 
			
		||||
			return 0
 | 
			
		||||
@@ -235,20 +230,6 @@ minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	load_bags_metadata(player, bags_inv)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
minetest.register_allow_player_inventory_action(function(player, action, inventory, info)
 | 
			
		||||
	-- From detached inventory -> player inventory: put & take callbacks
 | 
			
		||||
	if action ~= "put" or not info.listname:find("bag%dcontents") then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	if info.stack:get_definition().groups.bagslots then
 | 
			
		||||
		-- Problem 1: empty bags could be moved into their own slots
 | 
			
		||||
		-- Problem 2: cannot reliably keep track of ItemStack ownership due to
 | 
			
		||||
		--> Disallow all external bag movements into this list
 | 
			
		||||
		return 0
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- register bag tools
 | 
			
		||||
minetest.register_tool("unified_inventory:bag_small", {
 | 
			
		||||
	description = S("Small Bag"),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										115
									
								
								callbacks.lua
									
									
									
									
									
								
							
							
						
						@@ -1,5 +1,3 @@
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
local function default_refill(stack)
 | 
			
		||||
	stack:set_count(stack:get_stack_max())
 | 
			
		||||
	local itemdef = minetest.registered_items[stack:get_name()]
 | 
			
		||||
@@ -14,17 +12,19 @@ end
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	unified_inventory.players[player_name] = {}
 | 
			
		||||
	unified_inventory.current_index[player_name] = 1 -- Item (~page) index
 | 
			
		||||
	unified_inventory.current_index[player_name] = 1
 | 
			
		||||
	unified_inventory.filtered_items_list[player_name] =
 | 
			
		||||
		unified_inventory.items_list
 | 
			
		||||
	unified_inventory.items_list
 | 
			
		||||
	unified_inventory.activefilter[player_name] = ""
 | 
			
		||||
	unified_inventory.active_search_direction[player_name] = "nochange"
 | 
			
		||||
	unified_inventory.apply_filter(player, "", "nochange")
 | 
			
		||||
	unified_inventory.current_searchbox[player_name] = ""
 | 
			
		||||
	unified_inventory.current_category[player_name] = "all"
 | 
			
		||||
	unified_inventory.current_category_scroll[player_name] = 0
 | 
			
		||||
	unified_inventory.alternate[player_name] = 1
 | 
			
		||||
	unified_inventory.current_item[player_name] = nil
 | 
			
		||||
	unified_inventory.current_craft_direction[player_name] = "recipe"
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player, unified_inventory.default)
 | 
			
		||||
 | 
			
		||||
	-- Refill slot
 | 
			
		||||
	local refill = minetest.create_detached_inventory(player_name.."refill", {
 | 
			
		||||
@@ -46,58 +46,30 @@ minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	refill:set_size("main", 1)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
       minetest.register_on_joinplayer(function(player)
 | 
			
		||||
               -- After everything is initialized, set up the formspec
 | 
			
		||||
               ui.apply_filter(player, "", "nochange")
 | 
			
		||||
               ui.set_inventory_formspec(player, unified_inventory.default)
 | 
			
		||||
       end)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local function apply_new_filter(player, search_text, new_dir)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	minetest.sound_play("ui_click", {to_player=player_name, gain = 0.1})
 | 
			
		||||
	ui.apply_filter(player, search_text, new_dir)
 | 
			
		||||
	ui.current_searchbox[player_name] = search_text
 | 
			
		||||
	ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Search box handling
 | 
			
		||||
local function receive_fields_searchbox(player, formname, fields)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	-- always take new search text, even if not searching on it yet
 | 
			
		||||
	if fields.searchbox and fields.searchbox ~= ui.current_searchbox[player_name] then
 | 
			
		||||
		ui.current_searchbox[player_name] = fields.searchbox
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if fields.searchbutton
 | 
			
		||||
			or fields.key_enter_field == "searchbox" then
 | 
			
		||||
 | 
			
		||||
		if ui.current_searchbox[player_name] ~= ui.activefilter[player_name] then
 | 
			
		||||
			ui.apply_filter(player, ui.current_searchbox[player_name], "nochange")
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
			minetest.sound_play("paperflip2",
 | 
			
		||||
					{to_player=player_name, gain = 1.0})
 | 
			
		||||
		end
 | 
			
		||||
	elseif fields.searchresetbutton then
 | 
			
		||||
		if ui.activefilter[player_name] ~= "" then
 | 
			
		||||
			apply_new_filter(player, "", "nochange")
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	minetest.sound_play("click", {to_player=player_name, gain = 0.1})
 | 
			
		||||
	unified_inventory.apply_filter(player, search_text, new_dir)
 | 
			
		||||
	unified_inventory.current_searchbox[player_name] = search_text
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
			unified_inventory.current_page[player_name])
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
 | 
			
		||||
 | 
			
		||||
	if formname ~= "" then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	receive_fields_searchbox(player, formname, fields)
 | 
			
		||||
	-- always take new search text, even if not searching on it yet
 | 
			
		||||
	if fields.searchbox
 | 
			
		||||
	and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
 | 
			
		||||
		unified_inventory.current_searchbox[player_name] = fields.searchbox
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
 | 
			
		||||
 | 
			
		||||
	local clicked_category
 | 
			
		||||
	for name, value in pairs(fields) do
 | 
			
		||||
@@ -116,14 +88,19 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
				unified_inventory.current_page[player_name])
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if fields.next_category or fields.prev_category then
 | 
			
		||||
		local step = fields.next_category and 1 or -1
 | 
			
		||||
		local scroll_old = ui.current_category_scroll[player_name]
 | 
			
		||||
		local scroll_new = math.max(0, math.min(#ui.category_list - ui_peruser.pagecols, scroll_old + step))
 | 
			
		||||
 | 
			
		||||
		if scroll_old ~= scroll_new then
 | 
			
		||||
			ui.current_category_scroll[player_name] = scroll_new
 | 
			
		||||
			ui.set_inventory_formspec(player,
 | 
			
		||||
	if fields.next_category then
 | 
			
		||||
		local scroll = math.min(#unified_inventory.category_list-ui_peruser.pagecols, unified_inventory.current_category_scroll[player_name] + 1)
 | 
			
		||||
		if scroll ~= unified_inventory.current_category_scroll[player_name] then
 | 
			
		||||
			unified_inventory.current_category_scroll[player_name] = scroll
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
					unified_inventory.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	if fields.prev_category then
 | 
			
		||||
		local scroll = math.max(0, unified_inventory.current_category_scroll[player_name] - 1)
 | 
			
		||||
		if scroll ~= unified_inventory.current_category_scroll[player_name] then
 | 
			
		||||
			unified_inventory.current_category_scroll[player_name] = scroll
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
					unified_inventory.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
@@ -131,7 +108,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
	for i, def in pairs(unified_inventory.buttons) do
 | 
			
		||||
		if fields[def.name] then
 | 
			
		||||
			def.action(player)
 | 
			
		||||
			minetest.sound_play("ui_click",
 | 
			
		||||
			minetest.sound_play("click",
 | 
			
		||||
					{to_player=player_name, gain = 0.1})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
@@ -196,7 +173,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	if clicked_item then
 | 
			
		||||
		minetest.sound_play("ui_click",
 | 
			
		||||
		minetest.sound_play("click",
 | 
			
		||||
				{to_player=player_name, gain = 0.1})
 | 
			
		||||
		local page = unified_inventory.current_page[player_name]
 | 
			
		||||
		local player_creative = unified_inventory.is_creative(player_name)
 | 
			
		||||
@@ -218,11 +195,22 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if fields.searchbutton
 | 
			
		||||
			or fields.key_enter_field == "searchbox" then
 | 
			
		||||
		unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange")
 | 
			
		||||
		unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
				unified_inventory.current_page[player_name])
 | 
			
		||||
		minetest.sound_play("paperflip2",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
	elseif fields.searchresetbutton then
 | 
			
		||||
		apply_new_filter(player, "", "nochange")
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- alternate buttons
 | 
			
		||||
	if not (fields.alternate or fields.alternate_prev) then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	minetest.sound_play("ui_click",
 | 
			
		||||
	minetest.sound_play("click",
 | 
			
		||||
			{to_player=player_name, gain = 0.1})
 | 
			
		||||
	local item_name = unified_inventory.current_item[player_name]
 | 
			
		||||
	if not item_name then
 | 
			
		||||
@@ -253,8 +241,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
			unified_inventory.current_page[player_name])
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	minetest.remove_detached_inventory(player_name.."_bags")
 | 
			
		||||
	minetest.remove_detached_inventory(player_name.."refill")
 | 
			
		||||
end)
 | 
			
		||||
if minetest.delete_detached_inventory then
 | 
			
		||||
	minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		minetest.delete_detached_inventory(player_name.."_bags")
 | 
			
		||||
		minetest.delete_detached_inventory(player_name.."craftrecipe")
 | 
			
		||||
		minetest.delete_detached_inventory(player_name.."refill")
 | 
			
		||||
	end)
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -96,9 +96,6 @@ function unified_inventory.register_category(category_name, config)
 | 
			
		||||
	end
 | 
			
		||||
	update_category_list()
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- TODO: Mark these for removal. They are pretty much useless
 | 
			
		||||
 | 
			
		||||
function unified_inventory.set_category_symbol(category_name, symbol)
 | 
			
		||||
	ensure_category_exists(category_name)
 | 
			
		||||
	unified_inventory.registered_categories[category_name].symbol = symbol
 | 
			
		||||
@@ -115,11 +112,6 @@ function unified_inventory.set_category_index(category_name, index)
 | 
			
		||||
	update_category_list()
 | 
			
		||||
end
 | 
			
		||||
function unified_inventory.add_category_item(category_name, item)
 | 
			
		||||
	if type(item) ~= "string" then
 | 
			
		||||
		minetest.log("warning", "[unified_inventory] Cannot register category item: " .. dump(item))
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	ensure_category_exists(category_name)
 | 
			
		||||
	unified_inventory.registered_category_items[category_name][item] = true
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_category('plants', {
 | 
			
		||||
	symbol = "flowers:tulip",
 | 
			
		||||
@@ -26,87 +25,71 @@ unified_inventory.register_category('lighting', {
 | 
			
		||||
	label = S("Lighting")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
local function register_automatic_categorization()
 | 
			
		||||
	-- Add biome nodes to environment category
 | 
			
		||||
	for _,def in pairs(minetest.registered_biomes) do
 | 
			
		||||
		local env_nodes = {
 | 
			
		||||
			def.node_riverbed, def.node_top, def.node_filler, def.node_dust,
 | 
			
		||||
		}
 | 
			
		||||
		for i,node in pairs(env_nodes) do
 | 
			
		||||
			if node then
 | 
			
		||||
				unified_inventory.add_category_item('environment', node)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Preparation for ore registration: find all possible drops (digging)
 | 
			
		||||
	local possible_node_dig_drops = {
 | 
			
		||||
		-- ["default:stone_with_coal"] = { "default:coal_lump", "mymod:raregem" }
 | 
			
		||||
		-- Ores may be contained multiple times, depending on drop chances.
 | 
			
		||||
	}
 | 
			
		||||
	for itemname, recipes in pairs(ui.crafts_for.usage) do
 | 
			
		||||
		for _, recipe in ipairs(recipes) do
 | 
			
		||||
			if recipe.type == "digging" or recipe.type == "digging_chance" then
 | 
			
		||||
				if not possible_node_dig_drops[itemname] then
 | 
			
		||||
					possible_node_dig_drops[itemname] = {}
 | 
			
		||||
if unified_inventory.automatic_categorization then
 | 
			
		||||
	minetest.register_on_mods_loaded(function()
 | 
			
		||||
 | 
			
		||||
		-- Add biome nodes to environment category
 | 
			
		||||
		for _,def in pairs(minetest.registered_biomes) do
 | 
			
		||||
			local env_nodes = {
 | 
			
		||||
				def.node_riverbed, def.node_top, def.node_filler, def.node_dust,
 | 
			
		||||
			}
 | 
			
		||||
			for i,node in pairs(env_nodes) do
 | 
			
		||||
				if node then
 | 
			
		||||
					unified_inventory.add_category_item('environment', node)
 | 
			
		||||
				end
 | 
			
		||||
				local stack = ItemStack(recipe.output)
 | 
			
		||||
				table.insert(possible_node_dig_drops[itemname], stack:get_name())
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment
 | 
			
		||||
	for _, odef in pairs(minetest.registered_ores) do
 | 
			
		||||
		local drops = possible_node_dig_drops[odef.ore]
 | 
			
		||||
		if drops and odef.ore_type == "scatter" then
 | 
			
		||||
			ui.add_category_item('minerals', odef.ore)
 | 
			
		||||
			-- Register all possible drops as "minerals"
 | 
			
		||||
			ui.add_category_items('minerals', drops)
 | 
			
		||||
			possible_node_dig_drops[odef.ore] = {} -- mask as handled
 | 
			
		||||
		else
 | 
			
		||||
			ui.add_category_item('environment', odef.ore)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Add items by item definition
 | 
			
		||||
	for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
		local group = def.groups or {}
 | 
			
		||||
		if not group.not_in_creative_inventory then
 | 
			
		||||
			if group.stair or
 | 
			
		||||
			   group.slab or
 | 
			
		||||
			   group.wall or
 | 
			
		||||
			   group.fence then
 | 
			
		||||
				unified_inventory.add_category_item('building', name)
 | 
			
		||||
			elseif group.flora or
 | 
			
		||||
				   group.flower or
 | 
			
		||||
				   group.seed or
 | 
			
		||||
				   group.leaves or
 | 
			
		||||
				   group.sapling or
 | 
			
		||||
				   group.tree then
 | 
			
		||||
				unified_inventory.add_category_item('plants', name)
 | 
			
		||||
			elseif def.type == 'tool' then
 | 
			
		||||
				unified_inventory.add_category_item('tools', name)
 | 
			
		||||
			elseif def.liquidtype == 'source' then
 | 
			
		||||
				unified_inventory.add_category_item('environment', name)
 | 
			
		||||
			elseif def.light_source and def.light_source > 0 then
 | 
			
		||||
				unified_inventory.add_category_item('lighting', name)
 | 
			
		||||
			elseif group.door or
 | 
			
		||||
				   minetest.global_exists("doors") and (
 | 
			
		||||
					 doors.registered_doors and doors.registered_doors[name..'_a'] or
 | 
			
		||||
					 doors.registered_trapdoors and doors.registered_trapdoors[name]
 | 
			
		||||
				   ) then
 | 
			
		||||
				unified_inventory.add_category_item('building', name)
 | 
			
		||||
		-- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment
 | 
			
		||||
		for _,item in  pairs(minetest.registered_ores) do
 | 
			
		||||
			if item.ore_type == "scatter" then
 | 
			
		||||
				local drop = minetest.registered_nodes[item.ore].drop
 | 
			
		||||
				if drop and drop ~= "" then
 | 
			
		||||
					unified_inventory.add_category_item('minerals', item.ore)
 | 
			
		||||
					unified_inventory.add_category_item('minerals', drop)
 | 
			
		||||
				else
 | 
			
		||||
					unified_inventory.add_category_item('environment', item.ore)
 | 
			
		||||
				end
 | 
			
		||||
			else
 | 
			
		||||
				unified_inventory.add_category_item('environment', item.ore)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
if ui.automatic_categorization then
 | 
			
		||||
	ui.register_on_initialized(register_automatic_categorization)
 | 
			
		||||
		-- Add items by item definition
 | 
			
		||||
		for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
			local group = def.groups or {}
 | 
			
		||||
			if not group.not_in_creative_inventory then
 | 
			
		||||
				if group.stair or
 | 
			
		||||
				   group.slab or
 | 
			
		||||
				   group.wall or
 | 
			
		||||
				   group.fence then
 | 
			
		||||
					unified_inventory.add_category_item('building', name)
 | 
			
		||||
				elseif group.flora or
 | 
			
		||||
					   group.flower or
 | 
			
		||||
					   group.seed or
 | 
			
		||||
					   group.leaves or
 | 
			
		||||
					   group.sapling or
 | 
			
		||||
					   group.tree then
 | 
			
		||||
					unified_inventory.add_category_item('plants', name)
 | 
			
		||||
				elseif def.type == 'tool' then
 | 
			
		||||
					unified_inventory.add_category_item('tools', name)
 | 
			
		||||
				elseif def.liquidtype == 'source' then
 | 
			
		||||
					unified_inventory.add_category_item('environment', name)
 | 
			
		||||
				elseif def.light_source and def.light_source > 0 then
 | 
			
		||||
					unified_inventory.add_category_item('lighting', name)
 | 
			
		||||
				elseif group.door or
 | 
			
		||||
					   minetest.global_exists("doors") and (
 | 
			
		||||
					     doors.registered_doors and doors.registered_doors[name..'_a'] or
 | 
			
		||||
					     doors.registered_trapdoors and doors.registered_trapdoors[name]
 | 
			
		||||
					   ) then
 | 
			
		||||
					unified_inventory.add_category_item('building', name)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- [[
 | 
			
		||||
unified_inventory.add_category_items('plants', {
 | 
			
		||||
	"default:dry_grass_5",
 | 
			
		||||
@@ -273,6 +256,23 @@ unified_inventory.add_category_items('minerals', {
 | 
			
		||||
	"default:coal_lump",
 | 
			
		||||
	"default:bronzeblock",
 | 
			
		||||
	"default:goldblock",
 | 
			
		||||
 | 
			
		||||
	"stairs:slab_bronzeblock",
 | 
			
		||||
	"stairs:slab_copperblock",
 | 
			
		||||
	"stairs:slab_steelblock",
 | 
			
		||||
	"stairs:slab_tinblock",
 | 
			
		||||
	"stairs:stair_bronzeblock",
 | 
			
		||||
	"stairs:stair_copperblock",
 | 
			
		||||
	"stairs:stair_inner_bronzeblock",
 | 
			
		||||
	"stairs:stair_inner_copperblock",
 | 
			
		||||
	"stairs:stair_inner_steelblock",
 | 
			
		||||
	"stairs:stair_inner_tinblock",
 | 
			
		||||
	"stairs:stair_outer_bronzeblock",
 | 
			
		||||
	"stairs:stair_outer_copperblock",
 | 
			
		||||
	"stairs:stair_outer_steelblock",
 | 
			
		||||
	"stairs:stair_outer_tinblock",
 | 
			
		||||
	"stairs:stair_steelblock",
 | 
			
		||||
	"stairs:stair_tinblock",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.add_category_items('building', {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
unified_inventory API
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
This file provides information about the API of unified_inventory
 | 
			
		||||
and can be viewed in Markdown readers.
 | 
			
		||||
This file provides information about the API of unified_inventory.
 | 
			
		||||
 | 
			
		||||
API revisions within unified_inventory can be checked using:
 | 
			
		||||
 | 
			
		||||
@@ -24,9 +23,7 @@ Grouped by use-case, afterwards sorted alphabetically.
 | 
			
		||||
Callbacks
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft.
 | 
			
		||||
This callback is run before any recipe ingredients checks, hence it is also executed on recipes that are
 | 
			
		||||
purged after all mods finished loading.
 | 
			
		||||
Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.register_on_craft_registered(
 | 
			
		||||
		function (item_name, options)
 | 
			
		||||
@@ -166,57 +163,68 @@ Register a non-standard craft recipe:
 | 
			
		||||
Categories
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
 * `unified_inventory.register_category(name, def)`
 | 
			
		||||
     * Registers a new category
 | 
			
		||||
     * `name` (string): internal category name
 | 
			
		||||
     * `def` (optional, table): also its fields are optional
 | 
			
		||||
Register a new category:
 | 
			
		||||
	The config table (second argument) is optional, and all its members are optional
 | 
			
		||||
	See the unified_inventory.set_category_* functions for more details on the members of the config table
 | 
			
		||||
 | 
			
		||||
	unified_inventory.register_category("category_name", {
 | 
			
		||||
		symbol = source,
 | 
			
		||||
		-- ^ Can be in the format "mod_name:item_name" or "texture.png",
 | 
			
		||||
		symbol = "mod_name:item_name" or "texture.png",
 | 
			
		||||
		label = "Human Readable Label",
 | 
			
		||||
		index = 5,
 | 
			
		||||
		-- ^ Categories are sorted by index. Lower numbers appear before higher ones.
 | 
			
		||||
		--   By default, the name is translated to a number: AA -> 0.0101, ZZ -> 0.2626
 | 
			
		||||
		---  Predefined category indices: "all" = -2, "uncategorized" = -1
 | 
			
		||||
		items = {
 | 
			
		||||
			"mod_name:item_name",
 | 
			
		||||
			"another_mod:different_item"
 | 
			
		||||
		}
 | 
			
		||||
		-- ^ List of items within this category
 | 
			
		||||
	})
 | 
			
		||||
 * `unified_inventory.remove_category(name)`
 | 
			
		||||
     * Removes an entire category
 | 
			
		||||
 | 
			
		||||
Modifier functions (to be removed)
 | 
			
		||||
Add / override the symbol for a category:
 | 
			
		||||
	The category does not need to exist first
 | 
			
		||||
	The symbol can be an item name or a texture image
 | 
			
		||||
	If unset this will default to "default:stick"
 | 
			
		||||
 | 
			
		||||
 * `unified_inventory.set_category_symbol(name, source)`
 | 
			
		||||
     * Changes the symbol of the category. The category does not need to exist yet.
 | 
			
		||||
     * `name` (string): internal category name
 | 
			
		||||
     * `source` (string, optional): `"mod_name:item_name"` or `"texture.png"`.
 | 
			
		||||
       Defaults to `"default:stick"` if not specified.
 | 
			
		||||
 * `unified_inventory.set_category_label(name, label)`
 | 
			
		||||
     * Changes the human readable label of the category.
 | 
			
		||||
     * `name` (string): internal category name
 | 
			
		||||
     * `label` (string): human readable label. Defaults to the category name.
 | 
			
		||||
 * `unified_inventory.set_category_index(name, index)`
 | 
			
		||||
     * Changes the sorting index of the category.
 | 
			
		||||
     * `name` (string): internal category name
 | 
			
		||||
     * `index` (numeric): any real number
 | 
			
		||||
	unified_inventory.set_category_symbol("category_name", "mod_name:item_name" or "texture.png")
 | 
			
		||||
 | 
			
		||||
Item management
 | 
			
		||||
Add / override the human readable label for a category:
 | 
			
		||||
	If unset this will default to the category name
 | 
			
		||||
 | 
			
		||||
 * `	unified_inventory.add_category_item(name, itemname)`
 | 
			
		||||
     * Adds a single item to the category
 | 
			
		||||
     * `itemname` (string): self-explanatory
 | 
			
		||||
 * `unified_inventory.add_category_items(name, { itemname1, itemname2, ... }`
 | 
			
		||||
     * Same as above but with multiple items
 | 
			
		||||
 * `unified_inventory.remove_category_item(name, itemname)`
 | 
			
		||||
     * Removes an item from the category
 | 
			
		||||
 * `unified_inventory.find_category(itemname)`
 | 
			
		||||
     * Looks up the first category containing this item
 | 
			
		||||
     * Returns: category name (string) or nil
 | 
			
		||||
 * `unified_inventory.find_categories(itemname)`
 | 
			
		||||
     * Looks up the item name within all registered categories
 | 
			
		||||
     * Returns: array of category names (table)
 | 
			
		||||
	unified_inventory.set_category_label("category_name", "Human Readable Label")
 | 
			
		||||
 | 
			
		||||
Add / override the sorting index of the category:
 | 
			
		||||
	Must be a number, can also be negative (-5) or fractional (2.345)
 | 
			
		||||
	This determines the position the category appears in the list of categories
 | 
			
		||||
	The "all" meta-category has index -2, the "misc"/"uncategorized" meta-category has index -1, use a negative number smaller than these to make a category appear before these in the list
 | 
			
		||||
	By default categories are sorted alphabetically with an index between 0.0101(AA) and 0.2626(ZZ)
 | 
			
		||||
 | 
			
		||||
	unified_inventory.set_category_index("category_name", 5)
 | 
			
		||||
 | 
			
		||||
Add a single item to a category:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.add_category_item("category_name", "mod_name:item_name")
 | 
			
		||||
 | 
			
		||||
Add multiple items to a category:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.add_category_items("category_name", {
 | 
			
		||||
		"mod_name:item_name",
 | 
			
		||||
		"another_mod:different_item"
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
Remove an item from a category:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.remove_category_item("category_name", "mod_name:item_name")
 | 
			
		||||
 | 
			
		||||
Remove a category entirely:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.remove_category("category_name")
 | 
			
		||||
 | 
			
		||||
Finding existing items in categories:
 | 
			
		||||
	This will find the first category an item exists in
 | 
			
		||||
	It should be used for checking if an item is catgorised
 | 
			
		||||
	Returns "category_name" or nil
 | 
			
		||||
 | 
			
		||||
	unified_inventory.find_category("mod_name:item_name")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	This will find all the categories an item exists in
 | 
			
		||||
	Returns a number indexed table (list) of category names
 | 
			
		||||
 | 
			
		||||
	unified_inventory.find_categories("mod_name:item_name")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								group.lua
									
									
									
									
									
								
							
							
						
						@@ -1,5 +1,29 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
function unified_inventory.canonical_item_spec_matcher(spec)
 | 
			
		||||
	local specname = ItemStack(spec):get_name()
 | 
			
		||||
	if specname:sub(1, 6) ~= "group:" then
 | 
			
		||||
		return function (itemname)
 | 
			
		||||
			return itemname == specname
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local group_names = specname:sub(7):split(",")
 | 
			
		||||
	return function (itemname)
 | 
			
		||||
		local itemdef = minetest.registered_items[itemname]
 | 
			
		||||
		for _, group_name in ipairs(group_names) do
 | 
			
		||||
			if (itemdef.groups[group_name] or 0) == 0 then
 | 
			
		||||
				return false
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		return true
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.item_matches_spec(item, spec)
 | 
			
		||||
	local itemname = ItemStack(item):get_name()
 | 
			
		||||
	return unified_inventory.canonical_item_spec_matcher(spec)(itemname)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.extract_groupnames(groupname)
 | 
			
		||||
	local specname = ItemStack(groupname):get_name()
 | 
			
		||||
@@ -10,6 +34,22 @@ function unified_inventory.extract_groupnames(groupname)
 | 
			
		||||
	return table.concat(group_names, S(" and ")), #group_names
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
unified_inventory.registered_group_items = {
 | 
			
		||||
	mesecon_conductor_craftable = "mesecons:wire_00000000_off",
 | 
			
		||||
	stone = "default:cobble",
 | 
			
		||||
	wood = "default:wood",
 | 
			
		||||
	book = "default:book",
 | 
			
		||||
	sand = "default:sand",
 | 
			
		||||
	leaves = "default:leaves",
 | 
			
		||||
	tree = "default:tree",
 | 
			
		||||
	vessel = "vessels:glass_bottle",
 | 
			
		||||
	wool = "wool:white",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_group_item(groupname, itemname)
 | 
			
		||||
	unified_inventory.registered_group_items[groupname] = itemname
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- This is used when displaying craft recipes, where an ingredient is
 | 
			
		||||
-- specified by group rather than as a specific item.  A single-item group
 | 
			
		||||
@@ -27,7 +67,6 @@ end
 | 
			
		||||
-- It may be a comma-separated list of group names.  This is really a
 | 
			
		||||
-- "group:..." ingredient specification, minus the "group:" prefix.
 | 
			
		||||
 | 
			
		||||
-- TODO Replace this with the more efficient spec matcher (below)
 | 
			
		||||
local function compute_group_item(group_name_list)
 | 
			
		||||
	local group_names = group_name_list:split(",")
 | 
			
		||||
	local candidate_items = {}
 | 
			
		||||
@@ -86,61 +125,3 @@ function unified_inventory.get_group_item(group_name)
 | 
			
		||||
	return group_item_cache[group_name]
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
This is for filtering known items by groups
 | 
			
		||||
e.g. find all items that match "group:flower,yellow" (flower AND yellow groups)
 | 
			
		||||
]]
 | 
			
		||||
local spec_matcher = {}
 | 
			
		||||
function unified_inventory.init_matching_cache()
 | 
			
		||||
	for _, name in ipairs(ui.items_list) do
 | 
			
		||||
		-- we only need to care about groups, exact items are handled separately
 | 
			
		||||
		for group, value in pairs(minetest.registered_items[name].groups) do
 | 
			
		||||
			if value and value ~= 0 then
 | 
			
		||||
				if not spec_matcher[group] then
 | 
			
		||||
					spec_matcher[group] = {}
 | 
			
		||||
				end
 | 
			
		||||
				spec_matcher[group][name] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Retrieves all matching items
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	specname (string): Item name or group(s) to filter
 | 
			
		||||
 | 
			
		||||
Output:
 | 
			
		||||
	{
 | 
			
		||||
		matchingitem1 = true,
 | 
			
		||||
		...
 | 
			
		||||
	}
 | 
			
		||||
]]
 | 
			
		||||
function unified_inventory.get_matching_items(specname)
 | 
			
		||||
	if specname:sub(1,6) ~= "group:" then
 | 
			
		||||
		return { [specname] = true }
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local accepted = {}
 | 
			
		||||
	for i, group in ipairs(specname:sub(7):split(",")) do
 | 
			
		||||
		if i == 1 then
 | 
			
		||||
			-- First step: Copy all possible item names in this group
 | 
			
		||||
			for name, _ in pairs(spec_matcher[group] or {}) do
 | 
			
		||||
				accepted[name] = true
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			-- Perform filtering
 | 
			
		||||
			if spec_matcher[group] then
 | 
			
		||||
				for name, _ in pairs(accepted) do
 | 
			
		||||
					accepted[name] = spec_matcher[group][name]
 | 
			
		||||
				end
 | 
			
		||||
			else
 | 
			
		||||
				-- No matching items
 | 
			
		||||
				return {}
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return accepted
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						@@ -1,11 +1,5 @@
 | 
			
		||||
-- Unified Inventory
 | 
			
		||||
 | 
			
		||||
if not minetest.features.formspec_version_element then
 | 
			
		||||
	-- At least formspec_version[] is the minimal feature requirement
 | 
			
		||||
	error("Unified Inventory requires Minetest version 5.4.0 or newer.\n" ..
 | 
			
		||||
		" Please update Minetest or use an older version of Unified Inventory.")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
 | 
			
		||||
local worldpath = minetest.get_worldpath()
 | 
			
		||||
 | 
			
		||||
@@ -50,12 +44,9 @@ unified_inventory = {
 | 
			
		||||
	trash_enabled = (minetest.settings:get_bool("unified_inventory_trash") ~= false),
 | 
			
		||||
	imgscale = 1.25,
 | 
			
		||||
	list_img_offset = 0.13,
 | 
			
		||||
	standard_background = "bgcolor[#0000]background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]",
 | 
			
		||||
	standard_background = "background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]",
 | 
			
		||||
 | 
			
		||||
	hide_disabled_buttons = minetest.settings:get_bool("unified_inventory_hide_disabled_buttons", false),
 | 
			
		||||
	hide_uncraftable_items = minetest.settings:get_bool("unified_inventory_hide_uncraftable_items", false),
 | 
			
		||||
 | 
			
		||||
	version = 5
 | 
			
		||||
	version = 3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
@@ -68,16 +59,10 @@ ui.style_full = {
 | 
			
		||||
	formspec_y = 1,
 | 
			
		||||
	formw = 17.75,
 | 
			
		||||
	formh = 12.25,
 | 
			
		||||
	-- Item browser size, pos
 | 
			
		||||
	pagecols = 8,
 | 
			
		||||
	pagerows = 9,
 | 
			
		||||
	page_x = 10.75,
 | 
			
		||||
	page_y = 2.30,
 | 
			
		||||
	-- Item browser controls
 | 
			
		||||
	page_buttons_x = 11.60,
 | 
			
		||||
	page_buttons_y = 10.15,
 | 
			
		||||
	searchwidth = 3.4,
 | 
			
		||||
	-- Crafting grid positions
 | 
			
		||||
	craft_x = 2.8,
 | 
			
		||||
	craft_y = 1.15,
 | 
			
		||||
	craftresult_x = 7.8,
 | 
			
		||||
@@ -89,15 +74,13 @@ ui.style_full = {
 | 
			
		||||
	craft_guide_resultstr_x = 0.3,
 | 
			
		||||
	craft_guide_resultstr_y = 0.6,
 | 
			
		||||
	give_btn_x = 0.25,
 | 
			
		||||
	-- Tab switching buttons
 | 
			
		||||
	main_button_x = 0.4,
 | 
			
		||||
	main_button_y = 11.0,
 | 
			
		||||
	main_button_cols = 12,
 | 
			
		||||
	main_button_rows = 1,
 | 
			
		||||
	-- Tab title position
 | 
			
		||||
	page_buttons_x = 11.60,
 | 
			
		||||
	page_buttons_y = 10.15,
 | 
			
		||||
	searchwidth = 3.4,
 | 
			
		||||
	form_header_x = 0.4,
 | 
			
		||||
	form_header_y = 0.4,
 | 
			
		||||
	-- Generic sizes
 | 
			
		||||
	btn_spc = 0.85,
 | 
			
		||||
	btn_size = 0.75,
 | 
			
		||||
	std_inv_x = 0.3,
 | 
			
		||||
@@ -109,16 +92,10 @@ ui.style_lite = {
 | 
			
		||||
	formspec_y =  0.6,
 | 
			
		||||
	formw = 14,
 | 
			
		||||
	formh = 9.75,
 | 
			
		||||
	-- Item browser size, pos
 | 
			
		||||
	pagecols = 4,
 | 
			
		||||
	pagerows = 5,
 | 
			
		||||
	page_x = 10.5,
 | 
			
		||||
	page_y = 2.15,
 | 
			
		||||
	-- Item browser controls
 | 
			
		||||
	page_buttons_x = 10.5,
 | 
			
		||||
	page_buttons_y = 6.15,
 | 
			
		||||
	searchwidth = 1.6,
 | 
			
		||||
	-- Crafting grid positions
 | 
			
		||||
	craft_x = 2.6,
 | 
			
		||||
	craft_y = 0.75,
 | 
			
		||||
	craftresult_x = 5.75,
 | 
			
		||||
@@ -130,15 +107,13 @@ ui.style_lite = {
 | 
			
		||||
	craft_guide_resultstr_x = 0.15,
 | 
			
		||||
	craft_guide_resultstr_y = 0.35,
 | 
			
		||||
	give_btn_x = 0.15,
 | 
			
		||||
	-- Tab switching buttons
 | 
			
		||||
	main_button_x = 10.5,
 | 
			
		||||
	main_button_y = 8.15,
 | 
			
		||||
	main_button_cols = 4,
 | 
			
		||||
	main_button_rows = 2,
 | 
			
		||||
	-- Tab title position
 | 
			
		||||
	page_buttons_x = 10.5,
 | 
			
		||||
	page_buttons_y = 6.15,
 | 
			
		||||
	searchwidth = 1.6,
 | 
			
		||||
	form_header_x =  0.2,
 | 
			
		||||
	form_header_y =  0.2,
 | 
			
		||||
	-- Generic sizes
 | 
			
		||||
	btn_spc = 0.8,
 | 
			
		||||
	btn_size = 0.7,
 | 
			
		||||
	std_inv_x = 0.1,
 | 
			
		||||
@@ -192,10 +167,7 @@ dofile(modpath.."/register.lua")
 | 
			
		||||
if minetest.settings:get_bool("unified_inventory_bags") ~= false then
 | 
			
		||||
	dofile(modpath.."/bags.lua")
 | 
			
		||||
end
 | 
			
		||||
if minetest.settings:get_bool("unified_inventory_item_names") ~= false then
 | 
			
		||||
	dofile(modpath.."/item_names.lua")
 | 
			
		||||
end
 | 
			
		||||
if minetest.settings:get_bool("unified_inventory_waypoints") ~= false then
 | 
			
		||||
	dofile(modpath.."/waypoints.lua")
 | 
			
		||||
end
 | 
			
		||||
dofile(modpath.."/legacy.lua") -- mod compatibility
 | 
			
		||||
 | 
			
		||||
dofile(modpath.."/item_names.lua")
 | 
			
		||||
dofile(modpath.."/waypoints.lua")
 | 
			
		||||
minetest.log("action", "[unified_inventory] loaded.")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										172
									
								
								internal.lua
									
									
									
									
									
								
							
							
						
						@@ -18,7 +18,7 @@ function ui.demangle_for_formspec(str)
 | 
			
		||||
	return string.gsub(str, "_([0-9]+)_", function (v) return string.char(v) end)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Get the player-specific unified_inventory style
 | 
			
		||||
 | 
			
		||||
function ui.get_per_player_formspec(player_name)
 | 
			
		||||
	local draw_lite_mode = ui.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true})
 | 
			
		||||
 | 
			
		||||
@@ -27,7 +27,6 @@ function ui.get_per_player_formspec(player_name)
 | 
			
		||||
	return style
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Creates an item image or regular image button with a tooltip
 | 
			
		||||
local function formspec_button(ui_peruser, name, image, offset, pos, scale, label)
 | 
			
		||||
	local element = 'image_button'
 | 
			
		||||
	if minetest.registered_items[image] then
 | 
			
		||||
@@ -44,68 +43,52 @@ local function formspec_button(ui_peruser, name, image, offset, pos, scale, labe
 | 
			
		||||
		string.format("tooltip[%s;%s]", name, F(label or name))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Add registered buttons (tabs)
 | 
			
		||||
local function formspec_tab_buttons(player, formspec, style)
 | 
			
		||||
local function formspec_add_filters(player, formspec, style)
 | 
			
		||||
	local button_row = 0
 | 
			
		||||
	local button_col = 0
 | 
			
		||||
	local n = #formspec + 1
 | 
			
		||||
 | 
			
		||||
	-- Main buttons
 | 
			
		||||
 | 
			
		||||
	local filtered_inv_buttons = {}
 | 
			
		||||
 | 
			
		||||
	for _, def in pairs(ui.buttons) do
 | 
			
		||||
	for i, def in pairs(ui.buttons) do
 | 
			
		||||
		if not (style.is_lite_mode and def.hide_lite) then
 | 
			
		||||
			if def.condition == nil or def.condition(player) or not ui.hide_disabled_buttons then
 | 
			
		||||
				table.insert(filtered_inv_buttons, def)
 | 
			
		||||
			end
 | 
			
		||||
			table.insert(filtered_inv_buttons, def)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local needs_scrollbar = #filtered_inv_buttons > style.main_button_cols * style.main_button_rows
 | 
			
		||||
 | 
			
		||||
	formspec[n] = ("scroll_container[%g,%g;%g,%g;tabbtnscroll;vertical]"):format(
 | 
			
		||||
		style.main_button_x, style.main_button_y, -- position
 | 
			
		||||
		style.main_button_cols * style.btn_spc, style.main_button_rows -- size
 | 
			
		||||
	)
 | 
			
		||||
	n = n + 1
 | 
			
		||||
 | 
			
		||||
	local j = 1 --Modif NALC (sys4 20/11/2018) 12 buttons max by row
 | 
			
		||||
	for i, def in pairs(filtered_inv_buttons) do
 | 
			
		||||
		local pos_x =           ((i - 1) % style.main_button_cols) * style.btn_spc
 | 
			
		||||
		local pos_y = math.floor((i - 1) / style.main_button_cols) * style.btn_spc
 | 
			
		||||
		if style.is_lite_mode and i > 4 then
 | 
			
		||||
			button_row = 1
 | 
			
		||||
			button_col = 1
 | 
			
		||||
		elseif not draw_lite_mode and j > 12 then
 | 
			
		||||
			button_row = 1
 | 
			
		||||
			j = 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if def.type == "image" then
 | 
			
		||||
			if (def.condition == nil or def.condition(player)) then
 | 
			
		||||
				formspec[n] = string.format("image_button[%g,%g;%g,%g;%s;%s;]",
 | 
			
		||||
			local pos_x = style.main_button_x + style.btn_spc * (j - 1) - button_col * style.btn_spc * 4
 | 
			
		||||
			local pos_y = style.main_button_y + button_row * style.btn_spc
 | 
			
		||||
			if (def.condition == nil or def.condition(player) == true) then
 | 
			
		||||
				formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]",
 | 
			
		||||
					pos_x, pos_y, style.btn_size, style.btn_size,
 | 
			
		||||
					F(def.image),
 | 
			
		||||
					F(def.name))
 | 
			
		||||
				formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]"
 | 
			
		||||
				n = n+2
 | 
			
		||||
 | 
			
		||||
			else
 | 
			
		||||
				formspec[n] = string.format("image[%g,%g;%g,%g;%s^[colorize:#808080:alpha]",
 | 
			
		||||
				formspec[n] = string.format("image[%f,%f;%f,%f;%s^[colorize:#808080:alpha]",
 | 
			
		||||
					pos_x, pos_y, style.btn_size, style.btn_size,
 | 
			
		||||
					def.image)
 | 
			
		||||
				n = n+1
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	formspec[n] = "scroll_container_end[]"
 | 
			
		||||
	if needs_scrollbar then
 | 
			
		||||
		local total_rows = math.ceil(#filtered_inv_buttons / style.main_button_cols)
 | 
			
		||||
		formspec[n+1] = ("scrollbaroptions[max=%i;arrows=hide]"):format(
 | 
			
		||||
			-- This calculation is not 100% accurate but "good enough"
 | 
			
		||||
			(total_rows - style.main_button_rows) * style.btn_spc * 10
 | 
			
		||||
		)
 | 
			
		||||
		formspec[n+2] = ("scrollbar[%g,%g;0.4,%g;vertical;tabbtnscroll;0]"):format(
 | 
			
		||||
			style.main_button_x + style.main_button_cols * style.btn_spc - 0.1, -- x pos
 | 
			
		||||
			style.main_button_y, -- y pos
 | 
			
		||||
			style.main_button_rows * style.btn_spc -- height
 | 
			
		||||
		)
 | 
			
		||||
		formspec[n+3] = "scrollbaroptions[max=1000;arrows=default]"
 | 
			
		||||
		j = j + 1 -- Modif NALC
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Add category GUI elements (top right)
 | 
			
		||||
local function formspec_add_categories(player, formspec, ui_peruser)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local n = #formspec + 1
 | 
			
		||||
@@ -119,9 +102,9 @@ local function formspec_add_categories(player, formspec, ui_peruser)
 | 
			
		||||
		ui_peruser.form_header_y - (ui_peruser.is_lite_mode and 0 or 0.2)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;16]",
 | 
			
		||||
		ui_peruser.page_x-0.15, categories_scroll_pos[2],
 | 
			
		||||
		(ui_peruser.btn_spc * ui_peruser.pagecols) + 0.2, 1.4 + (ui_peruser.is_lite_mode and 0 or 0.2),
 | 
			
		||||
	formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;3]",
 | 
			
		||||
		ui_peruser.page_x-0.1, categories_scroll_pos[2],
 | 
			
		||||
		(ui_peruser.btn_spc * ui_peruser.pagecols) + 0.13, 1.4 + (ui_peruser.is_lite_mode and 0 or 0.2),
 | 
			
		||||
		"ui_smallbg_9_sliced.png")
 | 
			
		||||
	n = n + 1
 | 
			
		||||
 | 
			
		||||
@@ -143,21 +126,18 @@ local function formspec_add_categories(player, formspec, ui_peruser)
 | 
			
		||||
			if ui.current_category[player_name] == category.name then
 | 
			
		||||
				scale = 1
 | 
			
		||||
			end
 | 
			
		||||
			formspec[n] = formspec_button(ui_peruser, "category_"..category.name, category.symbol, categories_pos,
 | 
			
		||||
				{column-1, 0}, scale, category.label)
 | 
			
		||||
			formspec[n] = formspec_button(ui_peruser, "category_"..category.name, category.symbol, categories_pos, {column-1, 0}, scale, category.label)
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	if category_count > ui_peruser.pagecols and scroll_offset > 0 then
 | 
			
		||||
		-- prev
 | 
			
		||||
		formspec[n] = formspec_button(ui_peruser, "prev_category", "ui_left_icon.png", categories_scroll_pos,
 | 
			
		||||
			{ui_peruser.pagecols - 2, 0}, 0.8, S("Scroll categories left"))
 | 
			
		||||
		formspec[n] = formspec_button(ui_peruser, "prev_category", "ui_left_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 2, 0}, 0.8, S("Scroll categories left"))
 | 
			
		||||
		n = n + 1
 | 
			
		||||
	end
 | 
			
		||||
	if category_count > ui_peruser.pagecols and category_count - scroll_offset > ui_peruser.pagecols then
 | 
			
		||||
		-- next
 | 
			
		||||
		formspec[n] = formspec_button(ui_peruser, "next_category", "ui_right_icon.png", categories_scroll_pos,
 | 
			
		||||
			{ui_peruser.pagecols - 1, 0}, 0.8, S("Scroll categories right"))
 | 
			
		||||
		formspec[n] = formspec_button(ui_peruser, "next_category", "ui_right_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 1, 0}, 0.8, S("Scroll categories right"))
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -263,25 +243,17 @@ local function formspec_add_item_browser(player, formspec, ui_peruser)
 | 
			
		||||
					ui_peruser.btn_size, ui_peruser.btn_size,
 | 
			
		||||
					name, button_name
 | 
			
		||||
				)
 | 
			
		||||
				local tooltip = item.description
 | 
			
		||||
				if item.mod_origin then
 | 
			
		||||
					-- "mod_origin" may not be specified for items that were
 | 
			
		||||
					-- registered in a callback (during or before ServerEnv init)
 | 
			
		||||
					tooltip = tooltip .. " [" .. item.mod_origin .. "]"
 | 
			
		||||
				end
 | 
			
		||||
				formspec[n + 1] = ("tooltip[%s;%s]"):format(
 | 
			
		||||
					button_name, minetest.formspec_escape(tooltip)
 | 
			
		||||
					button_name, minetest.formspec_escape(item.description)
 | 
			
		||||
				)
 | 
			
		||||
				n = n + 2
 | 
			
		||||
				list_index = list_index + 1
 | 
			
		||||
			end
 | 
			
		||||
			list_index = list_index + 1
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	formspec[n] = "style[page_number;content_offset=0]"
 | 
			
		||||
	formspec[n + 1] = string.format("image_button[%f,%f;%f,0.4;;page_number;%s: %s;false;false;]",
 | 
			
		||||
		ui_peruser.page_buttons_x,
 | 
			
		||||
		ui_peruser.page_buttons_y + ui_peruser.btn_spc * 2 - 0.1,
 | 
			
		||||
		ui_peruser.btn_spc * (bn - 1) + ui_peruser.btn_size,
 | 
			
		||||
	formspec[n] = string.format("label[%f,%f;%s: %s]",
 | 
			
		||||
		ui_peruser.page_buttons_x + ui_peruser.btn_spc * (ui_peruser.is_lite_mode and 1 or 2),
 | 
			
		||||
		ui_peruser.page_buttons_y + 0.1 + ui_peruser.btn_spc * 2,
 | 
			
		||||
		F(S("Page")), S("@1 of @2",page2,pagemax))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -313,7 +285,7 @@ function ui.get_formspec(player, page)
 | 
			
		||||
 | 
			
		||||
	fs[#fs + 1] = fsdata.formspec
 | 
			
		||||
 | 
			
		||||
	formspec_tab_buttons(player, fs, ui_peruser)
 | 
			
		||||
	formspec_add_filters(player, fs, ui_peruser)
 | 
			
		||||
 | 
			
		||||
	if fsdata.draw_inventory ~= false then
 | 
			
		||||
		-- Player inventory
 | 
			
		||||
@@ -338,7 +310,7 @@ function ui.set_inventory_formspec(player, page)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function ui.is_itemdef_listable(def)
 | 
			
		||||
local function valid_def(def)
 | 
			
		||||
	return (not def.groups.not_in_creative_inventory
 | 
			
		||||
			or def.groups.not_in_creative_inventory == 0)
 | 
			
		||||
		and def.description
 | 
			
		||||
@@ -351,30 +323,11 @@ function ui.apply_filter(player, filter, search_dir)
 | 
			
		||||
		return false
 | 
			
		||||
	end
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	-- Whether to show uncraftable items
 | 
			
		||||
	local fprefilter = function(_)
 | 
			
		||||
		return true
 | 
			
		||||
	end
 | 
			
		||||
	if ui.hide_uncraftable_items and not ui.is_creative(player_name) then
 | 
			
		||||
		fprefilter = function(name)
 | 
			
		||||
			return ui.get_recipe_list(name)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local registered_items = minetest.registered_items
 | 
			
		||||
	local lfilter = string.lower(filter)
 | 
			
		||||
	local ffilter
 | 
			
		||||
 | 
			
		||||
	if lfilter:sub(1, 6) == "group:" then
 | 
			
		||||
		-- Group filter: all groups of the item must match
 | 
			
		||||
		local groups = lfilter:sub(7):split(",")
 | 
			
		||||
		ffilter = function(name)
 | 
			
		||||
			local def = registered_items[name]
 | 
			
		||||
			if not def then
 | 
			
		||||
				return false
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
		ffilter = function(name, def)
 | 
			
		||||
			for _, group in ipairs(groups) do
 | 
			
		||||
				if not def.groups[group]
 | 
			
		||||
				or def.groups[group] <= 0 then
 | 
			
		||||
@@ -384,16 +337,10 @@ function ui.apply_filter(player, filter, search_dir)
 | 
			
		||||
			return true
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		-- Name filter: fuzzy match item names and descriptions
 | 
			
		||||
		local player_info = minetest.get_player_information(player_name)
 | 
			
		||||
		local lang = player_info and player_info.lang_code or ""
 | 
			
		||||
 | 
			
		||||
		ffilter = function(name)
 | 
			
		||||
			local def = registered_items[name]
 | 
			
		||||
			if not def then
 | 
			
		||||
				return false
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
		ffilter = function(name, def)
 | 
			
		||||
			local lname = string.lower(name)
 | 
			
		||||
			local ldesc = string.lower(def.description)
 | 
			
		||||
			local llocaldesc = minetest.get_translated_string
 | 
			
		||||
@@ -402,50 +349,37 @@ function ui.apply_filter(player, filter, search_dir)
 | 
			
		||||
				or llocaldesc and string.find(llocaldesc, lfilter, 1, true)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local filtered_items = {}
 | 
			
		||||
 | 
			
		||||
	ui.filtered_items_list[player_name]={}
 | 
			
		||||
	local category = ui.current_category[player_name] or 'all'
 | 
			
		||||
	if category == 'all' then
 | 
			
		||||
		for _, name in ipairs(ui.items_list) do
 | 
			
		||||
			if fprefilter(name) and ffilter(name) then
 | 
			
		||||
				table.insert(filtered_items, name)
 | 
			
		||||
		for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
			if valid_def(def)
 | 
			
		||||
			and ffilter(name, def) then
 | 
			
		||||
				table.insert(ui.filtered_items_list[player_name], name)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	elseif category == 'uncategorized' then
 | 
			
		||||
		for _, name in ipairs(ui.items_list) do
 | 
			
		||||
			if not ui.find_category(name)
 | 
			
		||||
					and fprefilter(name)
 | 
			
		||||
					and ffilter(name) then
 | 
			
		||||
				table.insert(filtered_items, name)
 | 
			
		||||
		for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
			if (not ui.find_category(name))
 | 
			
		||||
			and valid_def(def)
 | 
			
		||||
			and ffilter(name, def) then
 | 
			
		||||
				table.insert(ui.filtered_items_list[player_name], name)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		-- Any other category is selected
 | 
			
		||||
		for name, exists in pairs(ui.registered_category_items[category]) do
 | 
			
		||||
			if exists
 | 
			
		||||
					and fprefilter(name)
 | 
			
		||||
					and ffilter(name) then
 | 
			
		||||
				table.insert(filtered_items, name)
 | 
			
		||||
		for name,exists in pairs(ui.registered_category_items[category]) do
 | 
			
		||||
			local def = minetest.registered_items[name]
 | 
			
		||||
			if exists and def
 | 
			
		||||
			and valid_def(def)
 | 
			
		||||
			and ffilter(name, def) then
 | 
			
		||||
				table.insert(ui.filtered_items_list[player_name], name)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	table.sort(filtered_items)
 | 
			
		||||
 | 
			
		||||
	ui.filtered_items_list_size[player_name] = #filtered_items
 | 
			
		||||
	ui.filtered_items_list[player_name] = filtered_items
 | 
			
		||||
	table.sort(ui.filtered_items_list[player_name])
 | 
			
		||||
	ui.filtered_items_list_size[player_name] = #ui.filtered_items_list[player_name]
 | 
			
		||||
	ui.current_index[player_name] = 1
 | 
			
		||||
	ui.activefilter[player_name] = filter
 | 
			
		||||
	ui.active_search_direction[player_name] = search_dir
 | 
			
		||||
	ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Inform players about potential visual issues
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local info = minetest.get_player_information(player_name)
 | 
			
		||||
	if info and (info.formspec_version or 0) < 4 then
 | 
			
		||||
		minetest.chat_send_player(player_name, S("Unified Inventory: Your game version is too old"
 | 
			
		||||
			.. " and does not support the GUI requirements. You might experience visual issues."))
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,6 @@
 | 
			
		||||
local item_names = {} -- [player_name] = { hud, dtime, itemname }
 | 
			
		||||
local dlimit = 3  -- HUD element will be hidden after this many seconds
 | 
			
		||||
local hudbars_mod = minetest.get_modpath("hudbars")
 | 
			
		||||
local only_names = minetest.settings:get_bool("unified_inventory_only_names", true)
 | 
			
		||||
local max_length = tonumber(minetest.settings:get("unified_inventory_max_item_name_length")) or 80
 | 
			
		||||
 | 
			
		||||
local function set_hud(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
@@ -18,8 +16,7 @@ local function set_hud(player)
 | 
			
		||||
 | 
			
		||||
	item_names[player_name] = {
 | 
			
		||||
		hud = player:hud_add({
 | 
			
		||||
			-- TODO: remove compatibility code when 5.8.0 is no longer used
 | 
			
		||||
			[minetest.features.hud_def_type_field and "type" or "hud_elem_type"] = "text",
 | 
			
		||||
			hud_elem_type = "text",
 | 
			
		||||
			position = {x=0.5, y=1},
 | 
			
		||||
			offset = off,
 | 
			
		||||
			alignment = {x=0, y=-1},
 | 
			
		||||
@@ -63,7 +60,6 @@ minetest.register_globalstep(function(dtime)
 | 
			
		||||
			data.itemname = itemname
 | 
			
		||||
			data.index = index
 | 
			
		||||
			data.dtime = 0
 | 
			
		||||
			local lang_code = minetest.get_player_information(player:get_player_name()).lang_code
 | 
			
		||||
 | 
			
		||||
			local desc = stack.get_meta
 | 
			
		||||
				and stack:get_meta():get_string("description")
 | 
			
		||||
@@ -73,14 +69,6 @@ minetest.register_globalstep(function(dtime)
 | 
			
		||||
				local def = minetest.registered_items[itemname]
 | 
			
		||||
				desc = def and def.description or ""
 | 
			
		||||
			end
 | 
			
		||||
			if only_names and desc and string.find(desc, "\n") then
 | 
			
		||||
				desc = string.match(desc, "([^\n]*)")
 | 
			
		||||
			end
 | 
			
		||||
			desc = minetest.get_translated_string(lang_code, desc)
 | 
			
		||||
			desc = minetest.strip_colors(desc)
 | 
			
		||||
			if string.len(desc) > max_length and max_length > 0 then
 | 
			
		||||
				desc = string.sub(desc, 1, max_length) .. " [...]"
 | 
			
		||||
			end
 | 
			
		||||
			player:hud_change(data.hud, 'text', desc)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								legacy.lua
									
									
									
									
									
								
							
							
						
						@@ -1,55 +0,0 @@
 | 
			
		||||
-- Inefficient pattern matching
 | 
			
		||||
 | 
			
		||||
local warned_funcs = {}
 | 
			
		||||
local function LOG_ONCE(funcname)
 | 
			
		||||
	if warned_funcs[funcname] then return end
 | 
			
		||||
	warned_funcs[funcname] = true
 | 
			
		||||
	minetest.log("error", "Call to undocumented, deprecated API '" .. funcname .. "'."
 | 
			
		||||
		.. " In a future version of Unified Inventory this will result in a real error.")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.canonical_item_spec_matcher(spec)
 | 
			
		||||
	LOG_ONCE("canonical_item_spec_matcher")
 | 
			
		||||
	local specname = ItemStack(spec):get_name()
 | 
			
		||||
	if specname:sub(1, 6) ~= "group:" then
 | 
			
		||||
		return function (itemname)
 | 
			
		||||
			return itemname == specname
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local group_names = specname:sub(7):split(",")
 | 
			
		||||
	return function (itemname)
 | 
			
		||||
		local itemdef = minetest.registered_items[itemname]
 | 
			
		||||
		for _, group_name in ipairs(group_names) do
 | 
			
		||||
			if (itemdef.groups[group_name] or 0) == 0 then
 | 
			
		||||
				return false
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		return true
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.item_matches_spec(item, spec)
 | 
			
		||||
	LOG_ONCE("item_matches_spec")
 | 
			
		||||
	local itemname = ItemStack(item):get_name()
 | 
			
		||||
	return unified_inventory.canonical_item_spec_matcher(spec)(itemname)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.registered_group_items = {
 | 
			
		||||
	mesecon_conductor_craftable = "mesecons:wire_00000000_off",
 | 
			
		||||
	stone = "default:cobble",
 | 
			
		||||
	wood = "default:wood",
 | 
			
		||||
	book = "default:book",
 | 
			
		||||
	sand = "default:sand",
 | 
			
		||||
	leaves = "default:leaves",
 | 
			
		||||
	tree = "default:tree",
 | 
			
		||||
	vessel = "vessels:glass_bottle",
 | 
			
		||||
	wool = "wool:white",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_group_item(groupname, itemname)
 | 
			
		||||
	LOG_ONCE("register_group_item")
 | 
			
		||||
	unified_inventory.registered_group_items[groupname] = itemname
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -1,366 +0,0 @@
 | 
			
		||||
# LANGUAGE translation for the unified_inventory mod.
 | 
			
		||||
# Copyright (C) 2018 Maciej Kasatkin (RealBadAngel)
 | 
			
		||||
# This file is distributed under the same license as the unified_inventory package.
 | 
			
		||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
 | 
			
		||||
#
 | 
			
		||||
#, fuzzy
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: unified_inventory\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2018-04-02 03:34+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2025-09-06 23:13+0200\n"
 | 
			
		||||
"Last-Translator: \n"
 | 
			
		||||
"Language-Team: \n"
 | 
			
		||||
"Language: da_DK\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"X-Generator: Poedit 3.6\n"
 | 
			
		||||
 | 
			
		||||
#: api.lua register.lua
 | 
			
		||||
msgid "Crafting"
 | 
			
		||||
msgstr "Fremstilling"
 | 
			
		||||
 | 
			
		||||
#: api.lua
 | 
			
		||||
msgid "Mixing"
 | 
			
		||||
msgstr "Mikse"
 | 
			
		||||
 | 
			
		||||
#: api.lua
 | 
			
		||||
msgid "Cooking"
 | 
			
		||||
msgstr "Koge"
 | 
			
		||||
 | 
			
		||||
#: api.lua
 | 
			
		||||
msgid "Digging"
 | 
			
		||||
msgstr "Grave"
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Bags"
 | 
			
		||||
msgstr "Tasker"
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Bag @1"
 | 
			
		||||
msgstr "Taske @1"
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Small Bag"
 | 
			
		||||
msgstr "Lille taske"
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Medium Bag"
 | 
			
		||||
msgstr "Mellem taske"
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Large Bag"
 | 
			
		||||
msgstr "Stor taske"
 | 
			
		||||
 | 
			
		||||
#: group.lua
 | 
			
		||||
msgid " and "
 | 
			
		||||
msgstr " og "
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "First page"
 | 
			
		||||
msgstr "Første side"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Back three pages"
 | 
			
		||||
msgstr "Tilbage tre sider"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Back one page"
 | 
			
		||||
msgstr "Tilbage en side"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Forward one page"
 | 
			
		||||
msgstr "Frem en side"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Forward three pages"
 | 
			
		||||
msgstr "Frem tre sider"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Last page"
 | 
			
		||||
msgstr "Sidste side"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Søg"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Reset search and display everything"
 | 
			
		||||
msgstr "Nulstil søgning og vis alting"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "No matching items"
 | 
			
		||||
msgstr "Ingen ting svarer til søgningen"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "No matches."
 | 
			
		||||
msgstr "Ingen resultater."
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Page"
 | 
			
		||||
msgstr "Side"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "%s of %s"
 | 
			
		||||
msgstr "%s af %s"
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Filter"
 | 
			
		||||
msgstr "Filter"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Can use the creative inventory"
 | 
			
		||||
msgstr "Kan bruge den kreative beholdning"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid ""
 | 
			
		||||
"Forces Unified Inventory to be displayed in Full mode if Lite mode is "
 | 
			
		||||
"configured globally"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Tvinger Unified Inventory til at blive vist i fuld visning, hvis simpel "
 | 
			
		||||
"visning er indstillet globalt"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Crafting Grid"
 | 
			
		||||
msgstr "Fremstillingsgitter"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Crafting Guide"
 | 
			
		||||
msgstr "Fremstillingsvejledning"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Set home position"
 | 
			
		||||
msgstr "Sæt position for hjem"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Home position set to: %s"
 | 
			
		||||
msgstr "Hjem-position sat til: %s"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "You don't have the \"home\" privilege!"
 | 
			
		||||
msgstr "Du har ikke \"hjem\"-rettigheden!"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Go home"
 | 
			
		||||
msgstr "Gå hjem"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Set time to day"
 | 
			
		||||
msgstr "Sæt tiden til dag"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Time of day set to 6am"
 | 
			
		||||
msgstr "Sæt uret til kl. 6"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "You don't have the settime privilege!"
 | 
			
		||||
msgstr "Du har ikke rettigheden til at sætte tiden!"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Set time to night"
 | 
			
		||||
msgstr "Sæt tiden til nat"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Time of day set to 9pm"
 | 
			
		||||
msgstr "Sæt uret til kl. 21"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Clear inventory"
 | 
			
		||||
msgstr "Ryd beholdningen"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid ""
 | 
			
		||||
"This button has been disabled outside of creative mode to prevent accidental "
 | 
			
		||||
"inventory trashing.\n"
 | 
			
		||||
"Use the trash slot instead."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Denne knap er deaktiveret uden for kreativ tilstand for at forhindre "
 | 
			
		||||
"utilsigtet rydning af beholdningen.\n"
 | 
			
		||||
"Brug skraldespanden i stedet."
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Inventory cleared!"
 | 
			
		||||
msgstr "Beholdningen er ryddet!"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Trash:"
 | 
			
		||||
msgstr "Skraldespand:"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Refill:"
 | 
			
		||||
msgstr "Genopfyld:"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Any item belonging to the %s group"
 | 
			
		||||
msgstr "Hvilken som helst ting der hører til %s-gruppen"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Any item belonging to the groups %s"
 | 
			
		||||
msgstr "Hvilken som helst ting der hører til grupperne %s"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Recipe %d of %d"
 | 
			
		||||
msgstr "Opskrift %d af %d"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Usage %d of %d"
 | 
			
		||||
msgstr "Brug %d af %d"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "No recipes"
 | 
			
		||||
msgstr "Ingen opskrifter"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "No usages"
 | 
			
		||||
msgstr "Ingen brugt"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Result"
 | 
			
		||||
msgstr "Resultat"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Ingredient"
 | 
			
		||||
msgstr "Ingrediens"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show next recipe"
 | 
			
		||||
msgstr "Vis næste opskrift"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show next usage"
 | 
			
		||||
msgstr "Vis næste brug"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show previous recipe"
 | 
			
		||||
msgstr "Vis foregående opskrift"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show previous usage"
 | 
			
		||||
msgstr "Vis foregående brug"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "%s (%s)"
 | 
			
		||||
msgstr "%s (%s)"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Give me:"
 | 
			
		||||
msgstr "Giv mig:"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid ""
 | 
			
		||||
"This recipe is too\n"
 | 
			
		||||
"large to be displayed."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Denne opskrift er for\n"
 | 
			
		||||
"stor til at blive vist."
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "To craft grid:"
 | 
			
		||||
msgstr "Fremstillingsgitteret:"
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "All"
 | 
			
		||||
msgstr "Alle"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "White"
 | 
			
		||||
msgstr "Hvid"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Yellow"
 | 
			
		||||
msgstr "Gul"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Red"
 | 
			
		||||
msgstr "Rød"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Green"
 | 
			
		||||
msgstr "Grøn"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Blue"
 | 
			
		||||
msgstr "Blå"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Waypoints"
 | 
			
		||||
msgstr "Vigtige lokaliteter"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Select Waypoint #%d"
 | 
			
		||||
msgstr "Vælg lokalitet #%d"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Waypoint %d"
 | 
			
		||||
msgstr "Lokalitet %d"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Set waypoint to current location"
 | 
			
		||||
msgstr "Angiv dette sted som vigtigt lokalitet"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "invisible"
 | 
			
		||||
msgstr "usynligt"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "visible"
 | 
			
		||||
msgstr "synligt"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Make waypoint @1"
 | 
			
		||||
msgstr "Gør lokalitet @1"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Disable"
 | 
			
		||||
msgstr "Slå fra"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Enable"
 | 
			
		||||
msgstr "Slå til"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "@1 display of waypoint coordinates"
 | 
			
		||||
msgstr "@1 visning af vigtige lokaliteters koordinater"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Change color of waypoint display"
 | 
			
		||||
msgstr "Ændr farven på visning af vigtige lokaliteter"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Edit waypoint name"
 | 
			
		||||
msgstr "Rediger lokalitetens navn"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Waypoint active"
 | 
			
		||||
msgstr "Lokaliteten aktiv"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Waypoint inactive"
 | 
			
		||||
msgstr "Lokaliteten inaktiv"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Finish editing"
 | 
			
		||||
msgstr "Afslut redigering"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "World position"
 | 
			
		||||
msgstr "Position i verdenen"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Name"
 | 
			
		||||
msgstr "Navn"
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "HUD text color"
 | 
			
		||||
msgstr "Farve på instrumentbrættet"
 | 
			
		||||
@@ -7,17 +7,17 @@ Bag @1=Tasche @1
 | 
			
		||||
Small Bag=Kleine Tasche
 | 
			
		||||
Medium Bag=Mittelgroße Tasche
 | 
			
		||||
Large Bag=Große Tasche
 | 
			
		||||
All Items=Alle Gegenstände
 | 
			
		||||
Misc. Items=Sonstige Gegenstände
 | 
			
		||||
Plant Life=Pfanzenwelt
 | 
			
		||||
Building Materials=Baumaterialien
 | 
			
		||||
Tools=Werkzeuge
 | 
			
		||||
Minerals and Metals=Minerale und Metalle
 | 
			
		||||
Environment and Worldgen=Umwelt und Welterstellung
 | 
			
		||||
Lighting=Beleuchtung
 | 
			
		||||
All Items=
 | 
			
		||||
Misc. Items=
 | 
			
		||||
Plant Life=
 | 
			
		||||
Building Materials=
 | 
			
		||||
Tools=
 | 
			
		||||
Minerals and Metals=
 | 
			
		||||
Environment and Worldgen=
 | 
			
		||||
Lighting=
 | 
			
		||||
 and = und 
 | 
			
		||||
Scroll categories left=Kategorien nach links blättern
 | 
			
		||||
Scroll categories right=Kategorien nach rechts blättern
 | 
			
		||||
Scroll categories left=
 | 
			
		||||
Scroll categories right=
 | 
			
		||||
Search=Suchen
 | 
			
		||||
Reset search and display everything=Suche zurücksetzen und alles anzeigen
 | 
			
		||||
First page=Erste Seite
 | 
			
		||||
@@ -76,10 +76,10 @@ Waypoints=Wegpunkte
 | 
			
		||||
Select Waypoint #@1=Wegpunkt Nr. @1 auswählen
 | 
			
		||||
Waypoint @1=Wegpunkt Nr. @1
 | 
			
		||||
Set waypoint to current location=Setze Wegpunkt zur derzeitigen Position
 | 
			
		||||
Hide waypoint=Wegpunkt verstecken
 | 
			
		||||
Show waypoint=Wegpunkt zeigen
 | 
			
		||||
Hide coordinates=Koordinaten verstecken
 | 
			
		||||
Show coordinates=Koordinaten zeigen
 | 
			
		||||
Hide waypoint=
 | 
			
		||||
Show waypoint=
 | 
			
		||||
Hide coordinates=
 | 
			
		||||
Show coordinates=
 | 
			
		||||
Change color of waypoint display=Farbe der Darstellung der Wegpunkte ändern
 | 
			
		||||
Edit waypoint name=Name des Wegpunkts ändern
 | 
			
		||||
Waypoint active=Wegpunkt aktiv
 | 
			
		||||
 
 | 
			
		||||
@@ -1,91 +1,98 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Category:=Kategorie:
 | 
			
		||||
Mixing=Miksowanie
 | 
			
		||||
Cooking=Gotowanie
 | 
			
		||||
Digging=Kopanie
 | 
			
		||||
Mixing=
 | 
			
		||||
Cooking=
 | 
			
		||||
Digging=
 | 
			
		||||
Bags=Plecaki
 | 
			
		||||
Bag @1=Plecak @1
 | 
			
		||||
Small Bag=Mały plecak
 | 
			
		||||
Medium Bag=Średni plecak
 | 
			
		||||
Large Bag=Duży plecak
 | 
			
		||||
All Items=Wszystkie przedmioty
 | 
			
		||||
Misc. Items=Różne przedmioty
 | 
			
		||||
Plant Life=Życie roślin
 | 
			
		||||
Building Materials=Materiały budowlane
 | 
			
		||||
Tools=Narzędzia
 | 
			
		||||
Minerals and Metals=Minerały i metale
 | 
			
		||||
Environment and Worldgen=Otoczenie i generowanie świata
 | 
			
		||||
Lighting=Oświetlenie
 | 
			
		||||
Small Bag=Maly plecak
 | 
			
		||||
Medium Bag=Sredni plecak
 | 
			
		||||
Large Bag=Duzy plecak
 | 
			
		||||
All Items=
 | 
			
		||||
Misc. Items=
 | 
			
		||||
Plant Life=
 | 
			
		||||
Building Materials=
 | 
			
		||||
Tools=
 | 
			
		||||
Minerals and Metals=
 | 
			
		||||
Environment and Worldgen=
 | 
			
		||||
Lighting=
 | 
			
		||||
 and = i 
 | 
			
		||||
Scroll categories left=Przewiń kategorię w lewo
 | 
			
		||||
Scroll categories right=Przewiń kategorię w prawo
 | 
			
		||||
Scroll categories left=
 | 
			
		||||
Scroll categories right=
 | 
			
		||||
Search=Szukaj
 | 
			
		||||
Reset search and display everything=Zresetuj wyszukiwanie i pokaż wszystko
 | 
			
		||||
Reset search and display everything=
 | 
			
		||||
First page=Pierwsza strona
 | 
			
		||||
Back three pages=Trzy strony do tyłu
 | 
			
		||||
Back one page=Stronę do tyłu
 | 
			
		||||
Forward one page=Stronę do przodu
 | 
			
		||||
Forward three pages=Trzy strony do przodu
 | 
			
		||||
Back three pages=3 strony w tyl
 | 
			
		||||
Back one page=1 strona w tyl
 | 
			
		||||
Forward one page=1 strona do przodu
 | 
			
		||||
Forward three pages=3 strony do przodu
 | 
			
		||||
Last page=Ostatnia strona
 | 
			
		||||
No matching items=Brak pasujących przedmiotów
 | 
			
		||||
No matching items=Brak pasujacych przedmiotow
 | 
			
		||||
No matches.=Brak wyników
 | 
			
		||||
Page=Strona
 | 
			
		||||
@1 of @2=@1 z @2
 | 
			
		||||
Filter=Filtr
 | 
			
		||||
Can use the creative inventory=Może używać kreatywnego ekwipunku
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Wymusza wyświetlanie Unified Inventory w trybie Full jeżeli tryb Lite jest skonfigurowany globalnie
 | 
			
		||||
Crafting Grid=Siatka craftingu
 | 
			
		||||
Crafting Guide=Przewodnik craftingu
 | 
			
		||||
Set home position=Ustaw pozycję domu
 | 
			
		||||
Home position set to: @1=Pozycja domu ustawiona na: @1
 | 
			
		||||
You don't have the "home" privilege!=Brak uprawnień "home"!
 | 
			
		||||
Can use the creative inventory=
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
 | 
			
		||||
Crafting Grid=
 | 
			
		||||
Crafting Guide=
 | 
			
		||||
Set home position=Ustaw pozycję wyjściową
 | 
			
		||||
Home position set to: @1=Pozycja domowa ustawiona na: @1
 | 
			
		||||
You don't have the "home" privilege!=Nie masz uprawnien do zmiany czasu "home"!
 | 
			
		||||
Go home=Idź do domu
 | 
			
		||||
Set time to day=Ustaw czas na dzień
 | 
			
		||||
Time of day set to 6am=Czas ustawiony na 6:00
 | 
			
		||||
You don't have the settime privilege!=Brak uprawnień "settime"!
 | 
			
		||||
You don't have the settime privilege!=Nie masz uprawnien do zmiany czasu "settime"!
 | 
			
		||||
Set time to night=Ustaw czas na noc
 | 
			
		||||
Time of day set to 9pm=Czas ustawiony na 21:00
 | 
			
		||||
Clear inventory=Wyczyść ekwipunek
 | 
			
		||||
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=Aby zapobiec przypadkowemu skasowaniu ekwipunku, ten przycisk został wyłączony poza trybem kreatywnym.@nUżyj zamiast tego ikony śmietnika.
 | 
			
		||||
Inventory cleared!=Ekwipunek został wyczyszczony!
 | 
			
		||||
Trash:=Śmietnik:
 | 
			
		||||
Refill:=Uzupełnianie:
 | 
			
		||||
Any item belonging to the @1 group=Każdy przedmiot należący do @1 grupy
 | 
			
		||||
Any item belonging to the groups @1=Każdy przedmiot należacy do grup @1
 | 
			
		||||
Clear inventory=Wyczyść zapasy
 | 
			
		||||
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
 | 
			
		||||
Inventory cleared!=Zapasy zostały wyczyszczone!
 | 
			
		||||
Trash:=Smietnik:
 | 
			
		||||
Refill:=Uzupelnianie:
 | 
			
		||||
Any item belonging to the @1 group=
 | 
			
		||||
Any item belonging to the groups @1=
 | 
			
		||||
Recipe @1 of @2=Recepta @1 z @2
 | 
			
		||||
Usage @1 of @2=Użycie @1 z @2
 | 
			
		||||
No recipes=Brak recepty
 | 
			
		||||
No usages=Bez użycia
 | 
			
		||||
Result=Wynik
 | 
			
		||||
Ingredient=Składnik
 | 
			
		||||
Show next recipe=Pokaż nastepną recepturę
 | 
			
		||||
Show next usage=Pokaż następne użycie
 | 
			
		||||
Show previous recipe=Pokaż poprzednią recepturę
 | 
			
		||||
Show previous usage=Pokaż poprzednie użycie
 | 
			
		||||
@1 (@2)=@1 (@2)
 | 
			
		||||
Show next recipe=
 | 
			
		||||
Show next usage=
 | 
			
		||||
Show previous recipe=
 | 
			
		||||
Show previous usage=
 | 
			
		||||
@1 (@2)=
 | 
			
		||||
Give me:=Daj mi:
 | 
			
		||||
This recipe is too@@large to be displayed.=Receptura jest zbyt@@duża aby ją wyświetlić.
 | 
			
		||||
To craft grid:=Do siatki craftingu.
 | 
			
		||||
This recipe is too@@large to be displayed.=
 | 
			
		||||
To craft grid:=
 | 
			
		||||
All=Wszystko
 | 
			
		||||
Crafting=Crafting
 | 
			
		||||
White=Biały
 | 
			
		||||
Yellow=Zółty
 | 
			
		||||
Crafting=
 | 
			
		||||
White=Bialy
 | 
			
		||||
Yellow=Zolty
 | 
			
		||||
Red=Czerwony
 | 
			
		||||
Green=Zielony
 | 
			
		||||
Blue=Niebieski
 | 
			
		||||
Waypoints=Punkty orientacyjne
 | 
			
		||||
Select Waypoint #@1=Wybierz punkt #@1
 | 
			
		||||
Waypoint @1=Punkty orientacyjne @1
 | 
			
		||||
Set waypoint to current location=Ustaw punkt orientacyjny na bieżacej pozycji
 | 
			
		||||
Hide waypoint=Ukryj punkt orientacyjny
 | 
			
		||||
Show waypoint=Pokaż punkt orientacyjny
 | 
			
		||||
Hide coordinates=Ukryj koordynaty
 | 
			
		||||
Show coordinates=Pokaż koordynaty
 | 
			
		||||
Change color of waypoint display=Zmień kolor punktu
 | 
			
		||||
Edit waypoint name=Edytuj nazwę punktu
 | 
			
		||||
Waypoint active=Punkt włączony
 | 
			
		||||
Waypoint inactive=Punkt wyłączony
 | 
			
		||||
Finish editing=Zakończ edycję
 | 
			
		||||
Set waypoint to current location=Ustaw punkt orientacyjny na biezacej pozycji
 | 
			
		||||
Hide waypoint=
 | 
			
		||||
Show waypoint=
 | 
			
		||||
Hide coordinates=
 | 
			
		||||
Show coordinates=
 | 
			
		||||
Change color of waypoint display=Zmien kolor punktu
 | 
			
		||||
Edit waypoint name=Edytuj nazwe punktu
 | 
			
		||||
Waypoint active=Punkt wlaczony
 | 
			
		||||
Waypoint inactive=Punkt wylaczony
 | 
			
		||||
Finish editing=Zakoncz edycje
 | 
			
		||||
World position=Pozycja
 | 
			
		||||
Name=Nazwa
 | 
			
		||||
HUD text color=Kolor tekstu HUD
 | 
			
		||||
HUD text color=Kolor tekstu HUD
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##### not used anymore #####
 | 
			
		||||
 | 
			
		||||
invisible=niewidzialny
 | 
			
		||||
visible=widomy
 | 
			
		||||
Make waypoint @1=Robić punkt @1
 | 
			
		||||
@1 display of waypoint coordinates=@1 koordynatow punktu
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,23 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Mixing=Мешать
 | 
			
		||||
Cooking=Готовить
 | 
			
		||||
Cooking=Варить
 | 
			
		||||
Digging=Копать
 | 
			
		||||
Bags=Сумки
 | 
			
		||||
Bag @1=Сумка @1
 | 
			
		||||
Small Bag=Малая сумка
 | 
			
		||||
Medium Bag=Средняя сумка
 | 
			
		||||
Large Bag=Большая сумка
 | 
			
		||||
All Items=Все предметы
 | 
			
		||||
Misc. Items=Разн. предметы
 | 
			
		||||
Plant Life=Растения
 | 
			
		||||
Building Materials=Стройматериалы
 | 
			
		||||
Tools=Инструменты
 | 
			
		||||
Minerals and Metals=Металлы и минералы
 | 
			
		||||
Environment and Worldgen=Окружение и генер.мира
 | 
			
		||||
Lighting=Освещение
 | 
			
		||||
All Items=
 | 
			
		||||
Misc. Items=
 | 
			
		||||
Plant Life=
 | 
			
		||||
Building Materials=
 | 
			
		||||
Tools=
 | 
			
		||||
Minerals and Metals=
 | 
			
		||||
Environment and Worldgen=
 | 
			
		||||
Lighting=
 | 
			
		||||
 and = и 
 | 
			
		||||
Scroll categories left=Листать влево
 | 
			
		||||
Scroll categories right=Листать вправо
 | 
			
		||||
Scroll categories left=
 | 
			
		||||
Scroll categories right=
 | 
			
		||||
Search=Поиск
 | 
			
		||||
Reset search and display everything=Сброс поиска, показать всё
 | 
			
		||||
First page=Первая страница
 | 
			
		||||
@@ -32,7 +32,7 @@ Page=Страница
 | 
			
		||||
@1 of @2=@1 из @2
 | 
			
		||||
Filter=Фильтр
 | 
			
		||||
Can use the creative inventory=Можно использовать инвентарь творческого режима
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Отображает инвентарь в полном режиме, если простой режим установлен глобально
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
 | 
			
		||||
Crafting Grid=Решетка крафта
 | 
			
		||||
Crafting Guide=Книга рецептов
 | 
			
		||||
Set home position=Установить позицию дома
 | 
			
		||||
@@ -59,11 +59,11 @@ Result=Результат
 | 
			
		||||
Ingredient=Состав
 | 
			
		||||
Show next recipe=Следующий рецепт
 | 
			
		||||
Show next usage=Следующее использование
 | 
			
		||||
Show previous recipe=Предыдущий рецепт
 | 
			
		||||
Show previous usage=Предыдущая страница
 | 
			
		||||
Show previous recipe=Прошлый рецепт
 | 
			
		||||
Show previous usage=Прошлая страница
 | 
			
		||||
@1 (@2)=
 | 
			
		||||
Give me:=Дай мне:
 | 
			
		||||
This recipe is too@@large to be displayed.=Этот рецепт слишком большой
 | 
			
		||||
This recipe is too@@large to be displayed.=
 | 
			
		||||
To craft grid:=На решeтку крафта:
 | 
			
		||||
All=Все
 | 
			
		||||
Crafting=Крафт
 | 
			
		||||
@@ -76,10 +76,10 @@ Waypoints=Путевые точки
 | 
			
		||||
Select Waypoint #@1=Выбрать путевую точку №@1
 | 
			
		||||
Waypoint @1=Путевая точка @1
 | 
			
		||||
Set waypoint to current location=Установить путевую точку по текущей позиции
 | 
			
		||||
Hide waypoint=Скрыть точку
 | 
			
		||||
Show waypoint=Показать точку
 | 
			
		||||
Hide coordinates=Скрыть координаты
 | 
			
		||||
Show coordinates=Показать координаты
 | 
			
		||||
Hide waypoint=
 | 
			
		||||
Show waypoint=
 | 
			
		||||
Hide coordinates=
 | 
			
		||||
Show coordinates=
 | 
			
		||||
Change color of waypoint display=Поменять цвет путевой точки
 | 
			
		||||
Edit waypoint name=Переименовать путевую точку
 | 
			
		||||
Waypoint active=Путевая точка включена
 | 
			
		||||
@@ -88,4 +88,13 @@ Finish editing=Закончить редакцию
 | 
			
		||||
World position=Позиция мира
 | 
			
		||||
Name=Имя
 | 
			
		||||
HUD text color=Цвет текста HUDа
 | 
			
		||||
Category:=Категории:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##### not used anymore #####
 | 
			
		||||
 | 
			
		||||
invisible=невидимой
 | 
			
		||||
visible=видимой
 | 
			
		||||
Make waypoint @1=Сделать путевую точку @1
 | 
			
		||||
Disable=Выключить
 | 
			
		||||
Enable=Включить
 | 
			
		||||
@1 display of waypoint coordinates=@1 показ координат путевых точек
 | 
			
		||||
 
 | 
			
		||||
@@ -1,92 +0,0 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Replaces the default inventory and adds a number of features, such as a crafting guide=Замінює стандартний інвентар та додає ряд особливостей, таких як книга рецептів
 | 
			
		||||
Mixing=Перемішати
 | 
			
		||||
Cooking=Виплавити
 | 
			
		||||
Digging=Викопати
 | 
			
		||||
Bags=Сумки
 | 
			
		||||
Bag @1=Сумка @1
 | 
			
		||||
Small Bag=Мала сумка
 | 
			
		||||
Medium Bag=Середня сумка
 | 
			
		||||
Large Bag=Велика сумка
 | 
			
		||||
All Items=Все
 | 
			
		||||
Misc. Items=Різне
 | 
			
		||||
Plant Life=Рослини
 | 
			
		||||
Building Materials=Будматеріали
 | 
			
		||||
Tools=Інструменти
 | 
			
		||||
Minerals and Metals=Руди й метали
 | 
			
		||||
Environment and Worldgen=Оточення та генерація світу
 | 
			
		||||
Lighting=Освітлення
 | 
			
		||||
 and = та
 | 
			
		||||
Scroll categories left=Ліворуч
 | 
			
		||||
Scroll categories right=Праворуч
 | 
			
		||||
Search=Пошук
 | 
			
		||||
Reset search and display everything=Скинути пошук та відобразити усе
 | 
			
		||||
First page=Перша сторінка
 | 
			
		||||
Back three pages=3 сторінки назад
 | 
			
		||||
Back one page=Попередня сторінка
 | 
			
		||||
Forward one page=Наступна сторінка
 | 
			
		||||
Forward three pages=3 сторінки вперед
 | 
			
		||||
Last page=Остання сторінка
 | 
			
		||||
No matching items=Не знайдено предметів
 | 
			
		||||
No matches.=Немає результатів.
 | 
			
		||||
Page=Сторінка
 | 
			
		||||
@1 of @2=@1 з @2
 | 
			
		||||
Filter=Фільтр
 | 
			
		||||
Can use the creative inventory=Можна використовувати творчий інвентар
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Відображає повний режим, якщо простий режим сконфігуровано глобально
 | 
			
		||||
Crafting Grid=Сітка майстрування
 | 
			
		||||
Crafting Guide=Книга рецептів
 | 
			
		||||
Set home position=Встановити позицію дому
 | 
			
		||||
Home position set to: @1=Тепер дім розташований по координатам: @1
 | 
			
		||||
You don't have the "home" privilege!=У вас немає привілею "home"!
 | 
			
		||||
Go home=Додому
 | 
			
		||||
Set time to day=День
 | 
			
		||||
Time of day set to 6am=Час встановлено на 6:00
 | 
			
		||||
You don't have the settime privilege!=Ви не можете встановлювати час (нема привілею "settime")
 | 
			
		||||
Set time to night=Ніч
 | 
			
		||||
Time of day set to 9pm=Час встановлено на 21:00
 | 
			
		||||
Clear inventory=Очистити інвентар
 | 
			
		||||
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=Цю кнопку було вимкнено в творчому режимі, щоб запобігти випадковому очищенню інвентаря.@nВикористовуйте слот смітника натомість.
 | 
			
		||||
Inventory cleared!=Інвентар очищено!
 | 
			
		||||
Trash:=Смітник:
 | 
			
		||||
Refill:=Заповнити:
 | 
			
		||||
Any item belonging to the @1 group=Будь-який елемент із групи @1
 | 
			
		||||
Any item belonging to the groups @1=Будь-який елемент із груп @1
 | 
			
		||||
Recipe @1 of @2=Рецепт @1 із @2
 | 
			
		||||
Usage @1 of @2=Використання @1 із @2
 | 
			
		||||
No recipes=Немає рецептів
 | 
			
		||||
No usages=Ніде не використовується
 | 
			
		||||
Result=Результат
 | 
			
		||||
Ingredient=Інгредієнт
 | 
			
		||||
Show next recipe=Наступний рецепт
 | 
			
		||||
Show next usage=Наступне використання
 | 
			
		||||
Show previous recipe=Попередній рецепт
 | 
			
		||||
Show previous usage=Попереднє використання
 | 
			
		||||
@1 (@2)=@1 (@2)
 | 
			
		||||
Give me:=Дай мені:
 | 
			
		||||
This recipe is too@@large to be displayed.=Цей рецепт надто великий, щоб його відобразити
 | 
			
		||||
To craft grid:=На сітку крафту:
 | 
			
		||||
All=Все
 | 
			
		||||
Crafting=Крафт
 | 
			
		||||
White=Білий
 | 
			
		||||
Yellow=Жовтий
 | 
			
		||||
Red=Червоний
 | 
			
		||||
Green=Зелений
 | 
			
		||||
Blue=Синій
 | 
			
		||||
Waypoints=Геомітки
 | 
			
		||||
Select Waypoint #@1=Вибрати геомітку №@1
 | 
			
		||||
Waypoint @1=Геомітка @1
 | 
			
		||||
Set waypoint to current location=Встановити тут
 | 
			
		||||
Hide waypoint=Сховати геомітку
 | 
			
		||||
Show waypoint=Показати геомітку
 | 
			
		||||
Hide coordinates=Сховати координати
 | 
			
		||||
Show coordinates=Показати координати
 | 
			
		||||
Change color of waypoint display=Змінити колір геомітки
 | 
			
		||||
Edit waypoint name=Перейменувати геомітку
 | 
			
		||||
Waypoint active=Геомітку показано
 | 
			
		||||
Waypoint inactive=Геомітку приховано
 | 
			
		||||
Finish editing=Закінчити редагування
 | 
			
		||||
World position=Світова позиція
 | 
			
		||||
Name=Назва
 | 
			
		||||
HUD text color=Колір тексту
 | 
			
		||||
Category:=Категорії:
 | 
			
		||||
@@ -7,17 +7,17 @@ Bag @1=背包@1
 | 
			
		||||
Small Bag=小背包
 | 
			
		||||
Medium Bag=中背包
 | 
			
		||||
Large Bag=大背包
 | 
			
		||||
All Items=所有物品
 | 
			
		||||
Misc. Items=杂项
 | 
			
		||||
Plant Life=植物
 | 
			
		||||
Building Materials=建材
 | 
			
		||||
Tools=工具
 | 
			
		||||
Minerals and Metals=矿物与金属
 | 
			
		||||
Environment and Worldgen=自然环境
 | 
			
		||||
Lighting=光源
 | 
			
		||||
All Items=
 | 
			
		||||
Misc. Items=
 | 
			
		||||
Plant Life=
 | 
			
		||||
Building Materials=
 | 
			
		||||
Tools=
 | 
			
		||||
Minerals and Metals=
 | 
			
		||||
Environment and Worldgen=
 | 
			
		||||
Lighting=
 | 
			
		||||
 and = 和 
 | 
			
		||||
Scroll categories left=向左滚动分类栏
 | 
			
		||||
Scroll categories right=向右滚动分类栏
 | 
			
		||||
Scroll categories left=
 | 
			
		||||
Scroll categories right=
 | 
			
		||||
Search=搜索
 | 
			
		||||
Reset search and display everything=重置搜索并显示所有物品
 | 
			
		||||
First page=第一页
 | 
			
		||||
@@ -32,7 +32,7 @@ Page=页面
 | 
			
		||||
@1 of @2=第@1页,共@2页
 | 
			
		||||
Filter=过滤器
 | 
			
		||||
Can use the creative inventory=可以使用创造背包
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=如果轻量模式被全局配置,强迫Unified Inventory以完全模式展现。
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
 | 
			
		||||
Crafting Grid=合成表
 | 
			
		||||
Crafting Guide=合成指南
 | 
			
		||||
Set home position=设置家的位置
 | 
			
		||||
@@ -45,7 +45,7 @@ You don't have the settime privilege!=你没有“settime”权限!
 | 
			
		||||
Set time to night=设置时间到晚上
 | 
			
		||||
Time of day set to 9pm=时间设置到晚上9点
 | 
			
		||||
Clear inventory=清空背包
 | 
			
		||||
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=此按钮已在非创造模式中禁用以防止意外的背包清空。@n请使用垃圾桶栏。
 | 
			
		||||
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
 | 
			
		||||
Inventory cleared!=清空背包
 | 
			
		||||
Trash:=丢弃:
 | 
			
		||||
Refill:=填满:
 | 
			
		||||
@@ -57,13 +57,13 @@ No recipes=没有配方
 | 
			
		||||
No usages=没有用法
 | 
			
		||||
Result=结果
 | 
			
		||||
Ingredient=原料
 | 
			
		||||
Show next recipe=显示下一个配方
 | 
			
		||||
Show next usage=显示下一个用法
 | 
			
		||||
Show previous recipe=显示前一个配方
 | 
			
		||||
Show previous usage=显示前一个用法
 | 
			
		||||
@1 (@2)=@1 (@2)
 | 
			
		||||
Show next recipe=
 | 
			
		||||
Show next usage=
 | 
			
		||||
Show previous recipe=
 | 
			
		||||
Show previous usage=
 | 
			
		||||
@1 (@2)=
 | 
			
		||||
Give me:=给予:
 | 
			
		||||
This recipe is too@@large to be displayed.=该配方太@@大,不能显示。
 | 
			
		||||
This recipe is too@@large to be displayed.=
 | 
			
		||||
To craft grid:=填充物品到合成表
 | 
			
		||||
All=全部
 | 
			
		||||
Crafting=合成
 | 
			
		||||
@@ -76,10 +76,10 @@ Waypoints=航路点
 | 
			
		||||
Select Waypoint #@1=查询航路点 #@1
 | 
			
		||||
Waypoint @1=航路点 @1
 | 
			
		||||
Set waypoint to current location=将航路点设置到当前位置
 | 
			
		||||
Hide waypoint=隐藏航路点
 | 
			
		||||
Show waypoint=显示航路点
 | 
			
		||||
Hide coordinates=隐藏坐标
 | 
			
		||||
Show coordinates=显示坐标
 | 
			
		||||
Hide waypoint=
 | 
			
		||||
Show waypoint=
 | 
			
		||||
Hide coordinates=
 | 
			
		||||
Show coordinates=
 | 
			
		||||
Change color of waypoint display=改变航路点显示的颜色
 | 
			
		||||
Edit waypoint name=编辑航路点名称
 | 
			
		||||
Waypoint active=航路点已激活
 | 
			
		||||
 
 | 
			
		||||
@@ -7,17 +7,17 @@ Bag @1=揹包@1
 | 
			
		||||
Small Bag=小揹包
 | 
			
		||||
Medium Bag=中揹包
 | 
			
		||||
Large Bag=大揹包
 | 
			
		||||
All Items=所有物品
 | 
			
		||||
Misc. Items=雜項
 | 
			
		||||
Plant Life=植物
 | 
			
		||||
Building Materials=建材
 | 
			
		||||
Tools=工具
 | 
			
		||||
Minerals and Metals=礦物與金屬
 | 
			
		||||
Environment and Worldgen=自然環境
 | 
			
		||||
Lighting=光源
 | 
			
		||||
All Items=
 | 
			
		||||
Misc. Items=
 | 
			
		||||
Plant Life=
 | 
			
		||||
Building Materials=
 | 
			
		||||
Tools=
 | 
			
		||||
Minerals and Metals=
 | 
			
		||||
Environment and Worldgen=
 | 
			
		||||
Lighting=
 | 
			
		||||
 and = 和 
 | 
			
		||||
Scroll categories left=向左滾動分類欄
 | 
			
		||||
Scroll categories right=向右滾動分類欄
 | 
			
		||||
Scroll categories left=
 | 
			
		||||
Scroll categories right=
 | 
			
		||||
Search=搜索
 | 
			
		||||
Reset search and display everything=重置搜索並顯示所有物品
 | 
			
		||||
First page=第一頁
 | 
			
		||||
@@ -32,7 +32,7 @@ Page=頁面
 | 
			
		||||
@1 of @2=第@1頁,共@2頁
 | 
			
		||||
Filter=過濾器
 | 
			
		||||
Can use the creative inventory=可以使用創造揹包
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=如果輕量模式被全局配置,強迫Unified Inventory以完全模式展現。
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
 | 
			
		||||
Crafting Grid=合成表
 | 
			
		||||
Crafting Guide=合成指南
 | 
			
		||||
Set home position=設置家的位置
 | 
			
		||||
@@ -45,7 +45,7 @@ You don't have the settime privilege!=你沒有“settime”權限!
 | 
			
		||||
Set time to night=設置時間到晚上
 | 
			
		||||
Time of day set to 9pm=時間設置到晚上9點
 | 
			
		||||
Clear inventory=清空揹包
 | 
			
		||||
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=此按鈕已在非創造模式中禁用以防止意外的背包清空。@n請使用垃圾桶欄。
 | 
			
		||||
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
 | 
			
		||||
Inventory cleared!=清空揹包
 | 
			
		||||
Trash:=丟棄:
 | 
			
		||||
Refill:=填滿:
 | 
			
		||||
@@ -57,13 +57,13 @@ No recipes=沒有配方
 | 
			
		||||
No usages=沒有用法
 | 
			
		||||
Result=結果
 | 
			
		||||
Ingredient=原料
 | 
			
		||||
Show next recipe=顯示下一個配方
 | 
			
		||||
Show next usage=顯示下一個用法
 | 
			
		||||
Show previous recipe=顯示上一個配方
 | 
			
		||||
Show previous usage=顯示上一個用法
 | 
			
		||||
@1 (@2)=@1 (@2)
 | 
			
		||||
Show next recipe=
 | 
			
		||||
Show next usage=
 | 
			
		||||
Show previous recipe=
 | 
			
		||||
Show previous usage=
 | 
			
		||||
@1 (@2)=
 | 
			
		||||
Give me:=給予:
 | 
			
		||||
This recipe is too@@large to be displayed.=該配方太@@大,不能顯示。
 | 
			
		||||
This recipe is too@@large to be displayed.=
 | 
			
		||||
To craft grid:=填充物品到合成表
 | 
			
		||||
All=全部
 | 
			
		||||
Crafting=合成
 | 
			
		||||
@@ -76,10 +76,10 @@ Waypoints=航路點
 | 
			
		||||
Select Waypoint #@1=查詢航路點 #@1
 | 
			
		||||
Waypoint @1=航路點 @1
 | 
			
		||||
Set waypoint to current location=將航路點設置到當前位置
 | 
			
		||||
Hide waypoint=隱藏航路點
 | 
			
		||||
Show waypoint=顯示航路點
 | 
			
		||||
Hide coordinates=隱藏坐標
 | 
			
		||||
Show coordinates=顯示坐標
 | 
			
		||||
Hide waypoint=
 | 
			
		||||
Show waypoint=
 | 
			
		||||
Hide coordinates=
 | 
			
		||||
Show coordinates=
 | 
			
		||||
Change color of waypoint display=改變航路點顯示的顏色
 | 
			
		||||
Edit waypoint name=編輯航路點名稱
 | 
			
		||||
Waypoint active=航路點已激活
 | 
			
		||||
 
 | 
			
		||||
@@ -126,18 +126,25 @@ Example output:
 | 
			
		||||
	}
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.find_usable_items(inv_items, craft_items)
 | 
			
		||||
	local get_group = minetest.get_item_group
 | 
			
		||||
	local result = {}
 | 
			
		||||
 | 
			
		||||
	for craft_item in pairs(craft_items) do
 | 
			
		||||
		-- may specify group:type1,type2
 | 
			
		||||
		local items = unified_inventory.get_matching_items(craft_item)
 | 
			
		||||
 | 
			
		||||
		local group = craft_item:match("^group:(.+)")
 | 
			
		||||
		local found = {}
 | 
			
		||||
		for itemname, _ in pairs(items) do
 | 
			
		||||
			if inv_items[itemname] then
 | 
			
		||||
				found[itemname] = true
 | 
			
		||||
 | 
			
		||||
		if group ~= nil then
 | 
			
		||||
			for inv_item in pairs(inv_items) do
 | 
			
		||||
				if get_group(inv_item, group) > 0 then
 | 
			
		||||
					found[inv_item] = true
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			if inv_items[craft_item] ~= nil then
 | 
			
		||||
				found[craft_item] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		result[craft_item] = found
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								mod.conf
									
									
									
									
									
								
							
							
						
						@@ -1,6 +1,6 @@
 | 
			
		||||
name = unified_inventory
 | 
			
		||||
 | 
			
		||||
optional_depends = default, creative, sfinv, datastorage
 | 
			
		||||
optional_depends = default, creative, sfinv, datastorage, farming
 | 
			
		||||
description = """
 | 
			
		||||
Unified Inventory replaces the default survival and creative inventory.
 | 
			
		||||
It adds a nicer interface and a number of features, such as a crafting guide.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										87
									
								
								register.lua
									
									
									
									
									
								
							
							
						
						@@ -41,55 +41,6 @@ ui.register_button("craftguide", {
 | 
			
		||||
	tooltip = S("Crafting Guide")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
ui.register_button("home_gui_set", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_sethome_icon.png",
 | 
			
		||||
	tooltip = S("Set home position"),
 | 
			
		||||
	hide_lite=true,
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {home=true}) then
 | 
			
		||||
			ui.set_home(player, player:get_pos())
 | 
			
		||||
			local home = ui.home_pos[player_name]
 | 
			
		||||
			if home ~= nil then
 | 
			
		||||
				minetest.sound_play("dingdong",
 | 
			
		||||
						{to_player=player_name, gain = 1.0})
 | 
			
		||||
				minetest.chat_send_player(player_name,
 | 
			
		||||
					S("Home position set to: @1", minetest.pos_to_string(home)))
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
				S("You don't have the \"home\" privilege!"))
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
		return minetest.check_player_privs(player:get_player_name(), {home=true})
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
ui.register_button("home_gui_go", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_gohome_icon.png",
 | 
			
		||||
	tooltip = S("Go home"),
 | 
			
		||||
	hide_lite=true,
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {home=true}) then
 | 
			
		||||
			if ui.go_home(player) then
 | 
			
		||||
				minetest.sound_play("teleport", {to_player = player_name})
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
				S("You don't have the \"home\" privilege!"))
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
		return minetest.check_player_privs(player:get_player_name(), {home=true})
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
ui.register_button("misc_set_day", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_sun_icon.png",
 | 
			
		||||
@@ -98,7 +49,7 @@ ui.register_button("misc_set_day", {
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {settime=true}) then
 | 
			
		||||
			minetest.sound_play("ui_morning",
 | 
			
		||||
			minetest.sound_play("birds",
 | 
			
		||||
					{to_player=player_name, gain = 1.0})
 | 
			
		||||
			minetest.set_timeofday((6000 % 24000) / 24000)
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
@@ -122,7 +73,7 @@ ui.register_button("misc_set_night", {
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {settime=true}) then
 | 
			
		||||
			minetest.sound_play("ui_owl",
 | 
			
		||||
			minetest.sound_play("owl",
 | 
			
		||||
					{to_player=player_name, gain = 1.0})
 | 
			
		||||
			minetest.set_timeofday((21000 % 24000) / 24000)
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
@@ -183,14 +134,14 @@ ui.register_page("craft", {
 | 
			
		||||
		local n=#formspec+1
 | 
			
		||||
 | 
			
		||||
		if ui.trash_enabled or ui.is_creative(player_name) or minetest.get_player_privs(player_name).give then
 | 
			
		||||
			formspec[n] = string.format("label[%f,%f;%s]", craftx + 6.35, crafty + 2.3, F(S("Trash:")))
 | 
			
		||||
			formspec[n] = string.format("label[%f,%f;%s]", craftx + 6.45, crafty + 2.4, F(S("Trash:")))
 | 
			
		||||
			formspec[n+1] = ui.make_trash_slot(craftx + 6.25, crafty + 2.5)
 | 
			
		||||
			n=n + 2
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if ui.is_creative(player_name) then
 | 
			
		||||
			formspec[n] = ui.single_slot(craftx - 2.5, crafty + 2.5)
 | 
			
		||||
			formspec[n+1] = string.format("label[%f,%f;%s]", craftx - 2.4, crafty + 2.3, F(S("Refill:")))
 | 
			
		||||
			formspec[n+1] = string.format("label[%f,%f;%s]", craftx - 2.3, crafty + 2.4,F(S("Refill:")))
 | 
			
		||||
			formspec[n+2] = string.format("list[detached:%srefill;main;%f,%f;1,1;]",
 | 
			
		||||
				F(player_name), craftx - 2.5 + ui.list_img_offset, crafty + 2.5 + ui.list_img_offset)
 | 
			
		||||
		end
 | 
			
		||||
@@ -207,15 +158,17 @@ ui.register_page("craft", {
 | 
			
		||||
 | 
			
		||||
local function stack_image_button(x, y, w, h, buttonname_prefix, item)
 | 
			
		||||
	local name = item:get_name()
 | 
			
		||||
	local count = item:get_count()
 | 
			
		||||
	local wear = item:get_wear()
 | 
			
		||||
	local description = item:get_meta():get_string("description")
 | 
			
		||||
	local show_is_group = false
 | 
			
		||||
	local displayitem = item:to_string()
 | 
			
		||||
	local displayitem = name.." "..count.." "..wear
 | 
			
		||||
	local selectitem = name
 | 
			
		||||
	if name:sub(1, 6) == "group:" then
 | 
			
		||||
		local group_name = name:sub(7)
 | 
			
		||||
		local group_item = ui.get_group_item(group_name)
 | 
			
		||||
		show_is_group = not group_item.sole
 | 
			
		||||
		displayitem = group_item.item or name
 | 
			
		||||
		displayitem = group_item.item or "unknown"
 | 
			
		||||
		selectitem = group_item.sole and displayitem or name
 | 
			
		||||
	end
 | 
			
		||||
	local label = show_is_group and "G" or ""
 | 
			
		||||
@@ -243,9 +196,6 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item)
 | 
			
		||||
	return button
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- The recipe text contains parameters, hence they can yet not be translated.
 | 
			
		||||
-- Instead, use a dummy translation call so that it can be picked up by the
 | 
			
		||||
-- static parsing of the translation string update script
 | 
			
		||||
local recipe_text = {
 | 
			
		||||
	recipe = NS("Recipe @1 of @2"),
 | 
			
		||||
	usage = NS("Usage @1 of @2"),
 | 
			
		||||
@@ -298,10 +248,11 @@ ui.register_page("craftguide", {
 | 
			
		||||
 | 
			
		||||
		local n = 4
 | 
			
		||||
 | 
			
		||||
		local item_def = minetest.registered_items[item_name]
 | 
			
		||||
		local item_name_shown
 | 
			
		||||
		if item_def and item_def.description then
 | 
			
		||||
			item_name_shown = S("@1 (@2)", item_def.description, item_name)
 | 
			
		||||
		if minetest.registered_items[item_name]
 | 
			
		||||
				and minetest.registered_items[item_name].description then
 | 
			
		||||
			item_name_shown = S("@1 (@2)",
 | 
			
		||||
				minetest.registered_items[item_name].description, item_name)
 | 
			
		||||
		else
 | 
			
		||||
			item_name_shown = item_name
 | 
			
		||||
		end
 | 
			
		||||
@@ -326,14 +277,12 @@ ui.register_page("craftguide", {
 | 
			
		||||
				F(role_text[dir]), item_name_shown)
 | 
			
		||||
		n = n + 2
 | 
			
		||||
 | 
			
		||||
		local giveme_form =
 | 
			
		||||
			"label[" .. (give_x + 0.1) .. "," .. (craftguidey + 2.7) .. ";" .. F(S("Give me:")) .. "]" ..
 | 
			
		||||
			"button[" .. (give_x) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_1;1]"
 | 
			
		||||
		if item_def and item_def.type ~= "tool" then
 | 
			
		||||
			giveme_form = giveme_form ..
 | 
			
		||||
				"button[" .. (give_x + 0.8) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_10;10]" ..
 | 
			
		||||
				"button[" .. (give_x + 1.6) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_99;99]"
 | 
			
		||||
		end
 | 
			
		||||
		local giveme_form = table.concat({
 | 
			
		||||
			"label[".. (give_x+0.1)..",".. (craftguidey + 2.7) .. ";" .. F(S("Give me:")) .. "]",
 | 
			
		||||
			"button["..(give_x)..","..     (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_1;1]",
 | 
			
		||||
			"button["..(give_x+0.8)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_10;10]",
 | 
			
		||||
			"button["..(give_x+1.6)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_99;99]"
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		if not craft then
 | 
			
		||||
			-- No craft recipes available for this item.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								screenshot.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 134 KiB  | 
@@ -1,36 +1,14 @@
 | 
			
		||||
# Reduced formspec layout, optimized for smaller displays.
 | 
			
		||||
# Note: This may also disable some features to free up visual space.
 | 
			
		||||
#Enabling lite mode enables a smaller and simpler version of the Unified
 | 
			
		||||
#Inventory, optimized for small displays.
 | 
			
		||||
unified_inventory_lite (Lite mode) bool false
 | 
			
		||||
 | 
			
		||||
# Provides craftable bag items to extend the inventory space.
 | 
			
		||||
#If enabled, bags will be made available which can be used to extend
 | 
			
		||||
#inventory storage size.
 | 
			
		||||
unified_inventory_bags (Enable bags) bool true
 | 
			
		||||
 | 
			
		||||
# Shows the trash slot to everyone.
 | 
			
		||||
# When disabled, only players with the privilege "creative" or "give" will
 | 
			
		||||
# have this slot shown in their inventory.
 | 
			
		||||
#If enabled, the trash slot can be used by those without both creative
 | 
			
		||||
#and the give privilege.
 | 
			
		||||
unified_inventory_trash (Enable trash) bool true
 | 
			
		||||
 | 
			
		||||
# Provides waypoints on a per-player basis to remember positions on the map.
 | 
			
		||||
unified_inventory_waypoints (Enable waypoints) bool true
 | 
			
		||||
 | 
			
		||||
# If enabled, disabled buttons will be hidden instead of grayed out.
 | 
			
		||||
unified_inventory_hide_disabled_buttons (Hide disabled buttons) bool false
 | 
			
		||||
 | 
			
		||||
# Hides items with no known craft recipe from the category "all" (default).
 | 
			
		||||
# This setting has no effect on players in creative mode.
 | 
			
		||||
unified_inventory_hide_uncraftable_items (Hide uncraftable items) bool false
 | 
			
		||||
 | 
			
		||||
# Automatically categorizes registered items based on their
 | 
			
		||||
# groups. This is based on a fuzzy match, thus is not 100% accurate.
 | 
			
		||||
unified_inventory_automatic_categorization (Categories: add items automatically) bool true
 | 
			
		||||
 | 
			
		||||
# Shows the selected wielded item description in the HUD for a few seconds.
 | 
			
		||||
unified_inventory_item_names (Enable HUD item names) bool true
 | 
			
		||||
 | 
			
		||||
# Trims the shown wielded item description to the first line.
 | 
			
		||||
unified_inventory_only_names (HUD item name: first line only) bool true
 | 
			
		||||
 | 
			
		||||
# Hard character limit of the wielded item description.
 | 
			
		||||
# Crops the shown description to the specified length.
 | 
			
		||||
# 0 disables this functionality.
 | 
			
		||||
unified_inventory_max_item_name_length (HUD item names: character limit) int 80
 | 
			
		||||
unified_inventory_automatic_categorization (Items automatically added to categories) bool true
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								sounds/birds.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								sounds/owl.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 510 B After Width: | Height: | Size: 240 B  | 
| 
		 Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 139 B  | 
| 
		 Before Width: | Height: | Size: 2.2 KiB  | 
@@ -103,7 +103,7 @@ local function get_waypoint_data(player)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
ui.register_page("waypoints", {
 | 
			
		||||
	get_formspec = function(player, perplayer_formspec)
 | 
			
		||||
	get_formspec = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		local wp_info_x = ui.style_full.form_header_x + 1.25
 | 
			
		||||
		local wp_info_y = ui.style_full.form_header_y + 0.5
 | 
			
		||||
@@ -115,16 +115,12 @@ ui.register_page("waypoints", {
 | 
			
		||||
		local sel = waypoints.selected or 1
 | 
			
		||||
 | 
			
		||||
		local formspec = {
 | 
			
		||||
			ui.style_full.standard_inv_bg,
 | 
			
		||||
			string.format("label[%f,%f;%s]",
 | 
			
		||||
				ui.style_full.form_header_x, ui.style_full.form_header_y, F(S("Waypoints"))),
 | 
			
		||||
			"image["..wp_info_x..","..wp_info_y..";1,1;ui_waypoints_icon.png]"
 | 
			
		||||
		}
 | 
			
		||||
		local n=3
 | 
			
		||||
 | 
			
		||||
		if not perplayer_formspec.is_lite_mode then
 | 
			
		||||
			formspec[n] = ui.style_full.standard_inv_bg
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
		local n=4
 | 
			
		||||
 | 
			
		||||
		-- Tabs buttons:
 | 
			
		||||
		for i = 1, COUNT do
 | 
			
		||||
@@ -144,50 +140,36 @@ ui.register_page("waypoints", {
 | 
			
		||||
 | 
			
		||||
		-- Main buttons:
 | 
			
		||||
		local btnlist = {
 | 
			
		||||
			-- 1. formspec name
 | 
			
		||||
			-- 2. button image
 | 
			
		||||
			-- 3. translation text
 | 
			
		||||
			{
 | 
			
		||||
				"toggle_waypoint",
 | 
			
		||||
				waypoint.active and "ui_on_icon.png" or "ui_off_icon.png",
 | 
			
		||||
				waypoint.active and S("Hide waypoint") or S("Show waypoint")
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				"rename_waypoint",
 | 
			
		||||
				"ui_pencil_icon.png",
 | 
			
		||||
				S("Edit waypoint name")
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				"set_waypoint",
 | 
			
		||||
			set_waypoint = {
 | 
			
		||||
				"ui_waypoint_set_icon.png",
 | 
			
		||||
				S("Set waypoint to current location")
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				"toggle_display_pos",
 | 
			
		||||
				waypoint.display_pos and "ui_green_icon_background.png^ui_xyz_icon.png" or
 | 
			
		||||
					"ui_red_icon_background.png^ui_xyz_icon.png^(ui_no.png^[transformR90)",
 | 
			
		||||
			toggle_waypoint = {
 | 
			
		||||
				waypoint.active and "ui_on_icon.png" or "ui_off_icon.png",
 | 
			
		||||
				waypoint.active and S("Hide waypoint") or S("Show waypoint")
 | 
			
		||||
			},
 | 
			
		||||
			toggle_display_pos = {
 | 
			
		||||
				waypoint.display_pos and "ui_green_icon_background.png^ui_xyz_icon.png" or "ui_red_icon_background.png^ui_xyz_icon.png^(ui_no.png^[transformR90)",
 | 
			
		||||
				waypoint.display_pos and S("Hide coordinates") or S("Show coordinates")
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				"toggle_color",
 | 
			
		||||
			toggle_color = {
 | 
			
		||||
				"ui_circular_arrows_icon.png",
 | 
			
		||||
				S("Change color of waypoint display")
 | 
			
		||||
			},
 | 
			
		||||
			rename_waypoint = {
 | 
			
		||||
				"ui_pencil_icon.png",
 | 
			
		||||
				S("Edit waypoint name")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if minetest.get_player_privs(player_name).teleport then
 | 
			
		||||
			table.insert(btnlist, {
 | 
			
		||||
				"teleport_waypoint",
 | 
			
		||||
				"ui_teleport.png",
 | 
			
		||||
				S("Teleport to waypoint")
 | 
			
		||||
			})
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		for i, def in pairs(btnlist) do
 | 
			
		||||
		local x = 4
 | 
			
		||||
		for name, def in pairs(btnlist) do
 | 
			
		||||
			formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s%i;]",
 | 
			
		||||
				wp_buttons_rj + ui.style_full.btn_spc * (i - #btnlist), wp_bottom_row,
 | 
			
		||||
				wp_buttons_rj - ui.style_full.btn_spc * x, wp_bottom_row,
 | 
			
		||||
				ui.style_full.btn_size, ui.style_full.btn_size,
 | 
			
		||||
				def[2], def[1], sel)
 | 
			
		||||
			formspec[n+1] = "tooltip["..def[1]..sel..";"..F(def[3]).."]"
 | 
			
		||||
				def[1], name, sel)
 | 
			
		||||
			formspec[n+1] = "tooltip["..name..sel..";"..F(def[2]).."]"
 | 
			
		||||
			x = x - 1
 | 
			
		||||
			n = n + 2
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
@@ -217,10 +199,7 @@ ui.register_page("waypoints", {
 | 
			
		||||
		formspec[n+2] = string.format("label[%f,%f;%s: %s]",
 | 
			
		||||
			wp_info_x, wp_info_y+2.60, F(S("HUD text color")), hud_colors[waypoint.color or 1][3])
 | 
			
		||||
 | 
			
		||||
		return {
 | 
			
		||||
			formspec = table.concat(formspec),
 | 
			
		||||
			draw_inventory = not perplayer_formspec.is_lite_mode,
 | 
			
		||||
		}
 | 
			
		||||
		return {formspec=table.concat(formspec)}
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -228,6 +207,7 @@ ui.register_button("waypoints", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_waypoints_icon.png",
 | 
			
		||||
	tooltip = S("Waypoints"),
 | 
			
		||||
	hide_lite=true
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
local function update_hud(player, waypoints, temp, i)
 | 
			
		||||
@@ -255,7 +235,7 @@ local function update_hud(player, waypoints, temp, i)
 | 
			
		||||
	end
 | 
			
		||||
	if waypoint.active then
 | 
			
		||||
		temp.hud = player:hud_add({
 | 
			
		||||
			[core.features.hud_def_type_field and "type" or "hud_elem_type"] = "waypoint",
 | 
			
		||||
			hud_elem_type = "waypoint",
 | 
			
		||||
			number = hud_colors[waypoint.color or 1][2] ,
 | 
			
		||||
			name = name,
 | 
			
		||||
			text = "m",
 | 
			
		||||
@@ -333,13 +313,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if fields["teleport_waypoint" .. i] and waypoint.world_pos then
 | 
			
		||||
			if minetest.get_player_privs(player_name).teleport then
 | 
			
		||||
				minetest.sound_play("teleport", {to_player = player_name})
 | 
			
		||||
				player:set_pos(waypoint.world_pos)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if hit then
 | 
			
		||||
			-- Save first
 | 
			
		||||
			waypoints.data[i] = waypoint
 | 
			
		||||
@@ -350,7 +323,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
			update_hud(player, waypoints, temp, i)
 | 
			
		||||
		end
 | 
			
		||||
		if update_formspec then
 | 
			
		||||
			minetest.sound_play("ui_click", {to_player=player_name, gain = 0.1})
 | 
			
		||||
			ui.set_inventory_formspec(player, "waypoints")
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||