Compare commits
	
		
			37 Commits
		
	
	
		
			9d66a21271
			...
			formspec_v
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0f3ed05da9 | ||
| 
						 | 
					784a4a60a5 | ||
| 
						 | 
					ce160eea55 | ||
| 
						 | 
					eb3b8d9626 | ||
| 
						 | 
					c84c23ff04 | ||
| 
						 | 
					7ad7a6b3a9 | ||
| 
						 | 
					d558d0355d | ||
| 
						 | 
					ff200762c8 | ||
| 
						 | 
					1334ca0202 | ||
| 
						 | 
					cfe21b93fb | ||
| 
						 | 
					036804716e | ||
| 
						 | 
					6da359e9d2 | ||
| 
						 | 
					e4f6e1adc4 | ||
| 
						 | 
					ea4151dfa7 | ||
| 
						 | 
					d063af1d27 | ||
| 
						 | 
					250d038d0b | ||
| 
						 | 
					8a7d8268ad | ||
| 
						 | 
					51de368949 | ||
| 
						 | 
					e61ae0e149 | ||
| 
						 | 
					531442c63e | ||
| 
						 | 
					62881d9938 | ||
| 
						 | 
					55692900f9 | ||
| 
						 | 
					d52303a89e | ||
| 
						 | 
					b9e4b9e455 | ||
| 
						 | 
					4d52ebe774 | ||
| 
						 | 
					73ce55646c | ||
| 
						 | 
					4b39bc86cb | ||
| 
						 | 
					0df814d9d4 | ||
| 
						 | 
					8056bdf966 | ||
| 
						 | 
					7e27f584eb | ||
| 
						 | 
					5140853a3a | ||
| 
						 | 
					a0c06516f4 | ||
| 
						 | 
					5ec4b986bb | ||
| 
						 | 
					0616d1f76b | ||
| 
						 | 
					eb6697aa0d | ||
| 
						 | 
					a5a09bcd3a | ||
| 
						 | 
					e8e1d4d705 | 
							
								
								
									
										116
									
								
								api.lua
									
									
									
									
									
								
							
							
						
						@@ -1,5 +1,6 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
-- Create detached creative inventory after loading all mods
 | 
			
		||||
minetest.after(0.01, function()
 | 
			
		||||
@@ -8,12 +9,12 @@ minetest.after(0.01, function()
 | 
			
		||||
		if not rev_aliases[target] then rev_aliases[target] = {} end
 | 
			
		||||
		table.insert(rev_aliases[target], source)
 | 
			
		||||
	end
 | 
			
		||||
	unified_inventory.items_list = {}
 | 
			
		||||
	ui.items_list = {}
 | 
			
		||||
	for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
		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(unified_inventory.items_list, name)
 | 
			
		||||
			table.insert(ui.items_list, name)
 | 
			
		||||
			local all_names = rev_aliases[name] or {}
 | 
			
		||||
			table.insert(all_names, name)
 | 
			
		||||
			for _, player_name in ipairs(all_names) do
 | 
			
		||||
@@ -26,30 +27,30 @@ minetest.after(0.01, function()
 | 
			
		||||
						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 unified_inventory.get_group_item(string.gsub(chk, "group:", "")).item)
 | 
			
		||||
							  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
 | 
			
		||||
							unified_inventory.register_craft(recipe)
 | 
			
		||||
							ui.register_craft(recipe)
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	table.sort(unified_inventory.items_list)
 | 
			
		||||
	unified_inventory.items_list_size = #unified_inventory.items_list
 | 
			
		||||
	print("Unified Inventory. inventory size: "..unified_inventory.items_list_size)
 | 
			
		||||
	for _, name in ipairs(unified_inventory.items_list) do
 | 
			
		||||
	table.sort(ui.items_list)
 | 
			
		||||
	ui.items_list_size = #ui.items_list
 | 
			
		||||
	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
 | 
			
		||||
		if type(def.drop) == "string" then
 | 
			
		||||
			local dstack = ItemStack(def.drop)
 | 
			
		||||
			if not dstack:is_empty() and dstack:get_name() ~= name then
 | 
			
		||||
				unified_inventory.register_craft({
 | 
			
		||||
				ui.register_craft({
 | 
			
		||||
					type = "digging",
 | 
			
		||||
					items = {name},
 | 
			
		||||
					output = def.drop,
 | 
			
		||||
@@ -115,7 +116,7 @@ minetest.after(0.01, function()
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			for itemstring, count in pairs(drop_guaranteed) do
 | 
			
		||||
				unified_inventory.register_craft({
 | 
			
		||||
				ui.register_craft({
 | 
			
		||||
					type = "digging",
 | 
			
		||||
					items = {name},
 | 
			
		||||
					output = itemstring .. " " .. count,
 | 
			
		||||
@@ -123,7 +124,7 @@ minetest.after(0.01, function()
 | 
			
		||||
				})
 | 
			
		||||
			end
 | 
			
		||||
			for itemstring, count in pairs(drop_maybe) do
 | 
			
		||||
				unified_inventory.register_craft({
 | 
			
		||||
				ui.register_craft({
 | 
			
		||||
					type = "digging_chance",
 | 
			
		||||
					items = {name},
 | 
			
		||||
					output = itemstring .. " " .. count,
 | 
			
		||||
@@ -132,22 +133,22 @@ minetest.after(0.01, function()
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	for _, recipes in pairs(unified_inventory.crafts_for.recipe) do
 | 
			
		||||
	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
 | 
			
		||||
				local matches_spec = unified_inventory.canonical_item_spec_matcher(spec)
 | 
			
		||||
				for _, name in ipairs(unified_inventory.items_list) do
 | 
			
		||||
				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 unified_inventory.crafts_for.usage[name] == nil then
 | 
			
		||||
					unified_inventory.crafts_for.usage[name] = {}
 | 
			
		||||
				if ui.crafts_for.usage[name] == nil then
 | 
			
		||||
					ui.crafts_for.usage[name] = {}
 | 
			
		||||
				end
 | 
			
		||||
				table.insert(unified_inventory.crafts_for.usage[name], recipe)
 | 
			
		||||
				table.insert(ui.crafts_for.usage[name], recipe)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
@@ -156,9 +157,9 @@ end)
 | 
			
		||||
 | 
			
		||||
-- load_home
 | 
			
		||||
local function load_home()
 | 
			
		||||
	local input = io.open(unified_inventory.home_filename, "r")
 | 
			
		||||
	local input = io.open(ui.home_filename, "r")
 | 
			
		||||
	if not input then
 | 
			
		||||
		unified_inventory.home_pos = {}
 | 
			
		||||
		ui.home_pos = {}
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	while true do
 | 
			
		||||
@@ -167,25 +168,25 @@ local function load_home()
 | 
			
		||||
		local y = input:read("*n")
 | 
			
		||||
		local z = input:read("*n")
 | 
			
		||||
		local name = input:read("*l")
 | 
			
		||||
		unified_inventory.home_pos[name:sub(2)] = {x = x, y = y, z = z}
 | 
			
		||||
		ui.home_pos[name:sub(2)] = {x = x, y = y, z = z}
 | 
			
		||||
	end
 | 
			
		||||
	io.close(input)
 | 
			
		||||
end
 | 
			
		||||
load_home()
 | 
			
		||||
 | 
			
		||||
function unified_inventory.set_home(player, pos)
 | 
			
		||||
function ui.set_home(player, pos)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	unified_inventory.home_pos[player_name] = vector.round(pos)
 | 
			
		||||
	ui.home_pos[player_name] = vector.round(pos)
 | 
			
		||||
	-- save the home data from the table to the file
 | 
			
		||||
	local output = io.open(unified_inventory.home_filename, "w")
 | 
			
		||||
	for k, v in pairs(unified_inventory.home_pos) do
 | 
			
		||||
	local output = io.open(ui.home_filename, "w")
 | 
			
		||||
	for k, v in pairs(ui.home_pos) do
 | 
			
		||||
		output:write(v.x.." "..v.y.." "..v.z.." "..k.."\n")
 | 
			
		||||
	end
 | 
			
		||||
	io.close(output)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.go_home(player)
 | 
			
		||||
	local pos = unified_inventory.home_pos[player:get_player_name()]
 | 
			
		||||
function ui.go_home(player)
 | 
			
		||||
	local pos = ui.home_pos[player:get_player_name()]
 | 
			
		||||
	if pos then
 | 
			
		||||
		player:set_pos(pos)
 | 
			
		||||
		return true
 | 
			
		||||
@@ -194,7 +195,7 @@ function unified_inventory.go_home(player)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- register_craft
 | 
			
		||||
function unified_inventory.register_craft(options)
 | 
			
		||||
function ui.register_craft(options)
 | 
			
		||||
	if not options.output then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
@@ -205,10 +206,10 @@ function unified_inventory.register_craft(options)
 | 
			
		||||
	if options.type == "normal" and options.width == 0 then
 | 
			
		||||
		options = { type = "shapeless", items = options.items, output = options.output, width = 0 }
 | 
			
		||||
	end
 | 
			
		||||
	if not unified_inventory.crafts_for.recipe[itemstack:get_name()] then
 | 
			
		||||
		unified_inventory.crafts_for.recipe[itemstack:get_name()] = {}
 | 
			
		||||
	if not ui.crafts_for.recipe[itemstack:get_name()] then
 | 
			
		||||
		ui.crafts_for.recipe[itemstack:get_name()] = {}
 | 
			
		||||
	end
 | 
			
		||||
	table.insert(unified_inventory.crafts_for.recipe[itemstack:get_name()],options)
 | 
			
		||||
	table.insert(ui.crafts_for.recipe[itemstack:get_name()],options)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -219,7 +220,7 @@ local craft_type_defaults = {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.craft_type_defaults(name, options)
 | 
			
		||||
function ui.craft_type_defaults(name, options)
 | 
			
		||||
	if not options.description then
 | 
			
		||||
		options.description = name
 | 
			
		||||
	end
 | 
			
		||||
@@ -228,13 +229,13 @@ function unified_inventory.craft_type_defaults(name, options)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_craft_type(name, options)
 | 
			
		||||
	unified_inventory.registered_craft_types[name] =
 | 
			
		||||
			unified_inventory.craft_type_defaults(name, options)
 | 
			
		||||
function ui.register_craft_type(name, options)
 | 
			
		||||
	ui.registered_craft_types[name] =
 | 
			
		||||
			ui.craft_type_defaults(name, options)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("normal", {
 | 
			
		||||
ui.register_craft_type("normal", {
 | 
			
		||||
	description = F(S("Crafting")),
 | 
			
		||||
	icon = "ui_craftgrid_icon.png",
 | 
			
		||||
	width = 3,
 | 
			
		||||
@@ -250,7 +251,7 @@ unified_inventory.register_craft_type("normal", {
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("shapeless", {
 | 
			
		||||
ui.register_craft_type("shapeless", {
 | 
			
		||||
	description = F(S("Mixing")),
 | 
			
		||||
	icon = "ui_craftgrid_icon.png",
 | 
			
		||||
	width = 3,
 | 
			
		||||
@@ -265,7 +266,7 @@ unified_inventory.register_craft_type("shapeless", {
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("cooking", {
 | 
			
		||||
ui.register_craft_type("cooking", {
 | 
			
		||||
	description = F(S("Cooking")),
 | 
			
		||||
	icon = "default_furnace_front.png",
 | 
			
		||||
	width = 1,
 | 
			
		||||
@@ -273,37 +274,60 @@ unified_inventory.register_craft_type("cooking", {
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("digging", {
 | 
			
		||||
ui.register_craft_type("digging", {
 | 
			
		||||
	description = F(S("Digging")),
 | 
			
		||||
	icon = "default_tool_steelpick.png",
 | 
			
		||||
	width = 1,
 | 
			
		||||
	height = 1,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("digging_chance", {
 | 
			
		||||
ui.register_craft_type("digging_chance", {
 | 
			
		||||
	description = "Digging (by chance)",
 | 
			
		||||
	icon = "default_tool_steelpick.png^[transformFY.png",
 | 
			
		||||
	width = 1,
 | 
			
		||||
	height = 1,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_page(name, def)
 | 
			
		||||
	unified_inventory.pages[name] = def
 | 
			
		||||
function ui.register_page(name, def)
 | 
			
		||||
	ui.pages[name] = def
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_button(name, def)
 | 
			
		||||
function ui.register_button(name, def)
 | 
			
		||||
	if not def.action then
 | 
			
		||||
		def.action = function(player)
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, name)
 | 
			
		||||
			ui.set_inventory_formspec(player, name)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	def.name = name
 | 
			
		||||
	table.insert(unified_inventory.buttons, def)
 | 
			
		||||
	table.insert(ui.buttons, def)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.is_creative(playername)
 | 
			
		||||
function ui.is_creative(playername)
 | 
			
		||||
	return minetest.check_player_privs(playername, {creative=true})
 | 
			
		||||
		or minetest.settings:get_bool("creative_mode")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
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 "") )
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function ui.make_trash_slot(xpos, ypos)
 | 
			
		||||
	return
 | 
			
		||||
		ui.single_slot(xpos, ypos)..
 | 
			
		||||
		"image["..xpos..","..ypos..";1.25,1.25;ui_trash_slot_icon.png^[opacity:95]"..
 | 
			
		||||
		"list[detached:trash;main;"..xpos..","..ypos..";1,1;]"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function ui.make_inv_img_grid(xpos, ypos, width, height, bright)
 | 
			
		||||
	local tiled = {}
 | 
			
		||||
	local n=1
 | 
			
		||||
	for y = 0, (height - 1) do
 | 
			
		||||
		for x = 0, (width -1) do
 | 
			
		||||
			tiled[n] = ui.single_slot(xpos + (ui.imgscale * x), ypos + (ui.imgscale * y), bright)
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return table.concat(tiled)
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										82
									
								
								bags.lua
									
									
									
									
									
								
							
							
						
						@@ -7,29 +7,32 @@ License: GPLv3
 | 
			
		||||
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
local bags_inv_bg_prefix = "image[-0.1,1.0;10.05,"
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("bags", {
 | 
			
		||||
ui.register_page("bags", {
 | 
			
		||||
	get_formspec = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		return { formspec = table.concat({
 | 
			
		||||
			string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4"),
 | 
			
		||||
			bags_inv_bg_prefix.."1.175;ui_bags_header.png]",
 | 
			
		||||
			"label[0,0;" .. F(S("Bags")) .. "]",
 | 
			
		||||
			"button[0,2.2;2,0.5;bag1;" .. F(S("Bag @1", 1)) .. "]",
 | 
			
		||||
			"button[2,2.2;2,0.5;bag2;" .. F(S("Bag @1", 2)) .. "]",
 | 
			
		||||
			"button[4,2.2;2,0.5;bag3;" .. F(S("Bag @1", 3)) .. "]",
 | 
			
		||||
			"button[6,2.2;2,0.5;bag4;" .. F(S("Bag @1", 4)) .. "]",
 | 
			
		||||
			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]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag1;0.5,1.1;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag2;2.5,1.1;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag3;4.5,1.1;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag4;6.5,1.1;1,1;]"
 | 
			
		||||
			"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,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("bags", {
 | 
			
		||||
ui.register_button("bags", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_bags_icon.png",
 | 
			
		||||
	tooltip = S("Bags"),
 | 
			
		||||
@@ -44,33 +47,31 @@ local function get_player_bag_stack(player, i)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
for bag_i = 1, 4 do
 | 
			
		||||
	unified_inventory.register_page("bag" .. bag_i, {
 | 
			
		||||
	ui.register_page("bag" .. bag_i, {
 | 
			
		||||
		get_formspec = function(player)
 | 
			
		||||
			local stack = get_player_bag_stack(player, bag_i)
 | 
			
		||||
			local image = stack:get_definition().inventory_image
 | 
			
		||||
			local fs = {
 | 
			
		||||
				string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4"),
 | 
			
		||||
				"image[7,0;1,1;" .. image .. "]",
 | 
			
		||||
				"label[0,0;" .. F(S("Bag @1", bag_i)) .. "]",
 | 
			
		||||
				"listcolors[#00000000;#00000000]",
 | 
			
		||||
				"list[current_player;bag" .. bag_i .. "contents;0,1.1;8,3;]",
 | 
			
		||||
				"listring[current_name;bag" .. bag_i .. "contents]",
 | 
			
		||||
				"listring[current_player;main]",
 | 
			
		||||
			}
 | 
			
		||||
			local slots = stack:get_definition().groups.bagslots
 | 
			
		||||
			if slots == 8 then
 | 
			
		||||
					fs[#fs + 1] = bags_inv_bg_prefix.."1.175;ui_bags_inv_small.png]"
 | 
			
		||||
			elseif slots == 16 then
 | 
			
		||||
					fs[#fs + 1] = bags_inv_bg_prefix.."2.35;ui_bags_inv_medium.png]"
 | 
			
		||||
			elseif slots == 24 then
 | 
			
		||||
					fs[#fs + 1] = bags_inv_bg_prefix.."3.525;ui_bags_inv_large.png]"
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			local formspec = {
 | 
			
		||||
				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, 0.3 + ui.list_img_offset, 1.5 + ui.list_img_offset),
 | 
			
		||||
				"listring[current_name;bag" .. bag_i .. "contents]",
 | 
			
		||||
			}
 | 
			
		||||
			local n = #formspec + 1
 | 
			
		||||
 | 
			
		||||
			local player_name = player:get_player_name() -- For if statement.
 | 
			
		||||
			if unified_inventory.trash_enabled
 | 
			
		||||
					or unified_inventory.is_creative(player_name)
 | 
			
		||||
					or minetest.get_player_privs(player_name).give then
 | 
			
		||||
				fs[#fs + 1] = "image[5.91,-0.06;1.21,1.15;ui_bags_trash.png]"
 | 
			
		||||
						.. "list[detached:trash;main;6,0.1;1,1;]"
 | 
			
		||||
			if ui.trash_enabled
 | 
			
		||||
				or ui.is_creative(player_name)
 | 
			
		||||
				or minetest.get_player_privs(player_name).give then
 | 
			
		||||
					formspec[n] = ui.make_trash_slot(7.8, 0.25)
 | 
			
		||||
					n = n + 1
 | 
			
		||||
			end
 | 
			
		||||
			local inv = player:get_inventory()
 | 
			
		||||
			for i = 1, 4 do
 | 
			
		||||
@@ -87,11 +88,12 @@ for bag_i = 1, 4 do
 | 
			
		||||
					end
 | 
			
		||||
					local img = def.inventory_image
 | 
			
		||||
					local label = F(S("Bag @1", i)) .. "\n" .. used .. "/" .. size
 | 
			
		||||
					fs[#fs + 1] = string.format("image_button[%i,0;1,1;%s;bag%i;%s]",
 | 
			
		||||
							i + 1, img, i, label)
 | 
			
		||||
					formspec[n] = string.format("image_button[%f,0.4;1,1;%s;bag%i;%s]",
 | 
			
		||||
							(i + 1.35)*1.25, img, i, label)
 | 
			
		||||
					n = n + 1
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			return { formspec = table.concat(fs) }
 | 
			
		||||
			return { formspec = table.concat(formspec) }
 | 
			
		||||
		end,
 | 
			
		||||
	})
 | 
			
		||||
end
 | 
			
		||||
@@ -106,7 +108,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
			if not stack:get_definition().groups.bagslots then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, "bag" .. i)
 | 
			
		||||
			ui.set_inventory_formspec(player, "bag" .. i)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,14 @@ unified_inventory API
 | 
			
		||||
 | 
			
		||||
This file provides information about the API of unified_inventory.
 | 
			
		||||
 | 
			
		||||
API revisions within unified_inventory can be checked using:
 | 
			
		||||
 | 
			
		||||
	(unified_inventory.version or 1)
 | 
			
		||||
 | 
			
		||||
**Revision history**
 | 
			
		||||
 | 
			
		||||
* Version `1`: Classic formspec layout (no real_coordinates)
 | 
			
		||||
* Version `2`: Force formspec version 4 (includes real_coordinates)
 | 
			
		||||
 | 
			
		||||
Misc functions
 | 
			
		||||
--------------
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						@@ -35,21 +35,101 @@ unified_inventory = {
 | 
			
		||||
 | 
			
		||||
	-- Trash enabled
 | 
			
		||||
	trash_enabled = (minetest.settings:get_bool("unified_inventory_trash") ~= false),
 | 
			
		||||
	imgscale = 1.25,
 | 
			
		||||
	list_img_offset = 0.13,
 | 
			
		||||
	standard_background = "background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]",
 | 
			
		||||
	version = 2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
-- These tables establish position and layout for the two UI styles.
 | 
			
		||||
-- UI doesn't use formspec_[xy] anymore, but other mods may need them.
 | 
			
		||||
 | 
			
		||||
ui.style_full = {
 | 
			
		||||
	formspec_x = 1,
 | 
			
		||||
	formspec_y = 1,
 | 
			
		||||
	pagecols = 8,
 | 
			
		||||
	pagerows = 10,
 | 
			
		||||
	page_y = 0,
 | 
			
		||||
	formspec_y = 1,
 | 
			
		||||
	main_button_x = 0,
 | 
			
		||||
	main_button_y = 9,
 | 
			
		||||
	craft_result_x = 0.3,
 | 
			
		||||
	craft_result_y = 0.5,
 | 
			
		||||
	form_header_y = 0,
 | 
			
		||||
	standard_background = "background[-0.2,-0.2;1,1;ui_form_bg.png;true]",    -- the 'true' scales to fill, overrides the 1,1
 | 
			
		||||
	standard_inv =        "list[current_player;main;0,YYY;8,4;]",             -- the YYY's are placeholders which get
 | 
			
		||||
	standard_inv_bg =     "image[-0.1,YYY;10.05,4.70;ui_main_inventory.png]", -- replaced later by string.gsub()
 | 
			
		||||
	page_x = 10.75,
 | 
			
		||||
	page_y = 1.45,
 | 
			
		||||
	craft_x = 2.8,
 | 
			
		||||
	craft_y = 1.15,
 | 
			
		||||
	craftresult_x = 7.8,
 | 
			
		||||
	craft_arrow_x = 6.55,
 | 
			
		||||
	craft_guide_x = 3.3,
 | 
			
		||||
	craft_guide_y = 1.15,
 | 
			
		||||
	craft_guide_arrow_x = 7.05,
 | 
			
		||||
	craft_guide_result_x = 8.3,
 | 
			
		||||
	craft_guide_resultstr_x = 0.3,
 | 
			
		||||
	craft_guide_resultstr_y = 0.6,
 | 
			
		||||
	give_btn_x = 0.25,
 | 
			
		||||
	main_button_x = 0.4,
 | 
			
		||||
	main_button_y = 11.0,
 | 
			
		||||
	page_buttons_x = 11.60,
 | 
			
		||||
	page_buttons_y = 10.15,
 | 
			
		||||
	searchwidth = 3.4,
 | 
			
		||||
	form_header_x = 0.4,
 | 
			
		||||
	form_header_y = 0.4,
 | 
			
		||||
	btn_spc = 0.85,
 | 
			
		||||
	btn_size = 0.75,
 | 
			
		||||
	std_inv_x = 0.3,
 | 
			
		||||
	std_inv_y = 5.75,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ui.style_lite = {
 | 
			
		||||
	formspec_x =  0.6,
 | 
			
		||||
	formspec_y =  0.6,
 | 
			
		||||
	pagecols = 4,
 | 
			
		||||
	pagerows = 6,
 | 
			
		||||
	page_x = 10.5,
 | 
			
		||||
	page_y = 1.25,
 | 
			
		||||
	craft_x = 2.6,
 | 
			
		||||
	craft_y = 0.75,
 | 
			
		||||
	craftresult_x = 5.75,
 | 
			
		||||
	craft_arrow_x = 6.35,
 | 
			
		||||
	craft_guide_x = 3.1,
 | 
			
		||||
	craft_guide_y = 0.75,
 | 
			
		||||
	craft_guide_arrow_x = 7.05,
 | 
			
		||||
	craft_guide_result_x = 8.3,
 | 
			
		||||
	craft_guide_resultstr_x = 0.15,
 | 
			
		||||
	craft_guide_resultstr_y = 0.35,
 | 
			
		||||
	give_btn_x = 0.15,
 | 
			
		||||
	main_button_x = 10.5,
 | 
			
		||||
	main_button_y = 7.9,
 | 
			
		||||
	page_buttons_x = 10.5,
 | 
			
		||||
	page_buttons_y = 6.3,
 | 
			
		||||
	searchwidth = 1.6,
 | 
			
		||||
	form_header_x =  0.2,
 | 
			
		||||
	form_header_y =  0.2,
 | 
			
		||||
	btn_spc = 0.8,
 | 
			
		||||
	btn_size = 0.7,
 | 
			
		||||
	std_inv_x = 0.1,
 | 
			
		||||
	std_inv_y = 4.6,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dofile(modpath.."/api.lua")
 | 
			
		||||
 | 
			
		||||
for _, style in ipairs({ui.style_full, ui.style_lite}) do
 | 
			
		||||
	style.items_per_page =  style.pagecols * style.pagerows
 | 
			
		||||
	style.standard_inv = string.format("list[current_player;main;%f,%f;8,4;]",
 | 
			
		||||
							style.std_inv_x+0.13, style.std_inv_y+0.13)
 | 
			
		||||
 | 
			
		||||
	style.standard_inv_bg = ui.make_inv_img_grid(style.std_inv_x, style.std_inv_y, 8, 1, true)..
 | 
			
		||||
							ui.make_inv_img_grid(style.std_inv_x, style.std_inv_y + ui.imgscale, 8, 3)
 | 
			
		||||
 | 
			
		||||
	style.craft_grid =	table.concat({
 | 
			
		||||
							ui.make_inv_img_grid(style.craft_x, style.craft_y, 3, 3),
 | 
			
		||||
							ui.single_slot(style.craft_x + ui.imgscale*4, style.craft_y), -- the craft result slot
 | 
			
		||||
							string.format("image[%f,%f;%f,%f;ui_crafting_arrow.png]",
 | 
			
		||||
							style.craft_arrow_x, style.craft_y, ui.imgscale, ui.imgscale),
 | 
			
		||||
							string.format("list[current_player;craft;%f,%f;3,3;]",
 | 
			
		||||
								style.craft_x + ui.list_img_offset, style.craft_y + ui.list_img_offset),
 | 
			
		||||
							string.format("list[current_player;craftpreview;%f,%f;1,1;]",
 | 
			
		||||
								style.craftresult_x + ui.list_img_offset, style.craft_y + ui.list_img_offset)
 | 
			
		||||
						})
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Disable default creative inventory
 | 
			
		||||
local creative = rawget(_G, "creative") or rawget(_G, "creative_inventory")
 | 
			
		||||
if creative then
 | 
			
		||||
@@ -65,7 +145,6 @@ if sfinv then
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
dofile(modpath.."/group.lua")
 | 
			
		||||
dofile(modpath.."/api.lua")
 | 
			
		||||
dofile(modpath.."/internal.lua")
 | 
			
		||||
dofile(modpath.."/callbacks.lua")
 | 
			
		||||
dofile(modpath.."/match_craft.lua")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										260
									
								
								internal.lua
									
									
									
									
									
								
							
							
						
						@@ -1,5 +1,6 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
-- This pair of encoding functions is used where variable text must go in
 | 
			
		||||
-- button names, where the text might contain formspec metacharacters.
 | 
			
		||||
@@ -9,78 +10,50 @@ local F = minetest.formspec_escape
 | 
			
		||||
-- This is a game engine bug, and in the anticipation that it might be
 | 
			
		||||
-- fixed some day we don't want to rely on it.  So for safety we apply
 | 
			
		||||
-- an encoding that avoids all formspec metacharacters.
 | 
			
		||||
function unified_inventory.mangle_for_formspec(str)
 | 
			
		||||
 | 
			
		||||
function ui.mangle_for_formspec(str)
 | 
			
		||||
	return string.gsub(str, "([^A-Za-z0-9])", function (c) return string.format("_%d_", string.byte(c)) end)
 | 
			
		||||
end
 | 
			
		||||
function unified_inventory.demangle_for_formspec(str)
 | 
			
		||||
function ui.demangle_for_formspec(str)
 | 
			
		||||
	return string.gsub(str, "_([0-9]+)_", function (v) return string.char(v) end)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.get_per_player_formspec(player_name)
 | 
			
		||||
	local lite = unified_inventory.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true})
 | 
			
		||||
 | 
			
		||||
	local ui = {}
 | 
			
		||||
	ui.pagecols = unified_inventory.pagecols
 | 
			
		||||
	ui.pagerows = unified_inventory.pagerows
 | 
			
		||||
	ui.page_y = unified_inventory.page_y
 | 
			
		||||
	ui.formspec_y = unified_inventory.formspec_y
 | 
			
		||||
	ui.main_button_x = unified_inventory.main_button_x
 | 
			
		||||
	ui.main_button_y = unified_inventory.main_button_y
 | 
			
		||||
	ui.craft_result_x = unified_inventory.craft_result_x
 | 
			
		||||
	ui.craft_result_y = unified_inventory.craft_result_y
 | 
			
		||||
	ui.form_header_y = unified_inventory.form_header_y
 | 
			
		||||
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})
 | 
			
		||||
 | 
			
		||||
	if lite then
 | 
			
		||||
		ui.pagecols = 4
 | 
			
		||||
		ui.pagerows = 6
 | 
			
		||||
		ui.page_y = 0.25
 | 
			
		||||
		ui.formspec_y = 0.47
 | 
			
		||||
		ui.main_button_x = 8.2
 | 
			
		||||
		ui.main_button_y = 6.5
 | 
			
		||||
		ui.craft_result_x = 2.8
 | 
			
		||||
		ui.craft_result_y = 3.4
 | 
			
		||||
		ui.form_header_y = -0.1
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	ui.items_per_page = ui.pagecols * ui.pagerows
 | 
			
		||||
	return ui, lite
 | 
			
		||||
	return table.copy(draw_lite_mode and ui.style_lite or ui.style_full), draw_lite_mode
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.get_formspec(player, page)
 | 
			
		||||
function ui.get_formspec(player, page)
 | 
			
		||||
 | 
			
		||||
	if not player then
 | 
			
		||||
		return ""
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
 | 
			
		||||
	local ui_peruser,draw_lite_mode = ui.get_per_player_formspec(player_name)
 | 
			
		||||
 | 
			
		||||
	unified_inventory.current_page[player_name] = page
 | 
			
		||||
	local pagedef = unified_inventory.pages[page]
 | 
			
		||||
	ui.current_page[player_name] = page
 | 
			
		||||
	local pagedef = ui.pages[page]
 | 
			
		||||
 | 
			
		||||
	if not pagedef then
 | 
			
		||||
		return "" -- Invalid page name
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local formspec = {
 | 
			
		||||
		"size[14,10]",
 | 
			
		||||
		"formspec_version[4]size[17.75,12.25]",
 | 
			
		||||
		pagedef.formspec_prepend and "" or "no_prepend[]",
 | 
			
		||||
		unified_inventory.standard_background -- Background
 | 
			
		||||
		ui.standard_background -- Background
 | 
			
		||||
	}
 | 
			
		||||
	local n = 4
 | 
			
		||||
 | 
			
		||||
	if draw_lite_mode then
 | 
			
		||||
		formspec[1] = "size[11,7.7]"
 | 
			
		||||
		formspec[3] = unified_inventory.standard_background
 | 
			
		||||
		formspec[1] = "formspec_version[4]size[14,9.75]"
 | 
			
		||||
		formspec[3] = ui.standard_background
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if unified_inventory.is_creative(player_name)
 | 
			
		||||
	and page == "craft" then
 | 
			
		||||
		formspec[n] = "background[0,"..(ui_peruser.formspec_y + 2)..";1,1;ui_single_slot.png]"
 | 
			
		||||
		n = n+1
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local perplayer_formspec = unified_inventory.get_per_player_formspec(player_name)
 | 
			
		||||
	local perplayer_formspec = ui.get_per_player_formspec(player_name)
 | 
			
		||||
	local fsdata = pagedef.get_formspec(player, perplayer_formspec)
 | 
			
		||||
 | 
			
		||||
	formspec[n] = fsdata.formspec
 | 
			
		||||
@@ -93,7 +66,7 @@ function unified_inventory.get_formspec(player, page)
 | 
			
		||||
 | 
			
		||||
	local filtered_inv_buttons = {}
 | 
			
		||||
 | 
			
		||||
	for i, def in pairs(unified_inventory.buttons) do
 | 
			
		||||
	for i, def in pairs(ui.buttons) do
 | 
			
		||||
		if not (draw_lite_mode and def.hide_lite) then
 | 
			
		||||
			table.insert(filtered_inv_buttons, def)
 | 
			
		||||
		end
 | 
			
		||||
@@ -108,21 +81,20 @@ function unified_inventory.get_formspec(player, page)
 | 
			
		||||
 | 
			
		||||
		if def.type == "image" then
 | 
			
		||||
			if (def.condition == nil or def.condition(player) == true) then
 | 
			
		||||
				formspec[n] = "image_button["
 | 
			
		||||
				formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4)
 | 
			
		||||
				formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;"
 | 
			
		||||
				formspec[n+3] = F(def.image)..";"
 | 
			
		||||
				formspec[n+4] = F(def.name)..";]"
 | 
			
		||||
				formspec[n+5] = "tooltip["..F(def.name)
 | 
			
		||||
				formspec[n+6] = ";"..(def.tooltip or "").."]"
 | 
			
		||||
				n = n+7
 | 
			
		||||
				formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]",
 | 
			
		||||
					ui_peruser.main_button_x + ui_peruser.btn_spc * (i - 1) - button_col * ui_peruser.btn_spc * 4,
 | 
			
		||||
					ui_peruser.main_button_y + button_row * ui_peruser.btn_spc,
 | 
			
		||||
					ui_peruser.btn_size,ui_peruser.btn_size,
 | 
			
		||||
					F(def.image),
 | 
			
		||||
					F(def.name))
 | 
			
		||||
				formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]"
 | 
			
		||||
				n = n+2
 | 
			
		||||
			else
 | 
			
		||||
				formspec[n] = "image["
 | 
			
		||||
				formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4)
 | 
			
		||||
				formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;"
 | 
			
		||||
				formspec[n+3] = F(def.image).."^[colorize:#808080:alpha]"
 | 
			
		||||
				n = n+4
 | 
			
		||||
 | 
			
		||||
				formspec[n] = string.format("image[%f,%f;%f,%f;%s^[colorize:#808080:alpha]",
 | 
			
		||||
				ui_peruser.main_button_x + ui_peruser.btn_spc * (i - 1) - button_col * ui_peruser.btn_spc * 4,
 | 
			
		||||
				ui_peruser.main_button_y + button_row * ui_peruser.btn_spc,
 | 
			
		||||
				ui_peruser.btn_size,ui_peruser.btn_size,def.image)
 | 
			
		||||
				n = n+1
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
@@ -130,7 +102,7 @@ function unified_inventory.get_formspec(player, page)
 | 
			
		||||
	if fsdata.draw_inventory ~= false then
 | 
			
		||||
		-- Player inventory
 | 
			
		||||
		formspec[n] = "listcolors[#00000000;#00000000]"
 | 
			
		||||
		formspec[n+1] = string.gsub(unified_inventory.standard_inv, "YYY", ui_peruser.formspec_y + 3.5)
 | 
			
		||||
		formspec[n+1] = ui_peruser.standard_inv
 | 
			
		||||
		n = n+2
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
@@ -138,71 +110,52 @@ function unified_inventory.get_formspec(player, page)
 | 
			
		||||
		return table.concat(formspec, "")
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Controls to flip items pages
 | 
			
		||||
	local start_x = 9.2
 | 
			
		||||
 | 
			
		||||
	if not draw_lite_mode then
 | 
			
		||||
		formspec[n] =
 | 
			
		||||
			"image_button[" .. (start_x + 0.6 * 0)
 | 
			
		||||
				.. ",9;.8,.8;ui_skip_backward_icon.png;start_list;]"
 | 
			
		||||
			.. "tooltip[start_list;" .. F(S("First page")) .. "]"
 | 
			
		||||
 | 
			
		||||
			.. "image_button[" .. (start_x + 0.6 * 1)
 | 
			
		||||
				.. ",9;.8,.8;ui_doubleleft_icon.png;rewind3;]"
 | 
			
		||||
			.. "tooltip[rewind3;" .. F(S("Back three pages")) .. "]"
 | 
			
		||||
			.. "image_button[" .. (start_x + 0.6 * 2)
 | 
			
		||||
				.. ",9;.8,.8;ui_left_icon.png;rewind1;]"
 | 
			
		||||
			.. "tooltip[rewind1;" .. F(S("Back one page")) .. "]"
 | 
			
		||||
 | 
			
		||||
			.. "image_button[" .. (start_x + 0.6 * 3)
 | 
			
		||||
				.. ",9;.8,.8;ui_right_icon.png;forward1;]"
 | 
			
		||||
			.. "tooltip[forward1;" .. F(S("Forward one page")) .. "]"
 | 
			
		||||
			.. "image_button[" .. (start_x + 0.6 * 4)
 | 
			
		||||
				.. ",9;.8,.8;ui_doubleright_icon.png;forward3;]"
 | 
			
		||||
			.. "tooltip[forward3;" .. F(S("Forward three pages")) .. "]"
 | 
			
		||||
 | 
			
		||||
			.. "image_button[" .. (start_x + 0.6 * 5)
 | 
			
		||||
				.. ",9;.8,.8;ui_skip_forward_icon.png;end_list;]"
 | 
			
		||||
			.. "tooltip[end_list;" .. F(S("Last page")) .. "]"
 | 
			
		||||
	else
 | 
			
		||||
		formspec[n] =
 | 
			
		||||
			"image_button[" .. (8.2 + 0.65 * 0)
 | 
			
		||||
				.. ",5.8;.8,.8;ui_skip_backward_icon.png;start_list;]"
 | 
			
		||||
			.. "tooltip[start_list;" .. F(S("First page")) .. "]"
 | 
			
		||||
			.. "image_button[" .. (8.2 + 0.65 * 1)
 | 
			
		||||
				.. ",5.8;.8,.8;ui_left_icon.png;rewind1;]"
 | 
			
		||||
			.. "tooltip[rewind1;" .. F(S("Back one page")) .. "]"
 | 
			
		||||
			.. "image_button[" .. (8.2 + 0.65 * 2)
 | 
			
		||||
				.. ",5.8;.8,.8;ui_right_icon.png;forward1;]"
 | 
			
		||||
			.. "tooltip[forward1;" .. F(S("Forward one page")) .. "]"
 | 
			
		||||
			.. "image_button[" .. (8.2 + 0.65 * 3)
 | 
			
		||||
				.. ",5.8;.8,.8;ui_skip_forward_icon.png;end_list;]"
 | 
			
		||||
			.. "tooltip[end_list;" .. F(S("Last page")) .. "]"
 | 
			
		||||
	end
 | 
			
		||||
	n = n+1
 | 
			
		||||
 | 
			
		||||
	-- Search box
 | 
			
		||||
	formspec[n] = "field_close_on_enter[searchbox;false]"
 | 
			
		||||
	n = n+1
 | 
			
		||||
 | 
			
		||||
	if not draw_lite_mode then
 | 
			
		||||
		formspec[n] = "field[9.5,8.325;3,1;searchbox;;"
 | 
			
		||||
			.. F(unified_inventory.current_searchbox[player_name]) .. "]"
 | 
			
		||||
		formspec[n+1] = "image_button[12.2,8.1;.8,.8;ui_search_icon.png;searchbutton;]"
 | 
			
		||||
			.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
 | 
			
		||||
		formspec[n+2] = "image_button[12.9,8.1;.8,.8;ui_reset_icon.png;searchresetbutton;]"
 | 
			
		||||
			.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
 | 
			
		||||
			.. "tooltip[searchresetbutton;" ..F(S("Reset search and display everything")) .. "]"
 | 
			
		||||
	else
 | 
			
		||||
		formspec[n] = "field[8.5,5.225;2.2,1;searchbox;;"
 | 
			
		||||
			.. F(unified_inventory.current_searchbox[player_name]) .. "]"
 | 
			
		||||
		formspec[n+1] = "image_button[10.3,5;.8,.8;ui_search_icon.png;searchbutton;]"
 | 
			
		||||
			.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
 | 
			
		||||
		formspec[n+2] = "image_button[11,5;.8,.8;ui_reset_icon.png;searchresetbutton;]"
 | 
			
		||||
			.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
 | 
			
		||||
			.. "tooltip[searchresetbutton;" ..F(S("Reset search and display everything")) .. "]"
 | 
			
		||||
	formspec[n+1] = string.format("field[%f,%f;%f,%f;searchbox;;%s]",
 | 
			
		||||
		ui_peruser.page_buttons_x, ui_peruser.page_buttons_y,
 | 
			
		||||
		ui_peruser.searchwidth - 0.1, ui_peruser.btn_size,
 | 
			
		||||
		F(ui.current_searchbox[player_name]))
 | 
			
		||||
	formspec[n+2] = string.format("image_button[%f,%f;%f,%f;ui_search_icon.png;searchbutton;]",
 | 
			
		||||
		ui_peruser.page_buttons_x + ui_peruser.searchwidth, ui_peruser.page_buttons_y,
 | 
			
		||||
		ui_peruser.btn_size,ui_peruser.btn_size)
 | 
			
		||||
	formspec[n+3] = "tooltip[searchbutton;" ..F(S("Search")) .. "]"
 | 
			
		||||
	formspec[n+4] = string.format("image_button[%f,%f;%f,%f;ui_reset_icon.png;searchresetbutton;]",
 | 
			
		||||
		ui_peruser.page_buttons_x + ui_peruser.searchwidth + ui_peruser.btn_spc,
 | 
			
		||||
		ui_peruser.page_buttons_y,
 | 
			
		||||
		ui_peruser.btn_size, ui_peruser.btn_size)
 | 
			
		||||
	formspec[n+5] = "tooltip[searchresetbutton;"..F(S("Reset search and display everything")).."]"
 | 
			
		||||
 | 
			
		||||
	n = n + 6
 | 
			
		||||
 | 
			
		||||
	-- Controls to flip items pages
 | 
			
		||||
 | 
			
		||||
	local btnlist = {
 | 
			
		||||
		{ "ui_skip_backward_icon.png", "start_list", S("First page") },
 | 
			
		||||
		{ "ui_doubleleft_icon.png",    "rewind3",    S("Back three pages") },
 | 
			
		||||
		{ "ui_left_icon.png",          "rewind1",    S("Back one page") },
 | 
			
		||||
		{ "ui_right_icon.png",         "forward1",   S("Forward one page") },
 | 
			
		||||
		{ "ui_doubleright_icon.png",   "forward3",   S("Forward three pages") },
 | 
			
		||||
		{ "ui_skip_forward_icon.png",  "end_list",   S("Last page") },
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if draw_lite_mode then
 | 
			
		||||
		btnlist[5] = nil
 | 
			
		||||
		btnlist[2] = nil
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local bn = 0
 | 
			
		||||
	for _, b in pairs(btnlist) do
 | 
			
		||||
		formspec[n] =  string.format("image_button[%f,%f;%f,%f;%s;%s;]",
 | 
			
		||||
			ui_peruser.page_buttons_x + ui_peruser.btn_spc*bn,
 | 
			
		||||
			ui_peruser.page_buttons_y + ui_peruser.btn_spc,
 | 
			
		||||
			ui_peruser.btn_size, ui_peruser.btn_size,
 | 
			
		||||
			b[1],b[2])
 | 
			
		||||
		formspec[n+1] = "tooltip["..b[2]..";"..F(b[3]).."]"
 | 
			
		||||
		bn = bn + 1
 | 
			
		||||
		n = n + 2
 | 
			
		||||
	end
 | 
			
		||||
	n = n+3
 | 
			
		||||
 | 
			
		||||
	local no_matches = S("No matching items")
 | 
			
		||||
	if draw_lite_mode then
 | 
			
		||||
@@ -210,23 +163,23 @@ function unified_inventory.get_formspec(player, page)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Items list
 | 
			
		||||
	if #unified_inventory.filtered_items_list[player_name] == 0 then
 | 
			
		||||
		formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";" .. F(no_matches) .. "]"
 | 
			
		||||
	if #ui.filtered_items_list[player_name] == 0 then
 | 
			
		||||
		formspec[n] = "label["..ui_peruser.page_x..","..(ui_peruser.page_y+0.15)..";" .. F(no_matches) .. "]"
 | 
			
		||||
	else
 | 
			
		||||
		local dir = unified_inventory.active_search_direction[player_name]
 | 
			
		||||
		local list_index = unified_inventory.current_index[player_name]
 | 
			
		||||
		local dir = ui.active_search_direction[player_name]
 | 
			
		||||
		local list_index = ui.current_index[player_name]
 | 
			
		||||
		local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1)
 | 
			
		||||
		local pagemax = math.floor(
 | 
			
		||||
			(#unified_inventory.filtered_items_list[player_name] - 1)
 | 
			
		||||
			(#ui.filtered_items_list[player_name] - 1)
 | 
			
		||||
				/ (ui_peruser.items_per_page) + 1)
 | 
			
		||||
		for y = 0, ui_peruser.pagerows - 1 do
 | 
			
		||||
			for x = 0, ui_peruser.pagecols - 1 do
 | 
			
		||||
				local name = unified_inventory.filtered_items_list[player_name][list_index]
 | 
			
		||||
				local name = ui.filtered_items_list[player_name][list_index]
 | 
			
		||||
				local item = minetest.registered_items[name]
 | 
			
		||||
				if item then
 | 
			
		||||
					-- Clicked on current item: Flip crafting direction
 | 
			
		||||
					if name == unified_inventory.current_item[player_name] then
 | 
			
		||||
						local cdir = unified_inventory.current_craft_direction[player_name]
 | 
			
		||||
					if name == ui.current_item[player_name] then
 | 
			
		||||
						local cdir = ui.current_craft_direction[player_name]
 | 
			
		||||
						if cdir == "recipe" then
 | 
			
		||||
							dir = "usage"
 | 
			
		||||
						elseif cdir == "usage" then
 | 
			
		||||
@@ -234,13 +187,15 @@ function unified_inventory.get_formspec(player, page)
 | 
			
		||||
						end
 | 
			
		||||
					else
 | 
			
		||||
					-- Default: use active search direction by default
 | 
			
		||||
						dir = unified_inventory.active_search_direction[player_name]
 | 
			
		||||
						dir = ui.active_search_direction[player_name]
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					local button_name = "item_button_" .. dir .. "_"
 | 
			
		||||
						.. unified_inventory.mangle_for_formspec(name)
 | 
			
		||||
					formspec[n] = ("item_image_button[%f,%f;.81,.81;%s;%s;]"):format(
 | 
			
		||||
						8.2 + x * 0.7, ui_peruser.formspec_y + ui_peruser.page_y + y * 0.7,
 | 
			
		||||
						.. ui.mangle_for_formspec(name)
 | 
			
		||||
					formspec[n] = ("item_image_button[%f,%f;%f,%f;%s;%s;]"):format(
 | 
			
		||||
						ui_peruser.page_x + x * ui_peruser.btn_spc,
 | 
			
		||||
						ui_peruser.page_y + y * ui_peruser.btn_spc,
 | 
			
		||||
						ui_peruser.btn_size, ui_peruser.btn_size,
 | 
			
		||||
						name, button_name
 | 
			
		||||
					)
 | 
			
		||||
					formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format(
 | 
			
		||||
@@ -252,26 +207,29 @@ function unified_inventory.get_formspec(player, page)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";"..F(S("Page")) .. ": "
 | 
			
		||||
			.. S("@1 of @2",page2,pagemax).."]"
 | 
			
		||||
		formspec[n] = string.format("label[%f,%f;%s: %s]",
 | 
			
		||||
			ui_peruser.page_x, ui_peruser.form_header_y,
 | 
			
		||||
			F(S("Page")), S("@1 of @2",page2,pagemax))
 | 
			
		||||
	end
 | 
			
		||||
	n= n+1
 | 
			
		||||
 | 
			
		||||
	if unified_inventory.activefilter[player_name] ~= "" then
 | 
			
		||||
		formspec[n] = "label[8.2,"..(ui_peruser.form_header_y + 0.4)..";" .. F(S("Filter")) .. ":]"
 | 
			
		||||
		formspec[n+1] = "label[9.1,"..(ui_peruser.form_header_y + 0.4)..";"..F(unified_inventory.activefilter[player_name]).."]"
 | 
			
		||||
	if ui.activefilter[player_name] ~= "" then
 | 
			
		||||
		formspec[n] = string.format("label[%f,%f;%s:]",
 | 
			
		||||
			ui_peruser.page_x, ui_peruser.page_y - 0.65, F(S("Filter")))
 | 
			
		||||
		formspec[n+1] = string.format("label[%f,%f;%s]",
 | 
			
		||||
			ui_peruser.page_x, ui_peruser.page_y - 0.25, F(ui.activefilter[player_name]))
 | 
			
		||||
	end
 | 
			
		||||
	return table.concat(formspec, "")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.set_inventory_formspec(player, page)
 | 
			
		||||
function ui.set_inventory_formspec(player, page)
 | 
			
		||||
	if player then
 | 
			
		||||
		player:set_inventory_formspec(unified_inventory.get_formspec(player, page))
 | 
			
		||||
		player:set_inventory_formspec(ui.get_formspec(player, page))
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--apply filter to the inventory list (create filtered copy of full one)
 | 
			
		||||
function unified_inventory.apply_filter(player, filter, search_dir)
 | 
			
		||||
function ui.apply_filter(player, filter, search_dir)
 | 
			
		||||
	if not player then
 | 
			
		||||
		return false
 | 
			
		||||
	end
 | 
			
		||||
@@ -300,26 +258,26 @@ function unified_inventory.apply_filter(player, filter, search_dir)
 | 
			
		||||
				or llocaldesc and string.find(llocaldesc, lfilter, 1, true)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	unified_inventory.filtered_items_list[player_name]={}
 | 
			
		||||
	ui.filtered_items_list[player_name]={}
 | 
			
		||||
	for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
		if (not def.groups.not_in_creative_inventory
 | 
			
		||||
			or def.groups.not_in_creative_inventory == 0)
 | 
			
		||||
		and def.description
 | 
			
		||||
		and def.description ~= ""
 | 
			
		||||
		and ffilter(name, def) then
 | 
			
		||||
			table.insert(unified_inventory.filtered_items_list[player_name], name)
 | 
			
		||||
			table.insert(ui.filtered_items_list[player_name], name)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	table.sort(unified_inventory.filtered_items_list[player_name])
 | 
			
		||||
	unified_inventory.filtered_items_list_size[player_name] = #unified_inventory.filtered_items_list[player_name]
 | 
			
		||||
	unified_inventory.current_index[player_name] = 1
 | 
			
		||||
	unified_inventory.activefilter[player_name] = filter
 | 
			
		||||
	unified_inventory.active_search_direction[player_name] = search_dir
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
	unified_inventory.current_page[player_name])
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
function unified_inventory.items_in_group(groups)
 | 
			
		||||
function ui.items_in_group(groups)
 | 
			
		||||
	local items = {}
 | 
			
		||||
	for name, item in pairs(minetest.registered_items) do
 | 
			
		||||
		for _, group in pairs(groups:split(',')) do
 | 
			
		||||
@@ -331,7 +289,7 @@ function unified_inventory.items_in_group(groups)
 | 
			
		||||
	return items
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.sort_inventory(inv)
 | 
			
		||||
function ui.sort_inventory(inv)
 | 
			
		||||
	local inlist = inv:get_list("main")
 | 
			
		||||
	local typecnt = {}
 | 
			
		||||
	local typekeys = {}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								mod.conf
									
									
									
									
									
								
							
							
						
						@@ -5,3 +5,4 @@ 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.
 | 
			
		||||
"""
 | 
			
		||||
min_minetest_version = 5.4.0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										261
									
								
								register.lua
									
									
									
									
									
								
							
							
						
						@@ -1,6 +1,7 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local NS = function(s) return s end
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
minetest.register_privilege("creative", {
 | 
			
		||||
	description = S("Can use the creative inventory"),
 | 
			
		||||
@@ -12,10 +13,9 @@ minetest.register_privilege("ui_full", {
 | 
			
		||||
	give_to_singleplayer = false,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local trash = minetest.create_detached_inventory("trash", {
 | 
			
		||||
	--allow_put = function(inv, listname, index, stack, player)
 | 
			
		||||
	--	if unified_inventory.is_creative(player:get_player_name()) then
 | 
			
		||||
	--	if ui.is_creative(player:get_player_name()) then
 | 
			
		||||
	--		return stack:get_count()
 | 
			
		||||
	--	else
 | 
			
		||||
	--		return 0
 | 
			
		||||
@@ -29,19 +29,19 @@ local trash = minetest.create_detached_inventory("trash", {
 | 
			
		||||
})
 | 
			
		||||
trash:set_size("main", 1)
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("craft", {
 | 
			
		||||
ui.register_button("craft", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_craft_icon.png",
 | 
			
		||||
	tooltip = S("Crafting Grid")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("craftguide", {
 | 
			
		||||
ui.register_button("craftguide", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_craftguide_icon.png",
 | 
			
		||||
	tooltip = S("Crafting Guide")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("home_gui_set", {
 | 
			
		||||
ui.register_button("home_gui_set", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_sethome_icon.png",
 | 
			
		||||
	tooltip = S("Set home position"),
 | 
			
		||||
@@ -49,8 +49,8 @@ unified_inventory.register_button("home_gui_set", {
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {home=true}) then
 | 
			
		||||
			unified_inventory.set_home(player, player:get_pos())
 | 
			
		||||
			local home = unified_inventory.home_pos[player_name]
 | 
			
		||||
			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})
 | 
			
		||||
@@ -60,7 +60,7 @@ unified_inventory.register_button("home_gui_set", {
 | 
			
		||||
		else
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
				S("You don't have the \"home\" privilege!"))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
@@ -68,7 +68,7 @@ unified_inventory.register_button("home_gui_set", {
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("home_gui_go", {
 | 
			
		||||
ui.register_button("home_gui_go", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_gohome_icon.png",
 | 
			
		||||
	tooltip = S("Go home"),
 | 
			
		||||
@@ -76,13 +76,13 @@ unified_inventory.register_button("home_gui_go", {
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {home=true}) then
 | 
			
		||||
			if unified_inventory.go_home(player) 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!"))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
@@ -90,7 +90,7 @@ unified_inventory.register_button("home_gui_go", {
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("misc_set_day", {
 | 
			
		||||
ui.register_button("misc_set_day", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_sun_icon.png",
 | 
			
		||||
	tooltip = S("Set time to day"),
 | 
			
		||||
@@ -106,7 +106,7 @@ unified_inventory.register_button("misc_set_day", {
 | 
			
		||||
		else
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
				S("You don't have the settime privilege!"))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
@@ -114,7 +114,7 @@ unified_inventory.register_button("misc_set_day", {
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("misc_set_night", {
 | 
			
		||||
ui.register_button("misc_set_night", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_moon_icon.png",
 | 
			
		||||
	tooltip = S("Set time to night"),
 | 
			
		||||
@@ -130,7 +130,7 @@ unified_inventory.register_button("misc_set_night", {
 | 
			
		||||
		else
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					S("You don't have the settime privilege!"))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
@@ -138,19 +138,19 @@ unified_inventory.register_button("misc_set_night", {
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("clear_inv", {
 | 
			
		||||
ui.register_button("clear_inv", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_trash_icon.png",
 | 
			
		||||
	tooltip = S("Clear inventory"),
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if not unified_inventory.is_creative(player_name) then
 | 
			
		||||
		if not ui.is_creative(player_name) then
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					S("This button has been disabled outside"
 | 
			
		||||
					.." of creative mode to prevent"
 | 
			
		||||
					.." accidental inventory trashing."
 | 
			
		||||
					.."\nUse the trash slot instead."))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
			ui.set_inventory_formspec(player, ui.current_page[player_name])
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		player:get_inventory():set_list("main", {})
 | 
			
		||||
@@ -159,35 +159,42 @@ unified_inventory.register_button("clear_inv", {
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
		return unified_inventory.is_creative(player:get_player_name())
 | 
			
		||||
		return ui.is_creative(player:get_player_name())
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("craft", {
 | 
			
		||||
ui.register_page("craft", {
 | 
			
		||||
	get_formspec = function(player, perplayer_formspec)
 | 
			
		||||
 | 
			
		||||
		local formspecy = perplayer_formspec.formspec_y
 | 
			
		||||
		local formheadery =  perplayer_formspec.form_header_y
 | 
			
		||||
		local formheaderx = perplayer_formspec.form_header_x
 | 
			
		||||
		local formheadery = perplayer_formspec.form_header_y
 | 
			
		||||
		local craftx = perplayer_formspec.craft_x
 | 
			
		||||
		local crafty = perplayer_formspec.craft_y
 | 
			
		||||
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		local formspec = "background[2,"..formspecy..";6,3;ui_crafting_form.png]"
 | 
			
		||||
		formspec = formspec..string.gsub(unified_inventory.standard_inv_bg, "YYY", (formspecy + 3.4))
 | 
			
		||||
		formspec = formspec.."label[0,"..formheadery..";" ..F(S("Crafting")).."]"
 | 
			
		||||
		formspec = formspec.."listcolors[#00000000;#00000000]"
 | 
			
		||||
		formspec = formspec.."list[current_player;craftpreview;6,"..formspecy..";1,1;]"
 | 
			
		||||
		formspec = formspec.."list[current_player;craft;2,"..formspecy..";3,3;]"
 | 
			
		||||
		if unified_inventory.trash_enabled or unified_inventory.is_creative(player_name) or minetest.get_player_privs(player_name).give then
 | 
			
		||||
			formspec = formspec.."label[7,"..(formspecy + 1.5)..";" .. F(S("Trash:")) .. "]"
 | 
			
		||||
			formspec = formspec.."background[7,"..(formspecy + 2)..";1,1;ui_single_slot.png]"
 | 
			
		||||
			formspec = formspec.."list[detached:trash;main;7,"..(formspecy + 2)..";1,1;]"
 | 
			
		||||
		local formspec = {
 | 
			
		||||
			perplayer_formspec.standard_inv_bg,
 | 
			
		||||
			perplayer_formspec.craft_grid,
 | 
			
		||||
			"label["..formheaderx..","..formheadery..";" ..F(S("Crafting")).."]",
 | 
			
		||||
			"listcolors[#00000000;#00000000]",
 | 
			
		||||
			"listring[current_name;craft]",
 | 
			
		||||
			"listring[current_player;main]"
 | 
			
		||||
		}
 | 
			
		||||
		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.45, crafty + 2.4, F(S("Trash:")))
 | 
			
		||||
			formspec[n+1] = ui.make_trash_slot(craftx + 6.25, crafty + 2.5)
 | 
			
		||||
			n=n + 2
 | 
			
		||||
		end
 | 
			
		||||
		formspec = formspec.."listring[current_name;craft]"
 | 
			
		||||
		formspec = formspec.."listring[current_player;main]"
 | 
			
		||||
		if unified_inventory.is_creative(player_name) then
 | 
			
		||||
			formspec = formspec.."label[0,"..(formspecy + 1.5)..";" .. F(S("Refill:")) .. "]"
 | 
			
		||||
			formspec = formspec.."list[detached:"..F(player_name).."refill;main;0,"..(formspecy +2)..";1,1;]"
 | 
			
		||||
 | 
			
		||||
		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.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.2 - ui.list_img_offset, crafty + 2.5 + ui.list_img_offset)
 | 
			
		||||
		end
 | 
			
		||||
		return {formspec=formspec}
 | 
			
		||||
		return {formspec=table.concat(formspec)}
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -206,18 +213,18 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item)
 | 
			
		||||
	local selectitem = name
 | 
			
		||||
	if name:sub(1, 6) == "group:" then
 | 
			
		||||
		local group_name = name:sub(7)
 | 
			
		||||
		local group_item = unified_inventory.get_group_item(group_name)
 | 
			
		||||
		local group_item = ui.get_group_item(group_name)
 | 
			
		||||
		show_is_group = not group_item.sole
 | 
			
		||||
		displayitem = group_item.item or "unknown"
 | 
			
		||||
		selectitem = group_item.sole and displayitem or name
 | 
			
		||||
	end
 | 
			
		||||
	local label = show_is_group and "G" or ""
 | 
			
		||||
	local buttonname = F(buttonname_prefix..unified_inventory.mangle_for_formspec(selectitem))
 | 
			
		||||
	local buttonname = F(buttonname_prefix..ui.mangle_for_formspec(selectitem))
 | 
			
		||||
	local button = string.format("item_image_button[%f,%f;%f,%f;%s;%s;%s]",
 | 
			
		||||
			x, y, w, h,
 | 
			
		||||
			F(displayitem), buttonname, label)
 | 
			
		||||
	if show_is_group then
 | 
			
		||||
		local groupstring, andcount = unified_inventory.extract_groupnames(name)
 | 
			
		||||
		local groupstring, andcount = ui.extract_groupnames(name)
 | 
			
		||||
		local grouptip
 | 
			
		||||
		if andcount == 1 then
 | 
			
		||||
			grouptip = S("Any item belonging to the @1 group", groupstring)
 | 
			
		||||
@@ -257,26 +264,33 @@ local other_dir = {
 | 
			
		||||
	usage = "recipe",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("craftguide", {
 | 
			
		||||
ui.register_page("craftguide", {
 | 
			
		||||
	get_formspec = function(player, perplayer_formspec)
 | 
			
		||||
 | 
			
		||||
		local formspecy =    perplayer_formspec.formspec_y
 | 
			
		||||
		local formheadery =  perplayer_formspec.form_header_y
 | 
			
		||||
		local craftresultx = perplayer_formspec.craft_result_x
 | 
			
		||||
		local craftresulty = perplayer_formspec.craft_result_y
 | 
			
		||||
		local craftguidex =       perplayer_formspec.craft_guide_x
 | 
			
		||||
		local craftguidey =       perplayer_formspec.craft_guide_y
 | 
			
		||||
		local craftguidearrowx =  perplayer_formspec.craft_guide_arrow_x
 | 
			
		||||
		local craftguideresultx = perplayer_formspec.craft_guide_result_x
 | 
			
		||||
		local formheaderx =       perplayer_formspec.form_header_x
 | 
			
		||||
		local formheadery =       perplayer_formspec.form_header_y
 | 
			
		||||
		local give_x =            perplayer_formspec.give_btn_x
 | 
			
		||||
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		local player_privs = minetest.get_player_privs(player_name)
 | 
			
		||||
		local fs = {
 | 
			
		||||
			string.gsub(unified_inventory.standard_inv_bg, "YYY", (formspecy + 3.4)),
 | 
			
		||||
			"label[0,"..formheadery..";" .. F(S("Crafting Guide")) .. "]",
 | 
			
		||||
 | 
			
		||||
		local formspec = {
 | 
			
		||||
			perplayer_formspec.standard_inv_bg,
 | 
			
		||||
			"label["..formheaderx..","..formheadery..";" .. F(S("Crafting Guide")) .. "]",
 | 
			
		||||
			"listcolors[#00000000;#00000000]"
 | 
			
		||||
		}
 | 
			
		||||
		local item_name = unified_inventory.current_item[player_name]
 | 
			
		||||
 | 
			
		||||
		local item_name = ui.current_item[player_name]
 | 
			
		||||
		if not item_name then
 | 
			
		||||
			return { formspec = table.concat(fs) }
 | 
			
		||||
			return { formspec = table.concat(formspec) }
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local n = 4
 | 
			
		||||
 | 
			
		||||
		local item_name_shown
 | 
			
		||||
		if minetest.registered_items[item_name]
 | 
			
		||||
				and minetest.registered_items[item_name].description then
 | 
			
		||||
@@ -286,51 +300,60 @@ unified_inventory.register_page("craftguide", {
 | 
			
		||||
			item_name_shown = item_name
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local dir = unified_inventory.current_craft_direction[player_name]
 | 
			
		||||
		local dir = ui.current_craft_direction[player_name]
 | 
			
		||||
		local rdir = dir == "recipe" and "usage" or "recipe"
 | 
			
		||||
 | 
			
		||||
		local crafts = unified_inventory.crafts_for[dir][item_name]
 | 
			
		||||
		local alternate = unified_inventory.alternate[player_name]
 | 
			
		||||
		local crafts = ui.crafts_for[dir][item_name]
 | 
			
		||||
		local alternate = ui.alternate[player_name]
 | 
			
		||||
		local alternates, craft
 | 
			
		||||
		if crafts and #crafts > 0 then
 | 
			
		||||
			alternates = #crafts
 | 
			
		||||
			craft = crafts[alternate]
 | 
			
		||||
		end
 | 
			
		||||
		local has_give = player_privs.give or unified_inventory.is_creative(player_name)
 | 
			
		||||
		local has_give = player_privs.give or ui.is_creative(player_name)
 | 
			
		||||
 | 
			
		||||
		fs[#fs + 1] = "background[0.5,"..(formspecy + 0.2)..";8,3;ui_craftguide_form.png]"
 | 
			
		||||
		fs[#fs + 1] = string.format("textarea[%f,%f;10,1;;%s: %s;]",
 | 
			
		||||
				craftresultx, craftresulty, F(role_text[dir]), item_name_shown)
 | 
			
		||||
		fs[#fs + 1] = stack_image_button(0, formspecy, 1.1, 1.1,
 | 
			
		||||
				"item_button_" .. rdir .. "_", ItemStack(item_name))
 | 
			
		||||
		formspec[n] = string.format("image[%f,%f;%f,%f;ui_crafting_arrow.png]",
 | 
			
		||||
	                            craftguidearrowx, craftguidey, ui.imgscale, ui.imgscale)
 | 
			
		||||
 | 
			
		||||
		formspec[n+1] = string.format("textarea[%f,%f;10,1;;%s: %s;]",
 | 
			
		||||
				perplayer_formspec.craft_guide_resultstr_x, perplayer_formspec.craft_guide_resultstr_y,
 | 
			
		||||
				F(role_text[dir]), item_name_shown)
 | 
			
		||||
		n = n + 2
 | 
			
		||||
 | 
			
		||||
		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.
 | 
			
		||||
			fs[#fs + 1] = "label[5.5,"..(formspecy + 2.35)..";"
 | 
			
		||||
					.. F(no_recipe_text[dir]) .. "]"
 | 
			
		||||
			local no_pos = dir == "recipe" and 4.5 or 6.5
 | 
			
		||||
			local item_pos = dir == "recipe" and 6.5 or 4.5
 | 
			
		||||
			fs[#fs + 1] = "image["..no_pos..","..formspecy..";1.1,1.1;ui_no.png]"
 | 
			
		||||
			fs[#fs + 1] = stack_image_button(item_pos, formspecy, 1.1, 1.1,
 | 
			
		||||
			formspec[n] = string.format("label[%f,%f;%s]", craftguidex+2.5, craftguidey+1.5, F(no_recipe_text[dir]))
 | 
			
		||||
			local no_pos = dir == "recipe" and (craftguidex+2.5) or craftguideresultx
 | 
			
		||||
			local item_pos = dir == "recipe" and craftguideresultx or (craftguidex+2.5)
 | 
			
		||||
			formspec[n+1] = "image["..no_pos..","..craftguidey..";1.2,1.2;ui_no.png]"
 | 
			
		||||
			formspec[n+2] = stack_image_button(item_pos, craftguidey, 1.2, 1.2,
 | 
			
		||||
				"item_button_" .. other_dir[dir] .. "_", ItemStack(item_name))
 | 
			
		||||
			if has_give then
 | 
			
		||||
				fs[#fs + 1] = "label[0," .. (formspecy + 2.10) .. ";" .. F(S("Give me:")) .. "]"
 | 
			
		||||
						.. "button[0,  " .. (formspecy + 2.7) .. ";0.6,0.5;craftguide_giveme_1;1]"
 | 
			
		||||
						.. "button[0.6," .. (formspecy + 2.7) .. ";0.7,0.5;craftguide_giveme_10;10]"
 | 
			
		||||
						.. "button[1.3," .. (formspecy + 2.7) .. ";0.8,0.5;craftguide_giveme_99;99]"
 | 
			
		||||
				formspec[n+3] = giveme_form
 | 
			
		||||
			end
 | 
			
		||||
			return { formspec = table.concat(fs) }
 | 
			
		||||
			return { formspec = table.concat(formspec) }
 | 
			
		||||
		else
 | 
			
		||||
			formspec[n] = stack_image_button(craftguideresultx, craftguidey, 1.2, 1.2,
 | 
			
		||||
					"item_button_" .. rdir .. "_", ItemStack(craft.output))
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local craft_type = unified_inventory.registered_craft_types[craft.type] or
 | 
			
		||||
				unified_inventory.craft_type_defaults(craft.type, {})
 | 
			
		||||
		local craft_type = ui.registered_craft_types[craft.type] or
 | 
			
		||||
				ui.craft_type_defaults(craft.type, {})
 | 
			
		||||
		if craft_type.icon then
 | 
			
		||||
			fs[#fs + 1] = string.format("image[%f,%f;%f,%f;%s]",
 | 
			
		||||
					5.7, (formspecy + 0.05), 0.5, 0.5, craft_type.icon)
 | 
			
		||||
			formspec[n] = string.format("image[%f,%f;%f,%f;%s]",
 | 
			
		||||
					craftguidearrowx+0.35, craftguidey, 0.5, 0.5, craft_type.icon)
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
		fs[#fs + 1] = "label[5.5,"..(formspecy + 1)..";" .. F(craft_type.description).."]"
 | 
			
		||||
		fs[#fs + 1] = stack_image_button(6.5, formspecy, 1.1, 1.1,
 | 
			
		||||
				"item_button_usage_", ItemStack(craft.output))
 | 
			
		||||
		formspec[n] = string.format("label[%f,%f;%s]", craftguidearrowx + 0.15, craftguidey + 1.4, F(craft_type.description))
 | 
			
		||||
		n = n + 1
 | 
			
		||||
 | 
			
		||||
		local display_size = craft_type.dynamic_display_size
 | 
			
		||||
				and craft_type.dynamic_display_size(craft)
 | 
			
		||||
@@ -341,11 +364,12 @@ unified_inventory.register_page("craftguide", {
 | 
			
		||||
 | 
			
		||||
		-- This keeps recipes aligned to the right,
 | 
			
		||||
		-- so that they're close to the arrow.
 | 
			
		||||
		local xoffset = 5.5
 | 
			
		||||
		local xoffset = craftguidex+3.75
 | 
			
		||||
		local bspc = 1.25
 | 
			
		||||
		-- Offset factor for crafting grids with side length > 4
 | 
			
		||||
		local of = (3/math.max(3, math.max(display_size.width, display_size.height)))
 | 
			
		||||
		local od = 0
 | 
			
		||||
		-- Minimum grid size at which size optimazation measures kick in
 | 
			
		||||
		-- Minimum grid size at which size optimization measures kick in
 | 
			
		||||
		local mini_craft_size = 6
 | 
			
		||||
		if display_size.width >= mini_craft_size then
 | 
			
		||||
			od = math.max(1, display_size.width - 2)
 | 
			
		||||
@@ -354,12 +378,12 @@ unified_inventory.register_page("craftguide", {
 | 
			
		||||
		-- Size modifier factor
 | 
			
		||||
		local sf = math.min(1, of * (1.05 + 0.05*od))
 | 
			
		||||
		-- Button size
 | 
			
		||||
		local bsize_h = 1.1 * sf
 | 
			
		||||
		local bsize_w = bsize_h
 | 
			
		||||
		if display_size.width >= mini_craft_size then
 | 
			
		||||
			bsize_w = 1.175 * sf
 | 
			
		||||
		local bsize = 1.2 * sf
 | 
			
		||||
 | 
			
		||||
		if display_size.width >= mini_craft_size then  -- it's not a normal 3x3 grid
 | 
			
		||||
			bsize = 0.8 * sf
 | 
			
		||||
		end
 | 
			
		||||
		if (bsize_h > 0.35 and display_size.width) then
 | 
			
		||||
		if (bsize > 0.35 and display_size.width) then
 | 
			
		||||
		for y = 1, display_size.height do
 | 
			
		||||
		for x = 1, display_size.width do
 | 
			
		||||
			local item
 | 
			
		||||
@@ -369,48 +393,53 @@ unified_inventory.register_page("craftguide", {
 | 
			
		||||
			-- Flipped x, used to build formspec buttons from right to left
 | 
			
		||||
			local fx = display_size.width - (x-1)
 | 
			
		||||
			-- x offset, y offset
 | 
			
		||||
			local xof = (fx-1) * of + of
 | 
			
		||||
			local yof = (y-1) * of + 1
 | 
			
		||||
			local xof = ((fx-1) * of + of) * bspc
 | 
			
		||||
			local yof = ((y-1) * of + 1) * bspc
 | 
			
		||||
			if item then
 | 
			
		||||
				fs[#fs + 1] = stack_image_button(
 | 
			
		||||
						xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h,
 | 
			
		||||
				formspec[n] = stack_image_button(
 | 
			
		||||
						xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize,
 | 
			
		||||
						"item_button_recipe_",
 | 
			
		||||
						ItemStack(item))
 | 
			
		||||
			else
 | 
			
		||||
				-- Fake buttons just to make grid
 | 
			
		||||
				fs[#fs + 1] = string.format("image_button[%f,%f;%f,%f;ui_blank_image.png;;]",
 | 
			
		||||
						xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h)
 | 
			
		||||
				formspec[n] = string.format("image_button[%f,%f;%f,%f;ui_blank_image.png;;]",
 | 
			
		||||
						xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize)
 | 
			
		||||
			end
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
		end
 | 
			
		||||
		else
 | 
			
		||||
			-- Error
 | 
			
		||||
			fs[#fs + 1] = string.format("label[2,%f;%s]",
 | 
			
		||||
				formspecy, F(S("This recipe is too@nlarge to be displayed.")))
 | 
			
		||||
			formspec[n] = string.format("label[2,%f;%s]",
 | 
			
		||||
				craftguidey, F(S("This recipe is too@nlarge to be displayed.")))
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if craft_type.uses_crafting_grid and display_size.width <= 3 then
 | 
			
		||||
			fs[#fs + 1] = "label[0," .. (formspecy + 0.9) .. ";" .. F(S("To craft grid:")) .. "]"
 | 
			
		||||
					.. "button[0,  " .. (formspecy + 1.5) .. ";0.6,0.5;craftguide_craft_1;1]"
 | 
			
		||||
					.. "button[0.6," .. (formspecy + 1.5) .. ";0.7,0.5;craftguide_craft_10;10]"
 | 
			
		||||
					.. "button[1.3," .. (formspecy + 1.5) .. ";0.8,0.5;craftguide_craft_max;" .. F(S("All")) .. "]"
 | 
			
		||||
			formspec[n]   = "label["..(give_x+0.1)..","..    (craftguidey + 1.7) .. ";" .. F(S("To craft grid:")) .. "]"
 | 
			
		||||
			formspec[n+1] = "button["..  (give_x)..","..     (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_1;1]"
 | 
			
		||||
			formspec[n+2] = "button["..  (give_x+0.8)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_10;10]"
 | 
			
		||||
			formspec[n+3] = "button["..  (give_x+1.6)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_max;" .. F(S("All")) .. "]"
 | 
			
		||||
			n = n + 4
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if has_give then
 | 
			
		||||
			fs[#fs + 1] = "label[0," .. (formspecy + 2.1) .. ";" .. F(S("Give me:")) .. "]"
 | 
			
		||||
					.. "button[0,  " .. (formspecy + 2.7) .. ";0.6,0.5;craftguide_giveme_1;1]"
 | 
			
		||||
					.. "button[0.6," .. (formspecy + 2.7) .. ";0.7,0.5;craftguide_giveme_10;10]"
 | 
			
		||||
					.. "button[1.3," .. (formspecy + 2.7) .. ";0.8,0.5;craftguide_giveme_99;99]"
 | 
			
		||||
			formspec[n] = giveme_form
 | 
			
		||||
			n = n + 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if alternates and alternates > 1 then
 | 
			
		||||
			fs[#fs + 1] = "label[5.5," .. (formspecy + 1.6) .. ";"
 | 
			
		||||
					.. F(S(recipe_text[dir], alternate, alternates)) .. "]"
 | 
			
		||||
					.. "image_button[5.5," .. (formspecy + 2) .. ";1,1;ui_left_icon.png;alternate_prev;]"
 | 
			
		||||
					.. "image_button[6.5," .. (formspecy + 2) .. ";1,1;ui_right_icon.png;alternate;]"
 | 
			
		||||
					.. "tooltip[alternate_prev;" .. F(prev_alt_text[dir]) .. "]"
 | 
			
		||||
					.. "tooltip[alternate;" .. F(next_alt_text[dir]) .. "]"
 | 
			
		||||
			formspec[n] = string.format("label[%f,%f;%s]",
 | 
			
		||||
						craftguidex+4, craftguidey + 2.3, F(S(recipe_text[dir], alternate, alternates)))
 | 
			
		||||
			formspec[n+1] = string.format("image_button[%f,%f;1.1,1.1;ui_left_icon.png;alternate_prev;]",
 | 
			
		||||
						craftguidearrowx+0.2, craftguidey + 2.6)
 | 
			
		||||
			formspec[n+2] = string.format("image_button[%f,%f;1.1,1.1;ui_right_icon.png;alternate;]",
 | 
			
		||||
						craftguidearrowx+1.35, craftguidey + 2.6)
 | 
			
		||||
			formspec[n+3] = "tooltip[alternate_prev;" .. F(prev_alt_text[dir]) .. "]"
 | 
			
		||||
			formspec[n+4] = "tooltip[alternate;" .. F(next_alt_text[dir]) .. "]"
 | 
			
		||||
		end
 | 
			
		||||
		return { formspec = table.concat(fs) }
 | 
			
		||||
 | 
			
		||||
		return { formspec = table.concat(formspec) }
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -418,7 +447,7 @@ local function craftguide_giveme(player, formname, fields)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local player_privs = minetest.get_player_privs(player_name)
 | 
			
		||||
	if not player_privs.give and
 | 
			
		||||
			not unified_inventory.is_creative(player_name) then
 | 
			
		||||
			not ui.is_creative(player_name) then
 | 
			
		||||
		minetest.log("action", "[unified_inventory] Denied give action to player " ..
 | 
			
		||||
			player_name)
 | 
			
		||||
		return
 | 
			
		||||
@@ -433,7 +462,7 @@ local function craftguide_giveme(player, formname, fields)
 | 
			
		||||
	amount = tonumber(amount) or 0
 | 
			
		||||
	if amount == 0 then return end
 | 
			
		||||
 | 
			
		||||
	local output = unified_inventory.current_item[player_name]
 | 
			
		||||
	local output = ui.current_item[player_name]
 | 
			
		||||
	if (not output) or (output == "") then return end
 | 
			
		||||
 | 
			
		||||
	local player_inv = player:get_inventory()
 | 
			
		||||
@@ -454,21 +483,21 @@ local function craftguide_craft(player, formname, fields)
 | 
			
		||||
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	local output = unified_inventory.current_item[player_name] or ""
 | 
			
		||||
	local output = ui.current_item[player_name] or ""
 | 
			
		||||
	if output == "" then return end
 | 
			
		||||
 | 
			
		||||
	local crafts = unified_inventory.crafts_for[
 | 
			
		||||
		unified_inventory.current_craft_direction[player_name]][output] or {}
 | 
			
		||||
	local crafts = ui.crafts_for[
 | 
			
		||||
		ui.current_craft_direction[player_name]][output] or {}
 | 
			
		||||
	if #crafts == 0 then return end
 | 
			
		||||
 | 
			
		||||
	local alternate = unified_inventory.alternate[player_name]
 | 
			
		||||
	local alternate = ui.alternate[player_name]
 | 
			
		||||
 | 
			
		||||
	local craft = crafts[alternate]
 | 
			
		||||
	if craft.width > 3 then return end
 | 
			
		||||
 | 
			
		||||
	unified_inventory.craftguide_match_craft(player, "main", "craft", craft, amount)
 | 
			
		||||
	ui.craftguide_match_craft(player, "main", "craft", craft, amount)
 | 
			
		||||
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player, "craft")
 | 
			
		||||
	ui.set_inventory_formspec(player, "craft")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 3.3 KiB  | 
| 
		 Before Width: | Height: | Size: 2.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.1 KiB  | 
| 
		 Before Width: | Height: | Size: 962 B  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_crafting_arrow.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 788 B  | 
| 
		 Before Width: | Height: | Size: 2.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1003 B  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_formbg_9_sliced.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 240 B  | 
| 
		 Before Width: | Height: | Size: 4.4 KiB  | 
| 
		 Before Width: | Height: | Size: 5.7 KiB  | 
| 
		 Before Width: | Height: | Size: 629 B After Width: | Height: | Size: 648 B  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_single_slot_bright.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_trash_slot_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.0 KiB  | 
| 
		 Before Width: | Height: | Size: 8.4 KiB  | 
| 
		 Before Width: | Height: | Size: 2.1 KiB  | 
							
								
								
									
										127
									
								
								waypoints.lua
									
									
									
									
									
								
							
							
						
						@@ -1,5 +1,6 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
local ui = unified_inventory
 | 
			
		||||
 | 
			
		||||
local hud_colors = {
 | 
			
		||||
	{"#FFFFFF", 0xFFFFFF, S("White")},
 | 
			
		||||
@@ -14,28 +15,38 @@ local hud_colors_max = #hud_colors
 | 
			
		||||
-- Stores temporary player data (persists until player leaves)
 | 
			
		||||
local waypoints_temp = {}
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("waypoints", {
 | 
			
		||||
ui.register_page("waypoints", {
 | 
			
		||||
	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
 | 
			
		||||
		local wp_bottom_row = ui.style_full.std_inv_y - 1
 | 
			
		||||
		local wp_buttons_rj = ui.style_full.std_inv_x + 10.1 - ui.style_full.btn_spc
 | 
			
		||||
		local wp_edit_w = ui.style_full.btn_spc * 4 - 0.1
 | 
			
		||||
 | 
			
		||||
		-- build a "fake" temp entry if the server took too long
 | 
			
		||||
		-- during sign-on and returned an empty entry
 | 
			
		||||
		if not waypoints_temp[player_name] then waypoints_temp[player_name] = {hud = 1} end
 | 
			
		||||
 | 
			
		||||
		local waypoints = datastorage.get(player_name, "waypoints")
 | 
			
		||||
		local formspec = string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4") ..
 | 
			
		||||
			"image[0,0;1,1;ui_waypoints_icon.png]" ..
 | 
			
		||||
			"label[1,0;" .. F(S("Waypoints")) .. "]"
 | 
			
		||||
		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=4
 | 
			
		||||
 | 
			
		||||
		-- Tabs buttons:
 | 
			
		||||
		for i = 1, 5, 1 do
 | 
			
		||||
			formspec = formspec ..
 | 
			
		||||
				"image_button[0.0," .. 0.2 + i * 0.7 .. ";.8,.8;" ..
 | 
			
		||||
				(i == waypoints.selected and "ui_blue_icon_background.png^" or "") ..
 | 
			
		||||
				"ui_" .. i .. "_icon.png;" ..
 | 
			
		||||
				"select_waypoint" .. i .. ";]" ..
 | 
			
		||||
				"tooltip[select_waypoint" .. i .. ";"
 | 
			
		||||
					.. S("Select Waypoint #@1", i).."]"
 | 
			
		||||
		for i = 1, 5 do
 | 
			
		||||
			local sw="select_waypoint"..i
 | 
			
		||||
			formspec[n] = string.format("image_button[%f,%f;%f,%f;%sui_%i_icon.png;%s;]",
 | 
			
		||||
				ui.style_full.main_button_x, wp_bottom_row - (5-i) * ui.style_full.btn_spc,
 | 
			
		||||
				ui.style_full.btn_size, ui.style_full.btn_size,
 | 
			
		||||
				(i == waypoints.selected) and "ui_blue_icon_background.png^" or "",
 | 
			
		||||
				i, sw)
 | 
			
		||||
			formspec[n+1] = "tooltip["..sw..";"..S("Select Waypoint #@1", i).."]"
 | 
			
		||||
			n = n + 2
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local i = waypoints.selected or 1
 | 
			
		||||
@@ -44,72 +55,58 @@ unified_inventory.register_page("waypoints", {
 | 
			
		||||
		local default_name = S("Waypoint @1", i)
 | 
			
		||||
 | 
			
		||||
		-- Main buttons:
 | 
			
		||||
		formspec = formspec ..
 | 
			
		||||
			"image_button[4.5,3.7;.8,.8;"..
 | 
			
		||||
			"ui_waypoint_set_icon.png;"..
 | 
			
		||||
			"set_waypoint"..i..";]"..
 | 
			
		||||
			"tooltip[set_waypoint" .. i .. ";"
 | 
			
		||||
				.. F(S("Set waypoint to current location")).."]"
 | 
			
		||||
		local btnlist = {
 | 
			
		||||
			{ "ui_waypoint_set_icon.png", "set_waypoint", S("Set waypoint to current location") },
 | 
			
		||||
			{ waypoint.active and "ui_on_icon.png" or "ui_off_icon.png", "toggle_waypoint", S("Make waypoint @1", waypoint.active and "invisible" or "visible") },
 | 
			
		||||
			{ 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_display_pos", S("@1 display of waypoint coordinates", waypoint.display_pos and "Disable" or "Enable") },
 | 
			
		||||
			{ "ui_circular_arrows_icon.png", "toggle_color", S("Change color of waypoint display") },
 | 
			
		||||
			{ "ui_pencil_icon.png", "rename_waypoint", S("Edit waypoint name") }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		formspec = formspec ..
 | 
			
		||||
			"image_button[5.2,3.7;.8,.8;"..
 | 
			
		||||
			(waypoint.active and "ui_on_icon.png" or "ui_off_icon.png")..";"..
 | 
			
		||||
			"toggle_waypoint"..i..";]"..
 | 
			
		||||
			"tooltip[toggle_waypoint" .. i .. ";"
 | 
			
		||||
				.. F(S("Make waypoint @1",
 | 
			
		||||
					waypoint.active and S("invisible") or S("visible"))).."]"
 | 
			
		||||
 | 
			
		||||
		formspec = formspec ..
 | 
			
		||||
			"image_button[5.9,3.7;.8,.8;"..
 | 
			
		||||
			(waypoint.display_pos and "ui_green_icon_background.png" or "ui_red_icon_background.png").."^ui_xyz_icon.png;"..
 | 
			
		||||
			"toggle_display_pos" .. i .. ";]"..
 | 
			
		||||
			"tooltip[toggle_display_pos" .. i .. ";"
 | 
			
		||||
				.. F(S("@1 display of waypoint coordinates",
 | 
			
		||||
					waypoint.display_pos and S("Disable") or S("Enable"))) .."]"
 | 
			
		||||
 | 
			
		||||
		formspec = formspec ..
 | 
			
		||||
			"image_button[6.6,3.7;.8,.8;"..
 | 
			
		||||
			"ui_circular_arrows_icon.png;"..
 | 
			
		||||
			"toggle_color"..i..";]"..
 | 
			
		||||
			"tooltip[toggle_color" .. i .. ";"
 | 
			
		||||
				.. F(S("Change color of waypoint display")).."]"
 | 
			
		||||
 | 
			
		||||
		formspec = formspec ..
 | 
			
		||||
			"image_button[7.3,3.7;.8,.8;"..
 | 
			
		||||
			"ui_pencil_icon.png;"..
 | 
			
		||||
			"rename_waypoint"..i..";]"..
 | 
			
		||||
			"tooltip[rename_waypoint" .. i .. ";"
 | 
			
		||||
				.. F(S("Edit waypoint name")).."]"
 | 
			
		||||
		local x = 4
 | 
			
		||||
		for _, b 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 * x, wp_bottom_row,
 | 
			
		||||
				ui.style_full.btn_size, ui.style_full.btn_size,
 | 
			
		||||
				b[1], b[2], i)
 | 
			
		||||
			formspec[n+1] = "tooltip["..b[2]..i..";"..F(b[3]).."]"
 | 
			
		||||
			x = x - 1
 | 
			
		||||
			n = n + 2
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		-- Waypoint's info:
 | 
			
		||||
		formspec[n] = "label["..wp_info_x..","..(wp_info_y+1.1)..";"
 | 
			
		||||
		if waypoint.active then
 | 
			
		||||
			formspec = formspec .. 	"label[1,0.8;"..F(S("Waypoint active")).."]"
 | 
			
		||||
			formspec[n+1] = F(S("Waypoint active")).."]"
 | 
			
		||||
		else
 | 
			
		||||
			formspec = formspec .. 	"label[1,0.8;"..F(S("Waypoint inactive")).."]"
 | 
			
		||||
			formspec[n+1] = F(S("Waypoint inactive")).."]"
 | 
			
		||||
		end
 | 
			
		||||
		n = n + 2
 | 
			
		||||
 | 
			
		||||
		if temp.edit then
 | 
			
		||||
			formspec = formspec ..
 | 
			
		||||
				"field[1.3,3.2;6,.8;rename_box" .. i .. ";;"
 | 
			
		||||
				..(waypoint.name or default_name).."]" ..
 | 
			
		||||
				"image_button[7.3,2.9;.8,.8;"..
 | 
			
		||||
				"ui_ok_icon.png;"..
 | 
			
		||||
				"confirm_rename"..i.. ";]"..
 | 
			
		||||
				"tooltip[confirm_rename" .. i .. ";"
 | 
			
		||||
					.. F(S("Finish editing")).."]"
 | 
			
		||||
			formspec[n] = string.format("field[%f,%f;%f,%f;rename_box%i;;%s]",
 | 
			
		||||
				wp_buttons_rj - wp_edit_w - 0.1, wp_bottom_row - ui.style_full.btn_spc,
 | 
			
		||||
				wp_edit_w, ui.style_full.btn_size, i, (waypoint.name or default_name))
 | 
			
		||||
			formspec[n+1] = string.format("image_button[%f,%f;%f,%f;ui_ok_icon.png;confirm_rename%i;]",
 | 
			
		||||
				wp_buttons_rj, wp_bottom_row - ui.style_full.btn_spc,
 | 
			
		||||
				ui.style_full.btn_size, ui.style_full.btn_size, i)
 | 
			
		||||
			formspec[n+2] = "tooltip[confirm_rename"..i..";"..F(S("Finish editing")).."]"
 | 
			
		||||
			n = n + 3
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		formspec = formspec .. "label[1,1.3;"..F(S("World position"))..": " ..
 | 
			
		||||
			minetest.pos_to_string(waypoint.world_pos or vector.new()) .. "]" ..
 | 
			
		||||
			"label[1,1.8;"..F(S("Name"))..": ".. (waypoint.name or default_name) .. "]" ..
 | 
			
		||||
			"label[1,2.3;"..F(S("HUD text color"))..": " ..
 | 
			
		||||
			hud_colors[waypoint.color or 1][3] .. "]"
 | 
			
		||||
		formspec[n] = string.format("label[%f,%f;%s: %s]",
 | 
			
		||||
			wp_info_x, wp_info_y+1.6, F(S("World position")),
 | 
			
		||||
			minetest.pos_to_string(waypoint.world_pos or vector.new()))
 | 
			
		||||
		formspec[n+1] = string.format("label[%f,%f;%s: %s]",
 | 
			
		||||
			wp_info_x, wp_info_y+2.10, F(S("Name")), (waypoint.name or default_name))
 | 
			
		||||
		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=formspec}
 | 
			
		||||
		return {formspec=table.concat(formspec)}
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("waypoints", {
 | 
			
		||||
ui.register_button("waypoints", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_waypoints_icon.png",
 | 
			
		||||
	tooltip = S("Waypoints"),
 | 
			
		||||
@@ -224,7 +221,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
			update_hud(player, waypoints, temp, i)
 | 
			
		||||
		end
 | 
			
		||||
		if update_formspec then
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, "waypoints")
 | 
			
		||||
			ui.set_inventory_formspec(player, "waypoints")
 | 
			
		||||
		end
 | 
			
		||||
		if hit then return end
 | 
			
		||||
	end
 | 
			
		||||
 
 | 
			
		||||