Compare commits
	
		
			197 Commits
		
	
	
		
			waypoints
			...
			9a31609cfd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9a31609cfd | |||
| 
						 | 
					04b2edceb4 | ||
| 
						 | 
					5a24e9f6fc | ||
| 
						 | 
					eb96c89b5d | ||
| 
						 | 
					606ba6a1a3 | ||
| 
						 | 
					c0bd9977be | ||
| 
						 | 
					26e0e41593 | ||
| 
						 | 
					a89245c41b | ||
| 
						 | 
					f5c982cc85 | ||
| 8e6a3740ae | |||
| 
						 | 
					05f7430216 | ||
| 
						 | 
					ca6d9a10df | ||
| 
						 | 
					4a1414bacc | ||
| 
						 | 
					8e74a80e91 | ||
| 
						 | 
					5327261718 | ||
| 
						 | 
					04b1cb9e7d | ||
| 
						 | 
					774674d0f5 | ||
| 
						 | 
					4403b696be | ||
| 
						 | 
					a70ffb1509 | ||
| 
						 | 
					86d2a11643 | ||
| 1fd87f5c51 | |||
| e5dc9ed53a | |||
| 
						 | 
					16babc54f3 | ||
| 
						 | 
					4d5e883629 | ||
| 
						 | 
					b871ccfc41 | ||
| 
						 | 
					e9b4b52dc1 | ||
| 
						 | 
					bcb96d6caf | ||
| 
						 | 
					850ee9cbc0 | ||
| 
						 | 
					4bf5f22696 | ||
| 
						 | 
					4f666f93d0 | ||
| 
						 | 
					54abad72f0 | ||
| 
						 | 
					264833ed41 | ||
| 
						 | 
					77c3de08ce | ||
| 
						 | 
					5cff869c27 | ||
| 
						 | 
					79e4a49c6b | ||
| 
						 | 
					9ffe40d210 | ||
| 
						 | 
					3988f4c572 | ||
| 
						 | 
					edd00f222c | ||
| 
						 | 
					c43074f5c2 | ||
| 
						 | 
					934757edd6 | ||
| 
						 | 
					ab20e43468 | ||
| 
						 | 
					1a52f33756 | ||
| 
						 | 
					87ae46b6d8 | ||
| 
						 | 
					827e544c58 | ||
| 
						 | 
					0288d558e9 | ||
| 
						 | 
					2159dd5a4a | ||
| 
						 | 
					72ca872002 | ||
| 
						 | 
					06f6d45891 | ||
| 
						 | 
					c1ab7277ab | ||
| 
						 | 
					2ab5a7c90a | ||
| 
						 | 
					86c73a4752 | ||
| 
						 | 
					4010953888 | ||
| 
						 | 
					4df1aa7492 | ||
| 
						 | 
					fc36b3ff3b | ||
| 
						 | 
					f23f0733a6 | ||
| 
						 | 
					8073df0134 | ||
| 
						 | 
					0764000d99 | ||
| 
						 | 
					cff06ab167 | ||
| 
						 | 
					7ab8825460 | ||
| 
						 | 
					e8529e7742 | ||
| 
						 | 
					3209033051 | ||
| 
						 | 
					2ea417fad0 | ||
| 
						 | 
					be00ffe913 | ||
| 
						 | 
					10c22c0032 | ||
| 
						 | 
					e6c380d8c5 | ||
| 
						 | 
					4a22f8e4da | ||
| 
						 | 
					2e00206f58 | ||
| 
						 | 
					e57a5f80b4 | ||
| 
						 | 
					2fb61ca7fb | ||
| 
						 | 
					41e9d43608 | ||
| 
						 | 
					8073a3d167 | ||
| 
						 | 
					029d5c4c6a | ||
| 
						 | 
					59f52fd481 | ||
| 
						 | 
					020732a954 | ||
| 
						 | 
					75a0e6a318 | ||
| 
						 | 
					8770b7df93 | ||
| 
						 | 
					a661f54e72 | ||
| 
						 | 
					8e98b00021 | ||
| 
						 | 
					5b9a53bf29 | ||
| 
						 | 
					f6ea3daef7 | ||
| 
						 | 
					15f5b8e804 | ||
| 
						 | 
					c9d7942840 | ||
| 
						 | 
					40f8b4d9cf | ||
| 
						 | 
					7224299e7c | ||
| 
						 | 
					2a516ac22b | ||
| 
						 | 
					dba69b1f71 | ||
| 
						 | 
					0678056716 | ||
| 
						 | 
					5d67d36396 | ||
| 
						 | 
					3bc3fae648 | ||
| 
						 | 
					2ef76af687 | ||
| 
						 | 
					c1fcc06059 | ||
| 
						 | 
					f8082a0e35 | ||
| 
						 | 
					5c57915159 | ||
| 
						 | 
					fc879df761 | ||
| 
						 | 
					a1e7b650ab | ||
| 
						 | 
					23a27b38ae | ||
| 
						 | 
					fe00059eea | ||
| 
						 | 
					32769c9f34 | ||
| 
						 | 
					54d97635ec | ||
| 
						 | 
					8332707198 | ||
| 
						 | 
					6ec72eba74 | ||
| 
						 | 
					af56ddf06b | ||
| 
						 | 
					1c5fcd18ca | ||
| 
						 | 
					80f99cffe7 | ||
| 
						 | 
					09c731cee0 | ||
| 
						 | 
					08d8d99ab3 | ||
| 
						 | 
					7bba35a911 | ||
| 
						 | 
					1c11de10d5 | ||
| 
						 | 
					c816666945 | ||
| 
						 | 
					534c7bd92c | ||
| 
						 | 
					2a18e7357d | ||
| 
						 | 
					8ffc8e9323 | ||
| 
						 | 
					bb19ab97fe | ||
| 
						 | 
					7c822a79be | ||
| 
						 | 
					8f14d41706 | ||
| 
						 | 
					115e0bfaf4 | ||
| 
						 | 
					1413f760bc | ||
| 
						 | 
					7d039147e7 | ||
| 
						 | 
					5da8914da9 | ||
| 
						 | 
					ea5ffafb9c | ||
| 
						 | 
					8c0d0309f1 | ||
| 
						 | 
					5aab3640ec | ||
| 
						 | 
					310ec1da81 | ||
| 
						 | 
					1b40a02f1c | ||
| 
						 | 
					1645d17c97 | ||
| 
						 | 
					f23b4aed65 | ||
| 
						 | 
					bae55eb7c6 | ||
| 
						 | 
					3cdfdd14a5 | ||
| 
						 | 
					bdf9b61779 | ||
| 
						 | 
					758b643c4d | ||
| 
						 | 
					b3c6c92286 | ||
| 
						 | 
					8f91abbfb8 | ||
| 
						 | 
					f3127e9d7c | ||
| 
						 | 
					df1309a6fd | ||
| 
						 | 
					9bc6301f60 | ||
| 
						 | 
					5df353c299 | ||
| 
						 | 
					9fe84789ba | ||
| 
						 | 
					babe4380ac | ||
| 
						 | 
					570d2cb162 | ||
| 
						 | 
					2d6a0ed606 | ||
| 
						 | 
					f2914b3d4f | ||
| 
						 | 
					56892b8e75 | ||
| 
						 | 
					2355dc6fc2 | ||
| 
						 | 
					8338b406d3 | ||
| 
						 | 
					16e40a2e22 | ||
| 
						 | 
					0a70d8edef | ||
| 
						 | 
					20eba2bf9b | ||
| 
						 | 
					7d8b5f3760 | ||
| 
						 | 
					8bb1c8288b | ||
| 
						 | 
					75f719507e | ||
| 
						 | 
					d5d97e7dca | ||
| 
						 | 
					12f14d7aff | ||
| 
						 | 
					2fd9e59242 | ||
| 
						 | 
					76a9efff71 | ||
| 
						 | 
					1a1bfc3839 | ||
| 
						 | 
					1a962542e6 | ||
| 
						 | 
					4bae2c7fa3 | ||
| 
						 | 
					9672ec599e | ||
| 
						 | 
					4fce317e2e | ||
| 
						 | 
					527812fa96 | ||
| 
						 | 
					0d777362f3 | ||
| 
						 | 
					f800f39083 | ||
| 
						 | 
					810f342458 | ||
| 
						 | 
					002bcbb6d8 | ||
| 
						 | 
					87f502a259 | ||
| 
						 | 
					c33efe8631 | ||
| 
						 | 
					4c982dd667 | ||
| 
						 | 
					a8c8ef0890 | ||
| 
						 | 
					dbf98cb694 | ||
| 
						 | 
					7f4f0fd225 | ||
| 
						 | 
					833a255ad4 | ||
| 
						 | 
					b46f4217ae | ||
| 
						 | 
					3003b19322 | ||
| 
						 | 
					44d967bbe5 | ||
| 
						 | 
					82d204cb7a | ||
| 
						 | 
					6780ae4abd | ||
| 
						 | 
					3f8a7fb816 | ||
| 
						 | 
					043f608145 | ||
| 
						 | 
					ba956d6838 | ||
| 
						 | 
					b9b2892f28 | ||
| 
						 | 
					79320c109c | ||
| 
						 | 
					12ef7f6393 | ||
| 
						 | 
					b492701915 | ||
| 
						 | 
					5d34b235dd | ||
| 
						 | 
					b3d83bc953 | ||
| 
						 | 
					d1e554b73d | ||
| 
						 | 
					580a832fda | ||
| 
						 | 
					48d28b1e5d | ||
| 
						 | 
					87cfad559b | ||
| 
						 | 
					37d87d6afc | ||
| 
						 | 
					b0e10d44f4 | ||
| 
						 | 
					01297996a6 | ||
| 
						 | 
					20cf474886 | ||
| 
						 | 
					76a2337c59 | ||
| 
						 | 
					5e52f3c49c | ||
| 
						 | 
					910c9fad5b | ||
| 
						 | 
					fa0142c2c0 | 
							
								
								
									
										11
									
								
								.github/workflows/check-release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,11 @@
 | 
			
		||||
on: [push, pull_request]
 | 
			
		||||
name: Check & Release
 | 
			
		||||
jobs:
 | 
			
		||||
  lint:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@master
 | 
			
		||||
      - name: lint
 | 
			
		||||
        uses: Roang-zero1/factorio-mod-luacheck@master
 | 
			
		||||
        with:
 | 
			
		||||
          luacheckrc_url: https://raw.githubusercontent.com/minetest-mods/unified_inventory/master/.luacheckrc
 | 
			
		||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
			
		||||
*~
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								.luacheckrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,20 @@
 | 
			
		||||
unused_args = false
 | 
			
		||||
allow_defined_top = true
 | 
			
		||||
max_line_length = 999
 | 
			
		||||
 | 
			
		||||
globals = {
 | 
			
		||||
	"unified_inventory",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
read_globals = {
 | 
			
		||||
	string = {fields = {"split", "trim"}},
 | 
			
		||||
	table = {fields = {"copy", "getn"}},
 | 
			
		||||
 | 
			
		||||
	"minetest", "vector",
 | 
			
		||||
	"ItemStack", "datastorage",
 | 
			
		||||
 | 
			
		||||
	"hb",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
files["callbacks.lua"].ignore = { "player", "draw_lite_mode" }
 | 
			
		||||
files["bags.lua"].ignore = { "player" }
 | 
			
		||||
							
								
								
									
										19
									
								
								LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,19 @@
 | 
			
		||||
Unified Inventory for Minetest
 | 
			
		||||
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
 | 
			
		||||
 | 
			
		||||
This library is free software; you can redistribute it and/or
 | 
			
		||||
modify it under the terms of the GNU Library General Public
 | 
			
		||||
License as published by the Free Software Foundation; either
 | 
			
		||||
version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This library is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
Library General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU Library General Public
 | 
			
		||||
License along with this library; if not, write to the Free Software
 | 
			
		||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
 | 
			
		||||
Contact information:
 | 
			
		||||
	Examine a git patch to get the contributor's email address.
 | 
			
		||||
							
								
								
									
										101
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@@ -1,6 +1,99 @@
 | 
			
		||||
unified_inventory
 | 
			
		||||
=================
 | 
			
		||||
# Unified Inventory
 | 
			
		||||
 | 
			
		||||
Replacement for Minetest creative inventory.
 | 
			
		||||
[](https://github.com/minetest-mods/unified_inventory/actions)
 | 
			
		||||
 | 
			
		||||
Unified Inventory replaces the survival and creative inventory; it also functions as a crafting guide.
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Unified Inventory replaces the default survival and creative inventory.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
 * Node, item and tool browser
 | 
			
		||||
 * Crafting guide
 | 
			
		||||
    * Can copy the recipe to the crafting grid
 | 
			
		||||
    * Recipe search function by ingredients
 | 
			
		||||
 * Up to four bags with up to 24 slots each
 | 
			
		||||
 * Home function to teleport
 | 
			
		||||
 * Trash slot
 | 
			
		||||
 * Lite mode: reduces the item browser width
 | 
			
		||||
    * `minetest.conf` setting `unified_inventory_lite = true`
 | 
			
		||||
 * Mod API for modders: see [mod_api.txt](doc/mod_api.txt)
 | 
			
		||||
 * Setting-determinated features: see [settingtypes.txt](settingtypes.txt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Requirements
 | 
			
		||||
 | 
			
		||||
 * Minetest 5.0.0+
 | 
			
		||||
 | 
			
		||||
# Licenses
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2012-? Various minetest-mods contributors
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Code
 | 
			
		||||
 | 
			
		||||
GNU LGPLv2+, see [license notice](LICENSE.txt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Textures
 | 
			
		||||
 | 
			
		||||
VanessaE: (CC-BY-4.0)
 | 
			
		||||
 | 
			
		||||
  * `ui_group.png`
 | 
			
		||||
 | 
			
		||||
Tango Project: (Public Domain, CC-BY-4.0)
 | 
			
		||||
 | 
			
		||||
  * [`ui_reset_icon.png`](https://commons.wikimedia.org/wiki/File:Edit-clear.svg)
 | 
			
		||||
  * [`ui_doubleleft_icon.png`](http://commons.wikimedia.org/wiki/File:Media-seek-backward.svg)
 | 
			
		||||
  * [`ui_doubleright_icon.png`](http://commons.wikimedia.org/wiki/File:Media-seek-forward.svg)
 | 
			
		||||
  * [`ui_left_icon.png` / `ui_right_icon.png`](http://commons.wikimedia.org/wiki/File:Media-playback-start.svg)
 | 
			
		||||
  * [`ui_skip_backward_icon.png`](http://commons.wikimedia.org/wiki/File:Media-skip-backward.svg)
 | 
			
		||||
  * [`ui_skip_forward_icon.png`](http://commons.wikimedia.org/wiki/File:Media-skip-forward.svg)
 | 
			
		||||
 | 
			
		||||
From http://www.clker.com (Public Domain, CC-BY-4.0):
 | 
			
		||||
 | 
			
		||||
  * [`bags_small.png`](http://www.clker.com/clipart-moneybag-empty.html)
 | 
			
		||||
  * [`bags_medium.png`](http://www.clker.com/clipart-backpack-1.html)
 | 
			
		||||
  * [`bags_large.png` / `ui_bags_icon.png`](http://www.clker.com/clipart-backpack-green-brown.html)
 | 
			
		||||
  * `ui_trash_icon.png`: <http://www.clker.com/clipart-29090.html> and <http://www.clker.com/clipart-trash.html>
 | 
			
		||||
  * [`ui_search_icon.png`](http://www.clker.com/clipart-24887.html)
 | 
			
		||||
  * [`ui_off_icon.png` / `ui_on_icon.png`](http://www.clker.com/clipart-on-off-switches.html)
 | 
			
		||||
  * [`ui_waypoints_icon.png`](http://www.clker.com/clipart-map-pin-red.html)
 | 
			
		||||
  * [`ui_circular_arrows_icon.png`](http://www.clker.com/clipart-circular-arrow-pattern.html)
 | 
			
		||||
  * [`ui_pencil_icon.pnc`](http://www.clker.com/clipart-2256.html)
 | 
			
		||||
  * [`ui_waypoint_set_icon.png`](http://www.clker.com/clipart-larger-flag.html)
 | 
			
		||||
 | 
			
		||||
Everaldo Coelho (YellowIcon) (LGPL v2.1+):
 | 
			
		||||
 | 
			
		||||
  * [`ui_craftguide_icon.png` / `ui_craft_icon.png`](http://commons.wikimedia.org/wiki/File:Advancedsettings.png)
 | 
			
		||||
 | 
			
		||||
Gregory H. Revera: (CC-BY-SA 3.0)
 | 
			
		||||
 | 
			
		||||
  * [`ui_moon_icon.png`](http://commons.wikimedia.org/wiki/File:FullMoon2010.jpg)
 | 
			
		||||
 | 
			
		||||
Thomas Bresson: (CC-BY 3.0)
 | 
			
		||||
 | 
			
		||||
  * [`ui_sun_icon.png`](http://commons.wikimedia.org/wiki/File:2012-10-13_15-29-35-sun.jpg)
 | 
			
		||||
 | 
			
		||||
Fibonacci: (Public domain, CC-BY 4.0)
 | 
			
		||||
 | 
			
		||||
  * [`ui_xyz_off_icon.png`](http://commons.wikimedia.org/wiki/File:No_sign.svg)
 | 
			
		||||
 | 
			
		||||
Gregory Maxwell: (Public domain, CC-BY 4.0)
 | 
			
		||||
 | 
			
		||||
  * [`ui_ok_icon.png`](http://commons.wikimedia.org/wiki/File:Yes_check.svg)
 | 
			
		||||
 | 
			
		||||
Adrien Facélina: (LGPL v2.1+)
 | 
			
		||||
 | 
			
		||||
  * [`inventory_plus_worldedit_gui.png`](http://commons.wikimedia.org/wiki/File:Erioll_world_2.svg)
 | 
			
		||||
 | 
			
		||||
Other files from Wikimedia Commons:
 | 
			
		||||
 | 
			
		||||
  * [`ui_gohome_icon.png` / `ui_home_icon.png` / `ui_sethome_icon.png`](http://commons.wikimedia.org/wiki/File:Home_256x256.png) (GPL v2+)
 | 
			
		||||
 | 
			
		||||
RealBadAngel: (CC-BY-4.0)
 | 
			
		||||
 | 
			
		||||
  * Everything else.
 | 
			
		||||
							
								
								
									
										275
									
								
								api.lua
									
									
									
									
									
								
							
							
						
						@@ -1,89 +1,295 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
 | 
			
		||||
-- Create detached creative inventory after loading all mods
 | 
			
		||||
minetest.after(0.01, function()
 | 
			
		||||
	local rev_aliases = {}
 | 
			
		||||
	for source, target in pairs(minetest.registered_aliases) do
 | 
			
		||||
		if not rev_aliases[target] then rev_aliases[target] = {} end
 | 
			
		||||
		table.insert(rev_aliases[target], source)
 | 
			
		||||
	end
 | 
			
		||||
	unified_inventory.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)
 | 
			
		||||
			local recipes = minetest.get_all_craft_recipes(name)
 | 
			
		||||
			if recipes then
 | 
			
		||||
				unified_inventory.crafts_table[name] = recipes
 | 
			
		||||
			else
 | 
			
		||||
				unified_inventory.crafts_table[name] = {}
 | 
			
		||||
			local all_names = rev_aliases[name] or {}
 | 
			
		||||
			table.insert(all_names, name)
 | 
			
		||||
			for _, player_name in ipairs(all_names) do
 | 
			
		||||
				local recipes = minetest.get_all_craft_recipes(player_name)
 | 
			
		||||
				if recipes then
 | 
			
		||||
					for _, recipe in ipairs(recipes) do
 | 
			
		||||
 | 
			
		||||
						local unknowns
 | 
			
		||||
 | 
			
		||||
						for _,chk in pairs(recipe.items) do
 | 
			
		||||
							local groupchk = string.find(chk, "group:")
 | 
			
		||||
							if (not groupchk and not minetest.registered_items[chk])
 | 
			
		||||
							  or (groupchk and not unified_inventory.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)
 | 
			
		||||
						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
 | 
			
		||||
		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({
 | 
			
		||||
					type = "digging",
 | 
			
		||||
					items = {name},
 | 
			
		||||
					output = def.drop,
 | 
			
		||||
					width = 0,
 | 
			
		||||
				})
 | 
			
		||||
 | 
			
		||||
			end
 | 
			
		||||
		-- Complex drops. Yes, it's really complex!
 | 
			
		||||
		elseif type(def.drop) == "table" then
 | 
			
		||||
			--[[ Extract single items from the table and save them into dedicated tables
 | 
			
		||||
			to register them later, in order to avoid duplicates. These tables counts
 | 
			
		||||
			the total number of guaranteed drops and drops by chance (“maybes”) for each item.
 | 
			
		||||
			For “maybes”, the final count is the theoretical maximum number of items, not
 | 
			
		||||
			neccessarily the actual drop count. ]]
 | 
			
		||||
			local drop_guaranteed = {}
 | 
			
		||||
			local drop_maybe = {}
 | 
			
		||||
			-- This is for catching an obscure corner case: If the top items table has
 | 
			
		||||
			-- only items with rarity = 1, but max_items is set, then only the first
 | 
			
		||||
			-- max_items will be part of the drop, any later entries are logically
 | 
			
		||||
			-- impossible, so this variable is for keeping track of this
 | 
			
		||||
			local max_items_left = def.drop.max_items
 | 
			
		||||
			-- For checking whether we still encountered only guaranteed only so far;
 | 
			
		||||
			-- for the first “maybe” item it will become false which will cause ALL
 | 
			
		||||
			-- later items to be considered “maybes”.
 | 
			
		||||
			-- A common idiom is:
 | 
			
		||||
			-- { max_items 1, { items = {
 | 
			
		||||
			--	{ items={"example:1"}, rarity = 5 },
 | 
			
		||||
			-- 	{ items={"example:2"}, rarity = 1 }, }}}
 | 
			
		||||
			-- example:2 must be considered a “maybe” because max_items is set and it
 | 
			
		||||
			-- appears after a “maybe”
 | 
			
		||||
			local max_start = true
 | 
			
		||||
			-- Let's iterate through the items madness!
 | 
			
		||||
			-- Handle invalid drop entries gracefully.
 | 
			
		||||
			local drop_items = def.drop.items or { }
 | 
			
		||||
			for i=1,#drop_items do
 | 
			
		||||
				if max_items_left ~= nil and max_items_left <= 0 then break end
 | 
			
		||||
				local itit = drop_items[i]
 | 
			
		||||
				for j=1,#itit.items do
 | 
			
		||||
					local dstack = ItemStack(itit.items[j])
 | 
			
		||||
					if not dstack:is_empty() and dstack:get_name() ~= name then
 | 
			
		||||
						local dname = dstack:get_name()
 | 
			
		||||
						local dcount = dstack:get_count()
 | 
			
		||||
						-- Guaranteed drops AND we are not yet in “maybe mode”
 | 
			
		||||
						if #itit.items == 1 and itit.rarity == 1 and max_start then
 | 
			
		||||
							if drop_guaranteed[dname] == nil then
 | 
			
		||||
								drop_guaranteed[dname] = 0
 | 
			
		||||
							end
 | 
			
		||||
							drop_guaranteed[dname] = drop_guaranteed[dname] + dcount
 | 
			
		||||
 | 
			
		||||
							if max_items_left ~= nil then
 | 
			
		||||
								max_items_left = max_items_left - 1
 | 
			
		||||
								if max_items_left <= 0 then break end
 | 
			
		||||
							end
 | 
			
		||||
						-- Drop was a “maybe”
 | 
			
		||||
						else
 | 
			
		||||
							if max_items_left ~= nil then max_start = false end
 | 
			
		||||
							if drop_maybe[dname] == nil then
 | 
			
		||||
								drop_maybe[dname] = 0
 | 
			
		||||
							end
 | 
			
		||||
							drop_maybe[dname] = drop_maybe[dname] + dcount
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			for itemstring, count in pairs(drop_guaranteed) do
 | 
			
		||||
				unified_inventory.register_craft({
 | 
			
		||||
					type = "digging",
 | 
			
		||||
					items = {name},
 | 
			
		||||
					output = itemstring .. " " .. count,
 | 
			
		||||
					width = 0,
 | 
			
		||||
				})
 | 
			
		||||
			end
 | 
			
		||||
			for itemstring, count in pairs(drop_maybe) do
 | 
			
		||||
				unified_inventory.register_craft({
 | 
			
		||||
					type = "digging_chance",
 | 
			
		||||
					items = {name},
 | 
			
		||||
					output = itemstring .. " " .. count,
 | 
			
		||||
					width = 0,
 | 
			
		||||
				})
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	for _, recipes in pairs(unified_inventory.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
 | 
			
		||||
					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] = {}
 | 
			
		||||
				end
 | 
			
		||||
				table.insert(unified_inventory.crafts_for.usage[name], recipe)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- load_home
 | 
			
		||||
local function load_home()
 | 
			
		||||
	local input = io.open(unified_inventory.home_filename, "r")
 | 
			
		||||
	if input then
 | 
			
		||||
		while true do
 | 
			
		||||
			local x = input:read("*n")
 | 
			
		||||
			if x == nil then
 | 
			
		||||
				break
 | 
			
		||||
			end
 | 
			
		||||
			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}
 | 
			
		||||
		end
 | 
			
		||||
		io.close(input)
 | 
			
		||||
	else
 | 
			
		||||
	if not input then
 | 
			
		||||
		unified_inventory.home_pos = {}
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	while true do
 | 
			
		||||
		local x = input:read("*n")
 | 
			
		||||
		if not x then break end
 | 
			
		||||
		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}
 | 
			
		||||
	end
 | 
			
		||||
	io.close(input)
 | 
			
		||||
end
 | 
			
		||||
load_home()
 | 
			
		||||
 | 
			
		||||
function unified_inventory.set_home(player, pos)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	unified_inventory.home_pos[player_name] = pos
 | 
			
		||||
	unified_inventory.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
 | 
			
		||||
		if v ~= nil then
 | 
			
		||||
			output:write(math.floor(v.x).." "
 | 
			
		||||
					..math.floor(v.y).." "
 | 
			
		||||
					..math.floor(v.z).." "
 | 
			
		||||
					..k.."\n")
 | 
			
		||||
		end
 | 
			
		||||
		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()]
 | 
			
		||||
	if pos ~= nil then
 | 
			
		||||
		player:setpos(pos)
 | 
			
		||||
	if pos then
 | 
			
		||||
		player:set_pos(pos)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- register_craft
 | 
			
		||||
function unified_inventory.register_craft(options)
 | 
			
		||||
	if  options.output == nil then
 | 
			
		||||
	if not options.output then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local itemstack = ItemStack(options.output)
 | 
			
		||||
	if itemstack:is_empty() then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	if unified_inventory.crafts_table[itemstack:get_name()] == nil then
 | 
			
		||||
		unified_inventory.crafts_table[itemstack:get_name()] = {}
 | 
			
		||||
	if options.type == "normal" and options.width == 0 then
 | 
			
		||||
		options = { type = "shapeless", items = options.items, output = options.output, width = 0 }
 | 
			
		||||
	end
 | 
			
		||||
	table.insert(unified_inventory.crafts_table[itemstack:get_name()],options)
 | 
			
		||||
	if not unified_inventory.crafts_for.recipe[itemstack:get_name()] then
 | 
			
		||||
		unified_inventory.crafts_for.recipe[itemstack:get_name()] = {}
 | 
			
		||||
	end
 | 
			
		||||
	table.insert(unified_inventory.crafts_for.recipe[itemstack:get_name()],options)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local craft_type_defaults = {
 | 
			
		||||
	width = 3,
 | 
			
		||||
	height = 3,
 | 
			
		||||
	uses_crafting_grid = false,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.craft_type_defaults(name, options)
 | 
			
		||||
	if not options.description then
 | 
			
		||||
		options.description = name
 | 
			
		||||
	end
 | 
			
		||||
	setmetatable(options, {__index = craft_type_defaults})
 | 
			
		||||
	return options
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_craft_type(name, options)
 | 
			
		||||
	unified_inventory.registered_craft_types[name] =
 | 
			
		||||
			unified_inventory.craft_type_defaults(name, options)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("normal", {
 | 
			
		||||
	description = F(S("Crafting")),
 | 
			
		||||
	icon = "ui_craftgrid_icon.png",
 | 
			
		||||
	width = 3,
 | 
			
		||||
	height = 3,
 | 
			
		||||
	get_shaped_craft_width = function (craft) return craft.width end,
 | 
			
		||||
	dynamic_display_size = function (craft)
 | 
			
		||||
		local w = craft.width
 | 
			
		||||
		local h = math.ceil(table.maxn(craft.items) / craft.width)
 | 
			
		||||
		local g = w < h and h or w
 | 
			
		||||
		return { width = g, height = g }
 | 
			
		||||
	end,
 | 
			
		||||
	uses_crafting_grid = true,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("shapeless", {
 | 
			
		||||
	description = F(S("Mixing")),
 | 
			
		||||
	icon = "ui_craftgrid_icon.png",
 | 
			
		||||
	width = 3,
 | 
			
		||||
	height = 3,
 | 
			
		||||
	dynamic_display_size = function (craft)
 | 
			
		||||
		local maxn = table.maxn(craft.items)
 | 
			
		||||
		local g = 1
 | 
			
		||||
		while g*g < maxn do g = g + 1 end
 | 
			
		||||
		return { width = g, height = g }
 | 
			
		||||
	end,
 | 
			
		||||
	uses_crafting_grid = true,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("cooking", {
 | 
			
		||||
	description = F(S("Cooking")),
 | 
			
		||||
	icon = "default_furnace_front.png",
 | 
			
		||||
	width = 1,
 | 
			
		||||
	height = 1,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_craft_type("digging", {
 | 
			
		||||
	description = F(S("Digging")),
 | 
			
		||||
	icon = "default_tool_steelpick.png",
 | 
			
		||||
	width = 1,
 | 
			
		||||
	height = 1,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_button(name, def)
 | 
			
		||||
	if not def.action then
 | 
			
		||||
		def.action = function(player)
 | 
			
		||||
@@ -94,9 +300,8 @@ function unified_inventory.register_button(name, def)
 | 
			
		||||
	table.insert(unified_inventory.buttons, def)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function unified_inventory.is_creative(playername)
 | 
			
		||||
	if minetest.check_player_privs(playername, {creative=true}) or
 | 
			
		||||
	   minetest.setting_getbool("creative_mode") then
 | 
			
		||||
		return true
 | 
			
		||||
	end
 | 
			
		||||
	return minetest.check_player_privs(playername, {creative=true})
 | 
			
		||||
		or minetest.settings:get_bool("creative_mode")
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										288
									
								
								bags.lua
									
									
									
									
									
								
							
							
						
						@@ -1,48 +1,94 @@
 | 
			
		||||
-- Bags for Minetest
 | 
			
		||||
--[[
 | 
			
		||||
Bags for Minetest
 | 
			
		||||
 | 
			
		||||
-- Copyright (c) 2012 cornernote, Brett O'Donnell <cornernote@gmail.com>
 | 
			
		||||
-- License: GPLv3
 | 
			
		||||
Copyright (c) 2012 cornernote, Brett O'Donnell <cornernote@gmail.com>
 | 
			
		||||
License: GPLv3
 | 
			
		||||
--]]
 | 
			
		||||
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("bags", {
 | 
			
		||||
	get_formspec = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		local formspec = "background[0.06,0.99;7.92,7.52;ui_bags_main_form.png]"
 | 
			
		||||
		formspec = formspec.."label[0,0;Bags]"
 | 
			
		||||
		formspec = formspec.."button[0,2;2,0.5;bag1;Bag 1]"
 | 
			
		||||
		formspec = formspec.."button[2,2;2,0.5;bag2;Bag 2]"
 | 
			
		||||
		formspec = formspec.."button[4,2;2,0.5;bag3;Bag 3]"
 | 
			
		||||
		formspec = formspec.."button[6,2;2,0.5;bag4;Bag 4]"
 | 
			
		||||
		formspec = formspec.."listcolors[#00000000;#00000000]"
 | 
			
		||||
		formspec = formspec.."list[detached:"..player_name.."_bags;bag1;0.5,1;1,1;]"
 | 
			
		||||
		formspec = formspec.."list[detached:"..player_name.."_bags;bag2;2.5,1;1,1;]"
 | 
			
		||||
		formspec = formspec.."list[detached:"..player_name.."_bags;bag3;4.5,1;1,1;]"
 | 
			
		||||
		formspec = formspec.."list[detached:"..player_name.."_bags;bag4;6.5,1;1,1;]"
 | 
			
		||||
		return {formspec=formspec}
 | 
			
		||||
		return { formspec = table.concat({
 | 
			
		||||
			"background[0.06,0.99;7.92,7.52;ui_bags_main_form.png]",
 | 
			
		||||
			"label[0,0;" .. F(S("Bags")) .. "]",
 | 
			
		||||
			"button[0,2;2,0.5;bag1;" .. F(S("Bag @1", 1)) .. "]",
 | 
			
		||||
			"button[2,2;2,0.5;bag2;" .. F(S("Bag @1", 2)) .. "]",
 | 
			
		||||
			"button[4,2;2,0.5;bag3;" .. F(S("Bag @1", 3)) .. "]",
 | 
			
		||||
			"button[6,2;2,0.5;bag4;" .. F(S("Bag @1", 4)) .. "]",
 | 
			
		||||
			"listcolors[#00000000;#00000000]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag1;0.5,1;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag2;2.5,1;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag3;4.5,1;1,1;]",
 | 
			
		||||
			"list[detached:" .. F(player_name) .. "_bags;bag4;6.5,1;1,1;]"
 | 
			
		||||
		}) }
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("bags", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_bags_icon.png",
 | 
			
		||||
	tooltip = S("Bags"),
 | 
			
		||||
	hide_lite=true
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
for i = 1, 4 do
 | 
			
		||||
	unified_inventory.register_page("bag"..i, {
 | 
			
		||||
local function get_player_bag_stack(player, i)
 | 
			
		||||
	return minetest.get_inventory({
 | 
			
		||||
		type = "detached",
 | 
			
		||||
		name = player:get_player_name() .. "_bags"
 | 
			
		||||
	}):get_stack("bag" .. i, 1)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
for bag_i = 1, 4 do
 | 
			
		||||
	unified_inventory.register_page("bag" .. bag_i, {
 | 
			
		||||
		get_formspec = function(player)
 | 
			
		||||
			local stack = player:get_inventory():get_stack("bag"..i, 1)
 | 
			
		||||
			local stack = get_player_bag_stack(player, bag_i)
 | 
			
		||||
			local image = stack:get_definition().inventory_image
 | 
			
		||||
			local formspec = "image[7,0;1,1;"..image.."]"
 | 
			
		||||
			formspec = formspec.."listcolors[#00000000;#00000000]"
 | 
			
		||||
			formspec = formspec.."list[current_player;bag"..i.."contents;0,1;8,3;]"
 | 
			
		||||
			local fs = {
 | 
			
		||||
				"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;8,3;]",
 | 
			
		||||
				"listring[current_name;bag" .. bag_i .. "contents]",
 | 
			
		||||
				"listring[current_player;main]"
 | 
			
		||||
			}
 | 
			
		||||
			local slots = stack:get_definition().groups.bagslots
 | 
			
		||||
			if slots == 8 then
 | 
			
		||||
				formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_sm_form.png]"
 | 
			
		||||
					fs[#fs + 1] = "background[0.06,0.99;7.92,7.52;ui_bags_sm_form.png]"
 | 
			
		||||
			elseif slots == 16 then
 | 
			
		||||
				formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_med_form.png]"
 | 
			
		||||
					fs[#fs + 1] = "background[0.06,0.99;7.92,7.52;ui_bags_med_form.png]"
 | 
			
		||||
			elseif slots == 24 then
 | 
			
		||||
				formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_lg_form.png]"
 | 
			
		||||
					fs[#fs + 1] = "background[0.06,0.99;7.92,7.52;ui_bags_lg_form.png]"
 | 
			
		||||
			end
 | 
			
		||||
			return {formspec=formspec}
 | 
			
		||||
			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] = "background[6.06,0;0.92,0.92;ui_bags_trash.png]"
 | 
			
		||||
						.. "list[detached:trash;main;6,0.1;1,1;]"
 | 
			
		||||
			end
 | 
			
		||||
			local inv = player:get_inventory()
 | 
			
		||||
			for i = 1, 4 do
 | 
			
		||||
				local def = get_player_bag_stack(player, i):get_definition()
 | 
			
		||||
				if def.groups.bagslots then
 | 
			
		||||
					local list_name = "bag" .. i .. "contents"
 | 
			
		||||
					local size = inv:get_size(list_name)
 | 
			
		||||
					local used = 0
 | 
			
		||||
					for si = 1, size do
 | 
			
		||||
						local stk = inv:get_stack(list_name, si)
 | 
			
		||||
						if not stk:is_empty() then
 | 
			
		||||
							used = used + 1
 | 
			
		||||
						end
 | 
			
		||||
					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)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			return { formspec = table.concat(fs) }
 | 
			
		||||
		end,
 | 
			
		||||
	})
 | 
			
		||||
end
 | 
			
		||||
@@ -52,98 +98,178 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	for i = 1, 4 do
 | 
			
		||||
		if fields["bag"..i] then
 | 
			
		||||
			local stack = player:get_inventory():get_stack("bag"..i, 1)
 | 
			
		||||
		if fields["bag" .. i] then
 | 
			
		||||
			local stack = get_player_bag_stack(player, i)
 | 
			
		||||
			if not stack:get_definition().groups.bagslots then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, "bag"..i)
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, "bag" .. i)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
local function save_bags_metadata(player, bags_inv)
 | 
			
		||||
	local is_empty = true
 | 
			
		||||
	local bags = {}
 | 
			
		||||
	for i = 1, 4 do
 | 
			
		||||
		local bag = "bag" .. i
 | 
			
		||||
		if not bags_inv:is_empty(bag) then
 | 
			
		||||
			-- Stack limit is 1, otherwise use stack:to_string()
 | 
			
		||||
			bags[i] = bags_inv:get_stack(bag, 1):get_name()
 | 
			
		||||
			is_empty = false
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	local meta = player:get_meta()
 | 
			
		||||
	if is_empty then
 | 
			
		||||
		meta:set_string("unified_inventory:bags", nil)
 | 
			
		||||
	else
 | 
			
		||||
		meta:set_string("unified_inventory:bags",
 | 
			
		||||
			minetest.serialize(bags))
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function load_bags_metadata(player, bags_inv)
 | 
			
		||||
	local player_inv = player:get_inventory()
 | 
			
		||||
	local bags_inv = minetest.create_detached_inventory(player:get_player_name().."_bags",{
 | 
			
		||||
	local meta = player:get_meta()
 | 
			
		||||
	local bags_meta = meta:get_string("unified_inventory:bags")
 | 
			
		||||
	local bags = bags_meta and minetest.deserialize(bags_meta) or {}
 | 
			
		||||
	local dirty_meta = false
 | 
			
		||||
	if not bags_meta then
 | 
			
		||||
		-- Backwards compatiblity
 | 
			
		||||
		for i = 1, 4 do
 | 
			
		||||
			local bag = "bag" .. i
 | 
			
		||||
			if not player_inv:is_empty(bag) then
 | 
			
		||||
				-- Stack limit is 1, otherwise use stack:to_string()
 | 
			
		||||
				bags[i] = player_inv:get_stack(bag, 1):get_name()
 | 
			
		||||
				dirty_meta = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	-- Fill detached slots
 | 
			
		||||
	for i = 1, 4 do
 | 
			
		||||
		local bag = "bag" .. i
 | 
			
		||||
		bags_inv:set_size(bag, 1)
 | 
			
		||||
		bags_inv:set_stack(bag, 1, bags[i] or "")
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if dirty_meta then
 | 
			
		||||
		-- Requires detached inventory to be set up
 | 
			
		||||
		save_bags_metadata(player, bags_inv)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Clean up deprecated garbage after saving
 | 
			
		||||
	for i = 1, 4 do
 | 
			
		||||
		local bag = "bag" .. i
 | 
			
		||||
		player_inv:set_size(bag, 0)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local bags_inv = minetest.create_detached_inventory(player_name .. "_bags",{
 | 
			
		||||
		on_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			player:get_inventory():set_stack(listname, index, stack)
 | 
			
		||||
			player:get_inventory():set_size(listname.."contents",
 | 
			
		||||
			player:get_inventory():set_size(listname .. "contents",
 | 
			
		||||
					stack:get_definition().groups.bagslots)
 | 
			
		||||
		end,
 | 
			
		||||
		on_take = function(inv, listname, index, stack, player)
 | 
			
		||||
			player:get_inventory():set_stack(listname, index, nil)
 | 
			
		||||
			save_bags_metadata(player, inv)
 | 
			
		||||
		end,
 | 
			
		||||
		allow_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			if stack:get_definition().groups.bagslots then
 | 
			
		||||
			local new_slots = stack:get_definition().groups.bagslots
 | 
			
		||||
			if not new_slots then
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
			local player_inv = player:get_inventory()
 | 
			
		||||
			local old_slots = player_inv:get_size(listname .. "contents")
 | 
			
		||||
 | 
			
		||||
			if new_slots >= old_slots then
 | 
			
		||||
				return 1
 | 
			
		||||
			else
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		end,
 | 
			
		||||
		allow_take = function(inv, listname, index, stack, player)
 | 
			
		||||
			if player:get_inventory():is_empty(listname.."contents") then
 | 
			
		||||
				return stack:get_count()
 | 
			
		||||
			else
 | 
			
		||||
				return 0
 | 
			
		||||
 | 
			
		||||
			-- using a smaller bag, make sure it fits
 | 
			
		||||
			local old_list = player_inv:get_list(listname .. "contents")
 | 
			
		||||
			local new_list = {}
 | 
			
		||||
			local slots_used = 0
 | 
			
		||||
			local use_new_list = false
 | 
			
		||||
 | 
			
		||||
			for i, v in ipairs(old_list) do
 | 
			
		||||
				if v and not v:is_empty() then
 | 
			
		||||
					slots_used = slots_used + 1
 | 
			
		||||
					use_new_list = i > new_slots
 | 
			
		||||
					new_list[slots_used] = v
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end,
 | 
			
		||||
		allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
 | 
			
		||||
			if new_slots >= slots_used then
 | 
			
		||||
				if use_new_list then
 | 
			
		||||
					player_inv:set_list(listname .. "contents", new_list)
 | 
			
		||||
				end
 | 
			
		||||
				return 1
 | 
			
		||||
			end
 | 
			
		||||
			-- New bag is smaller: Disallow inserting
 | 
			
		||||
			return 0
 | 
			
		||||
		end,
 | 
			
		||||
	})
 | 
			
		||||
	for i=1,4 do
 | 
			
		||||
		local bag = "bag"..i
 | 
			
		||||
		player_inv:set_size(bag, 1)
 | 
			
		||||
		bags_inv:set_size(bag, 1)
 | 
			
		||||
		bags_inv:set_stack(bag, 1, player_inv:get_stack(bag, 1))
 | 
			
		||||
	end
 | 
			
		||||
		allow_take = function(inv, listname, index, stack, player)
 | 
			
		||||
			if player:get_inventory():is_empty(listname .. "contents") then
 | 
			
		||||
				return stack:get_count()
 | 
			
		||||
			end
 | 
			
		||||
			return 0
 | 
			
		||||
		end,
 | 
			
		||||
		on_take = function(inv, listname, index, stack, player)
 | 
			
		||||
			player:get_inventory():set_size(listname .. "contents", 0)
 | 
			
		||||
			save_bags_metadata(player, inv)
 | 
			
		||||
		end,
 | 
			
		||||
		allow_move = function()
 | 
			
		||||
			return 0
 | 
			
		||||
		end,
 | 
			
		||||
	}, player_name)
 | 
			
		||||
 | 
			
		||||
	load_bags_metadata(player, bags_inv)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
-- register bag tools
 | 
			
		||||
minetest.register_tool("unified_inventory:bag_small", {
 | 
			
		||||
	description = "Small Bag",
 | 
			
		||||
	description = S("Small Bag"),
 | 
			
		||||
	inventory_image = "bags_small.png",
 | 
			
		||||
	groups = {bagslots=8},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_tool("unified_inventory:bag_medium", {
 | 
			
		||||
	description = "Medium Bag",
 | 
			
		||||
	description = S("Medium Bag"),
 | 
			
		||||
	inventory_image = "bags_medium.png",
 | 
			
		||||
	groups = {bagslots=16},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_tool("unified_inventory:bag_large", {
 | 
			
		||||
	description = "Large Bag",
 | 
			
		||||
	description = S("Large Bag"),
 | 
			
		||||
	inventory_image = "bags_large.png",
 | 
			
		||||
	groups = {bagslots=24},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-- register bag crafts
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	output = "unified_inventory:bag_small",
 | 
			
		||||
	recipe = {
 | 
			
		||||
		{"",           "default:stick", ""},
 | 
			
		||||
		{"group:wood", "group:wood",    "group:wood"},
 | 
			
		||||
		{"group:wood", "group:wood",    "group:wood"},
 | 
			
		||||
	},
 | 
			
		||||
})
 | 
			
		||||
if minetest.get_modpath("farming") ~= nil then
 | 
			
		||||
	minetest.register_craft({
 | 
			
		||||
		output = "unified_inventory:bag_small",
 | 
			
		||||
		recipe = {
 | 
			
		||||
			{"",           "farming:string", ""},
 | 
			
		||||
			{"group:wool", "group:wool",     "group:wool"},
 | 
			
		||||
			{"group:wool", "group:wool",     "group:wool"},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	output = "unified_inventory:bag_medium",
 | 
			
		||||
	recipe = {
 | 
			
		||||
		{"",              "",                            ""},
 | 
			
		||||
		{"default:stick", "unified_inventory:bag_small", "default:stick"},
 | 
			
		||||
		{"default:stick", "unified_inventory:bag_small", "default:stick"},
 | 
			
		||||
	},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	output = "unified_inventory:bag_large",
 | 
			
		||||
	recipe = {
 | 
			
		||||
		{"",              "",                             ""},
 | 
			
		||||
		{"default:stick", "unified_inventory:bag_medium", "default:stick"},
 | 
			
		||||
		{"default:stick", "unified_inventory:bag_medium", "default:stick"},
 | 
			
		||||
    },
 | 
			
		||||
})
 | 
			
		||||
	minetest.register_craft({
 | 
			
		||||
		output = "unified_inventory:bag_medium",
 | 
			
		||||
		recipe = {
 | 
			
		||||
			{"",               "",                            ""},
 | 
			
		||||
			{"farming:string", "unified_inventory:bag_small", "farming:string"},
 | 
			
		||||
			{"farming:string", "unified_inventory:bag_small", "farming:string"},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	minetest.register_craft({
 | 
			
		||||
		output = "unified_inventory:bag_large",
 | 
			
		||||
		recipe = {
 | 
			
		||||
			{"",               "",                             ""},
 | 
			
		||||
			{"farming:string", "unified_inventory:bag_medium", "farming:string"},
 | 
			
		||||
			{"farming:string", "unified_inventory:bag_medium", "farming:string"},
 | 
			
		||||
	    },
 | 
			
		||||
	})
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										190
									
								
								callbacks.lua
									
									
									
									
									
								
							
							
						
						@@ -1,36 +1,33 @@
 | 
			
		||||
local function default_refill(stack)
 | 
			
		||||
	stack:set_count(stack:get_stack_max())
 | 
			
		||||
	local itemdef = minetest.registered_items[stack:get_name()]
 | 
			
		||||
	if itemdef
 | 
			
		||||
	and (itemdef.wear_represents or "mechanical_wear") == "mechanical_wear"
 | 
			
		||||
	and stack:get_wear() ~= 0 then
 | 
			
		||||
		stack:set_wear(0)
 | 
			
		||||
	end
 | 
			
		||||
	return stack
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	unified_inventory.players[player_name] = {}
 | 
			
		||||
	unified_inventory.current_index[player_name] = 1
 | 
			
		||||
	unified_inventory.filtered_items_list[player_name] =
 | 
			
		||||
			unified_inventory.items_list
 | 
			
		||||
	unified_inventory.items_list
 | 
			
		||||
	unified_inventory.activefilter[player_name] = ""
 | 
			
		||||
	unified_inventory.apply_filter(player, "")
 | 
			
		||||
	unified_inventory.active_search_direction[player_name] = "nochange"
 | 
			
		||||
	unified_inventory.apply_filter(player, "", "nochange")
 | 
			
		||||
	unified_inventory.current_searchbox[player_name] = ""
 | 
			
		||||
	unified_inventory.alternate[player_name] = 1
 | 
			
		||||
	unified_inventory.current_item[player_name] = nil
 | 
			
		||||
	unified_inventory.current_craft_direction[player_name] = "recipe"
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
			unified_inventory.default)
 | 
			
		||||
 | 
			
		||||
	-- Crafting guide inventories
 | 
			
		||||
	local inv = minetest.create_detached_inventory(player_name.."craftrecipe", {
 | 
			
		||||
		allow_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			return 0
 | 
			
		||||
		end,
 | 
			
		||||
		allow_take = function(inv, listname, index, stack, player)
 | 
			
		||||
			return 0
 | 
			
		||||
		end,
 | 
			
		||||
		allow_move = function(inv, from_list, from_index, to_list,
 | 
			
		||||
				to_index, count, player)
 | 
			
		||||
			return 0
 | 
			
		||||
		end,
 | 
			
		||||
	})
 | 
			
		||||
	inv:set_size("output", 1)
 | 
			
		||||
	unified_inventory.default)
 | 
			
		||||
 | 
			
		||||
	-- Refill slot
 | 
			
		||||
	local refill = minetest.create_detached_inventory(player_name.."refill", {
 | 
			
		||||
		allow_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			local player_name = player:get_player_name()
 | 
			
		||||
			if unified_inventory.is_creative(player_name) then
 | 
			
		||||
				return stack:get_count()
 | 
			
		||||
			else
 | 
			
		||||
@@ -38,21 +35,39 @@ minetest.register_on_joinplayer(function(player)
 | 
			
		||||
			end
 | 
			
		||||
		end,
 | 
			
		||||
		on_put = function(inv, listname, index, stack, player)
 | 
			
		||||
			local player_name = player:get_player_name()
 | 
			
		||||
			stack:set_count(stack:get_stack_max())
 | 
			
		||||
			local handle_refill = (minetest.registered_items[stack:get_name()] or {}).on_refill or default_refill
 | 
			
		||||
			stack = handle_refill(stack)
 | 
			
		||||
			inv:set_stack(listname, index, stack)
 | 
			
		||||
			minetest.sound_play("electricity",
 | 
			
		||||
					{to_player=player_name, gain = 1.0})
 | 
			
		||||
		end,
 | 
			
		||||
	})
 | 
			
		||||
	}, player_name)
 | 
			
		||||
	refill:set_size("main", 1)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local function apply_new_filter(player, search_text, new_dir)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	minetest.sound_play("click", {to_player=player_name, gain = 0.1})
 | 
			
		||||
	unified_inventory.apply_filter(player, search_text, new_dir)
 | 
			
		||||
	unified_inventory.current_searchbox[player_name] = search_text
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
			unified_inventory.current_page[player_name])
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
 | 
			
		||||
 | 
			
		||||
	if formname ~= "" then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	-- always take new search text, even if not searching on it yet
 | 
			
		||||
	if fields.searchbox
 | 
			
		||||
	and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
 | 
			
		||||
		unified_inventory.current_searchbox[player_name] = fields.searchbox
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	for i, def in pairs(unified_inventory.buttons) do
 | 
			
		||||
		if fields[def.name] then
 | 
			
		||||
@@ -65,40 +80,28 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
 | 
			
		||||
	-- Inventory page controls
 | 
			
		||||
	local start = math.floor(
 | 
			
		||||
		unified_inventory.current_index[player_name] / 80 + 1)
 | 
			
		||||
		unified_inventory.current_index[player_name] / ui_peruser.items_per_page + 1)
 | 
			
		||||
	local start_i = start
 | 
			
		||||
	local pagemax = math.floor(
 | 
			
		||||
		(#unified_inventory.filtered_items_list[player_name] - 1)
 | 
			
		||||
		/ (80) + 1)
 | 
			
		||||
		/ (ui_peruser.items_per_page) + 1)
 | 
			
		||||
 | 
			
		||||
	if fields.start_list then
 | 
			
		||||
		minetest.sound_play("paperflip1",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
		start_i = 1
 | 
			
		||||
	end
 | 
			
		||||
	if fields.rewind1 then
 | 
			
		||||
		minetest.sound_play("paperflip1",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
		start_i = start_i - 1
 | 
			
		||||
	end
 | 
			
		||||
	if fields.forward1 then
 | 
			
		||||
		minetest.sound_play("paperflip1",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
		start_i = start_i + 1
 | 
			
		||||
	end
 | 
			
		||||
	if fields.rewind3 then
 | 
			
		||||
		minetest.sound_play("paperflip1",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
		start_i = start_i - 3
 | 
			
		||||
	end
 | 
			
		||||
	if fields.forward3 then
 | 
			
		||||
		minetest.sound_play("paperflip1",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
		start_i = start_i + 3
 | 
			
		||||
	end
 | 
			
		||||
	if fields.end_list then
 | 
			
		||||
		minetest.sound_play("paperflip1",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
		start_i = pagemax
 | 
			
		||||
	end
 | 
			
		||||
	if start_i < 1 then
 | 
			
		||||
@@ -107,78 +110,105 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
	if start_i > pagemax then
 | 
			
		||||
		start_i = pagemax
 | 
			
		||||
	end
 | 
			
		||||
	if not (start_i	== start) then
 | 
			
		||||
		unified_inventory.current_index[player_name] = (start_i - 1) * 80 + 1
 | 
			
		||||
	if start_i ~= start then
 | 
			
		||||
		minetest.sound_play("paperflip1",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
		unified_inventory.current_index[player_name] = (start_i - 1) * ui_peruser.items_per_page + 1
 | 
			
		||||
		unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
				unified_inventory.current_page[player_name])
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local clicked_item = nil
 | 
			
		||||
	-- Check clicked item image button
 | 
			
		||||
	local clicked_item
 | 
			
		||||
	for name, value in pairs(fields) do
 | 
			
		||||
		if string.sub(name, 1, 12) == "item_button_" then
 | 
			
		||||
			clicked_item = string.sub(name, 13)
 | 
			
		||||
		local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$")
 | 
			
		||||
		if new_dir and mangled_item then
 | 
			
		||||
			clicked_item = unified_inventory.demangle_for_formspec(mangled_item)
 | 
			
		||||
			if string.sub(clicked_item, 1, 6) == "group:" then
 | 
			
		||||
				-- Change search filter to this group
 | 
			
		||||
				apply_new_filter(player, clicked_item, new_dir)
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			if new_dir == "recipe" or new_dir == "usage" then
 | 
			
		||||
				unified_inventory.current_craft_direction[player_name] = new_dir
 | 
			
		||||
			end
 | 
			
		||||
			break
 | 
			
		||||
		elseif string.sub(name, 1, 11) == "item_group_" then
 | 
			
		||||
			minetest.sound_play("click",
 | 
			
		||||
					{to_player=player_name, gain = 0.1})
 | 
			
		||||
			unified_inventory.apply_filter(player, "group:"..string.sub(name, 12))
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	if clicked_item then
 | 
			
		||||
		minetest.sound_play("click",
 | 
			
		||||
				{to_player=player_name, gain = 0.1})
 | 
			
		||||
		local page = unified_inventory.current_page[player_name]
 | 
			
		||||
		if not unified_inventory.is_creative(player_name) then
 | 
			
		||||
		local player_creative = unified_inventory.is_creative(player_name)
 | 
			
		||||
		if not player_creative then
 | 
			
		||||
			page = "craftguide"
 | 
			
		||||
		end
 | 
			
		||||
		if page == "craftguide" then
 | 
			
		||||
			unified_inventory.current_item[player_name] = clicked_item
 | 
			
		||||
			unified_inventory.alternate[player_name] = 1
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
					"craftguide")
 | 
			
		||||
		else
 | 
			
		||||
			if unified_inventory.is_creative(player_name) then
 | 
			
		||||
				local inv = player:get_inventory()
 | 
			
		||||
				local stack = ItemStack(clicked_item)
 | 
			
		||||
				stack:set_count(stack:get_stack_max())
 | 
			
		||||
				if inv:room_for_item("main", stack) then
 | 
			
		||||
					inv:add_item("main", stack)
 | 
			
		||||
				end
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, "craftguide")
 | 
			
		||||
		elseif player_creative then
 | 
			
		||||
			-- Creative page: Add entire stack to inventory
 | 
			
		||||
			local inv = player:get_inventory()
 | 
			
		||||
			local stack = ItemStack(clicked_item)
 | 
			
		||||
			stack:set_count(stack:get_stack_max())
 | 
			
		||||
			if inv:room_for_item("main", stack) then
 | 
			
		||||
				inv:add_item("main", stack)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if fields.searchbutton then
 | 
			
		||||
		unified_inventory.apply_filter(player, fields.searchbox)
 | 
			
		||||
	if fields.searchbutton
 | 
			
		||||
			or fields.key_enter_field == "searchbox" then
 | 
			
		||||
		unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange")
 | 
			
		||||
		unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
				unified_inventory.current_page[player_name])
 | 
			
		||||
		minetest.sound_play("paperflip2",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
	elseif fields.searchresetbutton then
 | 
			
		||||
		apply_new_filter(player, "", "nochange")
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- alternate button
 | 
			
		||||
	-- alternate buttons
 | 
			
		||||
	if not (fields.alternate or fields.alternate_prev) then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	minetest.sound_play("click",
 | 
			
		||||
			{to_player=player_name, gain = 0.1})
 | 
			
		||||
	local item_name = unified_inventory.current_item[player_name]
 | 
			
		||||
	if not item_name then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local crafts = unified_inventory.crafts_for[unified_inventory.current_craft_direction[player_name]][item_name]
 | 
			
		||||
	if not crafts then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local alternates = #crafts
 | 
			
		||||
	if alternates <= 1 then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local alternate
 | 
			
		||||
	if fields.alternate then
 | 
			
		||||
		minetest.sound_play("click",
 | 
			
		||||
				{to_player=player_name, gain = 0.1})
 | 
			
		||||
		local item_name = unified_inventory.current_item[player_name]
 | 
			
		||||
		if item_name then
 | 
			
		||||
			local alternates = 0
 | 
			
		||||
			local alternate = unified_inventory.alternate[player_name]
 | 
			
		||||
			local crafts = unified_inventory.crafts_table[item_name]
 | 
			
		||||
			if crafts ~= nil then
 | 
			
		||||
				alternates = #crafts
 | 
			
		||||
			end
 | 
			
		||||
			if alternates > 1 then
 | 
			
		||||
				alternate = alternate + 1
 | 
			
		||||
				if alternate > alternates then
 | 
			
		||||
					alternate = 1
 | 
			
		||||
				end
 | 
			
		||||
				unified_inventory.alternate[player_name] = alternate
 | 
			
		||||
				unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
						unified_inventory.current_page[player_name])
 | 
			
		||||
			end
 | 
			
		||||
		alternate = unified_inventory.alternate[player_name] + 1
 | 
			
		||||
		if alternate > alternates then
 | 
			
		||||
			alternate = 1
 | 
			
		||||
		end
 | 
			
		||||
	elseif fields.alternate_prev then
 | 
			
		||||
		alternate = unified_inventory.alternate[player_name] - 1
 | 
			
		||||
		if alternate < 1 then
 | 
			
		||||
			alternate = alternates
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	unified_inventory.alternate[player_name] = alternate
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player,
 | 
			
		||||
			unified_inventory.current_page[player_name])
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
if minetest.delete_detached_inventory then
 | 
			
		||||
	minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		minetest.delete_detached_inventory(player_name.."_bags")
 | 
			
		||||
		minetest.delete_detached_inventory(player_name.."craftrecipe")
 | 
			
		||||
		minetest.delete_detached_inventory(player_name.."refill")
 | 
			
		||||
	end)
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1,5 @@
 | 
			
		||||
default
 | 
			
		||||
creative?
 | 
			
		||||
sfinv?
 | 
			
		||||
datastorage?
 | 
			
		||||
farming?
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								description.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1 @@
 | 
			
		||||
Unified Inventory replaces the default survival and creative inventory. It adds a nicer interface and a number of features, such as a crafting guide.
 | 
			
		||||
							
								
								
									
										95
									
								
								doc/mod_api.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,95 @@
 | 
			
		||||
unified_inventory API
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
This file provides information about the API of unified_inventory.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Misc functions
 | 
			
		||||
--------------
 | 
			
		||||
Grouped by use-case, afterwards sorted alphabetically.
 | 
			
		||||
 | 
			
		||||
* `unified_inventory.is_creative(name)`
 | 
			
		||||
	* Checks whether creative is enabled or the player has `creative`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Pages
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
Register a new page: The callback inside this function is called on user input.
 | 
			
		||||
 | 
			
		||||
	unified_inventory.register_page("pagename", {
 | 
			
		||||
		get_formspec = function(player)
 | 
			
		||||
			-- ^ `player` is an `ObjectRef`
 | 
			
		||||
			-- Compute the formspec string here
 | 
			
		||||
			return {
 | 
			
		||||
				formspec = "button[2,2;2,1;mybutton;Press me]",
 | 
			
		||||
				-- ^ Final form of the formspec to display
 | 
			
		||||
				draw_inventory = false,   -- default `true`
 | 
			
		||||
				-- ^ Optional. Hides the player's `main` inventory list
 | 
			
		||||
				draw_item_list = false,   -- default `true`
 | 
			
		||||
				-- ^ Optional. Hides the item list on the right side
 | 
			
		||||
				formspec_prepend = false, -- default `false`
 | 
			
		||||
				-- ^ Optional. When `false`: Disables the formspec prepend
 | 
			
		||||
			}
 | 
			
		||||
		end,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Buttons
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
Register a new button for the bottom row:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.register_button("skins", {
 | 
			
		||||
		type = "image",
 | 
			
		||||
		image = "skins_skin_button.png",
 | 
			
		||||
		tooltip = "Skins",
 | 
			
		||||
		hide_lite = true
 | 
			
		||||
		-- ^ Button is hidden when following two conditions are met:
 | 
			
		||||
		--   Configuration line `unified_inventory_lite = true`
 | 
			
		||||
		--   Player does not have the privilege `ui_full`
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Crafting
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
The code blocks below document each possible parameter using exemplary values.
 | 
			
		||||
 | 
			
		||||
Provide information to display custom craft types:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.register_craft_type("mytype", {
 | 
			
		||||
		-- ^ Unique identifier for `register_craft`
 | 
			
		||||
		description = "Sample Craft",
 | 
			
		||||
		-- ^ Text shown below the crafting arrow
 | 
			
		||||
		icon = "dummy.png",
 | 
			
		||||
		-- ^ Image shown above the crafting arrow
 | 
			
		||||
		width = 3,
 | 
			
		||||
		height = 3,
 | 
			
		||||
		-- ^ Maximal input dimensions of the recipes
 | 
			
		||||
		dynamic_display_size = function(craft)
 | 
			
		||||
			-- ^ `craft` is the definition from `register_craft`
 | 
			
		||||
			return {
 | 
			
		||||
				width = 2,
 | 
			
		||||
				height = 3
 | 
			
		||||
			}
 | 
			
		||||
		end,
 | 
			
		||||
		-- ^ Optional callback to change the displayed recipe size
 | 
			
		||||
		uses_crafting_grid = true,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
Register a non-standard craft recipe:
 | 
			
		||||
 | 
			
		||||
	unified_inventory.register_craft({
 | 
			
		||||
		output = "default:foobar",
 | 
			
		||||
		type = "mytype",
 | 
			
		||||
		-- ^ Standard craft type or custom (see `register_craft_type`)
 | 
			
		||||
		items = {
 | 
			
		||||
			{ "default:foo" },
 | 
			
		||||
			{ "default:bar" }
 | 
			
		||||
		},
 | 
			
		||||
		width = 3,
 | 
			
		||||
		-- ^ Same as `minetest.register_recipe`
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										127
									
								
								group.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,127 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
 | 
			
		||||
function unified_inventory.canonical_item_spec_matcher(spec)
 | 
			
		||||
	local specname = ItemStack(spec):get_name()
 | 
			
		||||
	if specname:sub(1, 6) ~= "group:" then
 | 
			
		||||
		return function (itemname)
 | 
			
		||||
			return itemname == specname
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local group_names = specname:sub(7):split(",")
 | 
			
		||||
	return function (itemname)
 | 
			
		||||
		local itemdef = minetest.registered_items[itemname]
 | 
			
		||||
		for _, group_name in ipairs(group_names) do
 | 
			
		||||
			if (itemdef.groups[group_name] or 0) == 0 then
 | 
			
		||||
				return false
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		return true
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.item_matches_spec(item, spec)
 | 
			
		||||
	local itemname = ItemStack(item):get_name()
 | 
			
		||||
	return unified_inventory.canonical_item_spec_matcher(spec)(itemname)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.extract_groupnames(groupname)
 | 
			
		||||
	local specname = ItemStack(groupname):get_name()
 | 
			
		||||
	if specname:sub(1, 6) ~= "group:" then
 | 
			
		||||
		return nil, 0
 | 
			
		||||
	end
 | 
			
		||||
	local group_names = specname:sub(7):split(",")
 | 
			
		||||
	return table.concat(group_names, S(" and ")), #group_names
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
unified_inventory.registered_group_items = {
 | 
			
		||||
	mesecon_conductor_craftable = "mesecons:wire_00000000_off",
 | 
			
		||||
	stone = "default:cobble",
 | 
			
		||||
	wood = "default:wood",
 | 
			
		||||
	book = "default:book",
 | 
			
		||||
	sand = "default:sand",
 | 
			
		||||
	leaves = "default:leaves",
 | 
			
		||||
	tree = "default:tree",
 | 
			
		||||
	vessel = "vessels:glass_bottle",
 | 
			
		||||
	wool = "wool:white",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function unified_inventory.register_group_item(groupname, itemname)
 | 
			
		||||
	unified_inventory.registered_group_items[groupname] = itemname
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- This is used when displaying craft recipes, where an ingredient is
 | 
			
		||||
-- specified by group rather than as a specific item.  A single-item group
 | 
			
		||||
-- is represented by that item, with the single-item status signalled
 | 
			
		||||
-- in the "sole" field.  If the group contains no items at all, the item
 | 
			
		||||
-- field will be nil.
 | 
			
		||||
--
 | 
			
		||||
-- Within a multiple-item group, we prefer to use an item that has the
 | 
			
		||||
-- same specific name as the group, and if there are more than one of
 | 
			
		||||
-- those items we prefer the one registered for the group by a mod.
 | 
			
		||||
-- Among equally-preferred items, we just pick the one with the
 | 
			
		||||
-- lexicographically earliest name.
 | 
			
		||||
--
 | 
			
		||||
-- The parameter to this function isn't just a single group name.
 | 
			
		||||
-- It may be a comma-separated list of group names.  This is really a
 | 
			
		||||
-- "group:..." ingredient specification, minus the "group:" prefix.
 | 
			
		||||
 | 
			
		||||
local function compute_group_item(group_name_list)
 | 
			
		||||
	local group_names = group_name_list:split(",")
 | 
			
		||||
	local candidate_items = {}
 | 
			
		||||
	for itemname, itemdef in pairs(minetest.registered_items) do
 | 
			
		||||
		if (itemdef.groups.not_in_creative_inventory or 0) == 0 then
 | 
			
		||||
			local all = true
 | 
			
		||||
			for _, group_name in ipairs(group_names) do
 | 
			
		||||
				if (itemdef.groups[group_name] or 0) == 0 then
 | 
			
		||||
					all = false
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			if all then table.insert(candidate_items, itemname) end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	local num_candidates = #candidate_items
 | 
			
		||||
	if num_candidates == 0 then
 | 
			
		||||
		return {sole = true}
 | 
			
		||||
	elseif num_candidates == 1 then
 | 
			
		||||
		return {item = candidate_items[1], sole = true}
 | 
			
		||||
	end
 | 
			
		||||
	local is_group = {}
 | 
			
		||||
	local registered_rep = {}
 | 
			
		||||
	for _, group_name in ipairs(group_names) do
 | 
			
		||||
		is_group[group_name] = true
 | 
			
		||||
		local rep = unified_inventory.registered_group_items[group_name]
 | 
			
		||||
		if rep then registered_rep[rep] = true end
 | 
			
		||||
	end
 | 
			
		||||
	local bestitem = ""
 | 
			
		||||
	local bestpref = 0
 | 
			
		||||
	for _, item in ipairs(candidate_items) do
 | 
			
		||||
		local pref
 | 
			
		||||
		if registered_rep[item] then
 | 
			
		||||
			pref = 4
 | 
			
		||||
		elseif string.sub(item, 1, 8) == "default:" and is_group[string.sub(item, 9)] then
 | 
			
		||||
			pref = 3
 | 
			
		||||
		elseif is_group[item:gsub("^[^:]*:", "")] then
 | 
			
		||||
			pref = 2
 | 
			
		||||
		else
 | 
			
		||||
			pref = 1
 | 
			
		||||
		end
 | 
			
		||||
		if pref > bestpref or (pref == bestpref and item < bestitem) then
 | 
			
		||||
			bestitem = item
 | 
			
		||||
			bestpref = pref
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return {item = bestitem, sole = false}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local group_item_cache = {}
 | 
			
		||||
 | 
			
		||||
function unified_inventory.get_group_item(group_name)
 | 
			
		||||
	if not group_item_cache[group_name] then
 | 
			
		||||
		group_item_cache[group_name] = compute_group_item(group_name)
 | 
			
		||||
	end
 | 
			
		||||
	return group_item_cache[group_name]
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										69
									
								
								image_credits.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,69 @@
 | 
			
		||||
bags_small.png:
 | 
			
		||||
	http://www.clker.com/clipart-moneybag-empty.html
 | 
			
		||||
 | 
			
		||||
bags_medium.png:
 | 
			
		||||
	http://www.clker.com/clipart-backpack-1.html
 | 
			
		||||
 | 
			
		||||
bags_large.png / ui_bags_icon.png:
 | 
			
		||||
	http://www.clker.com/clipart-backpack-green-brown.html
 | 
			
		||||
 | 
			
		||||
ui_craftguide_icon.png / ui_craft_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Advancedsettings.png
 | 
			
		||||
	
 | 
			
		||||
ui_doubleleft_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Media-seek-backward.svg
 | 
			
		||||
 | 
			
		||||
ui_doubleright_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Media-seek-forward.svg
 | 
			
		||||
 | 
			
		||||
ui_left_icon.png / ui_right_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Media-playback-start.svg
 | 
			
		||||
 | 
			
		||||
ui_skip_backward_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Media-skip-backward.svg
 | 
			
		||||
 | 
			
		||||
ui_skip_forward_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Media-skip-forward.svg
 | 
			
		||||
 | 
			
		||||
ui_reset_icon.png
 | 
			
		||||
	https://commons.wikimedia.org/wiki/File:Edit-clear.svg
 | 
			
		||||
 | 
			
		||||
ui_gohome_icon.png / ui_home_icon.png / ui_sethome_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Home_256x256.png
 | 
			
		||||
 | 
			
		||||
ui_moon_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:FullMoon2010.jpg
 | 
			
		||||
 | 
			
		||||
ui_sun_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:2012-10-13_15-29-35-sun.jpg
 | 
			
		||||
 | 
			
		||||
ui_trash_icon.png
 | 
			
		||||
	http://www.clker.com/clipart-29090.html
 | 
			
		||||
	http://www.clker.com/clipart-trash.html
 | 
			
		||||
 | 
			
		||||
ui_search_icon.png
 | 
			
		||||
	http://www.clker.com/clipart-24887.html
 | 
			
		||||
 | 
			
		||||
ui_off_icon.png / ui_on_icon.png
 | 
			
		||||
	http://www.clker.com/clipart-on-off-switches.html
 | 
			
		||||
 | 
			
		||||
ui_waypoints_icon.png
 | 
			
		||||
	http://www.clker.com/clipart-map-pin-red.html
 | 
			
		||||
 | 
			
		||||
ui_circular_arrows_icon.png
 | 
			
		||||
	http://www.clker.com/clipart-circular-arrow-pattern.html
 | 
			
		||||
 | 
			
		||||
ui_pencil_icon.pnc
 | 
			
		||||
	http://www.clker.com/clipart-2256.html
 | 
			
		||||
 | 
			
		||||
ui_waypoint_set_icon.png
 | 
			
		||||
	http://www.clker.com/clipart-larger-flag.html
 | 
			
		||||
 | 
			
		||||
ui_xyz_off_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:No_sign.svg
 | 
			
		||||
 | 
			
		||||
ui_ok_icon.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Yes_check.svg
 | 
			
		||||
 | 
			
		||||
inventory_plus_worldedit_gui.png
 | 
			
		||||
	http://commons.wikimedia.org/wiki/File:Erioll_world_2.svg
 | 
			
		||||
							
								
								
									
										89
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						@@ -1,42 +1,81 @@
 | 
			
		||||
-- Unified Inventory for Minetest 0.4.8+
 | 
			
		||||
-- Unified Inventory for Minetest >= 0.4.16
 | 
			
		||||
 | 
			
		||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
 | 
			
		||||
local worldpath = minetest.get_worldpath()
 | 
			
		||||
 | 
			
		||||
-- Data tables definitions
 | 
			
		||||
unified_inventory = {}
 | 
			
		||||
unified_inventory.activefilter = {}
 | 
			
		||||
unified_inventory.alternate = {}
 | 
			
		||||
unified_inventory.current_page = {}
 | 
			
		||||
unified_inventory.current_index = {}
 | 
			
		||||
unified_inventory.current_item = {}
 | 
			
		||||
unified_inventory.crafts_table = {}
 | 
			
		||||
unified_inventory.crafts_table_count = 0
 | 
			
		||||
unified_inventory.players = {}
 | 
			
		||||
unified_inventory.items_list_size = 0
 | 
			
		||||
unified_inventory.items_list = {}
 | 
			
		||||
unified_inventory.filtered_items_list_size = {}
 | 
			
		||||
unified_inventory.filtered_items_list = {}
 | 
			
		||||
unified_inventory.pages = {}
 | 
			
		||||
unified_inventory.buttons = {}
 | 
			
		||||
unified_inventory = {
 | 
			
		||||
	activefilter = {},
 | 
			
		||||
	active_search_direction = {},
 | 
			
		||||
	alternate = {},
 | 
			
		||||
	current_page = {},
 | 
			
		||||
	current_searchbox = {},
 | 
			
		||||
	current_index = {},
 | 
			
		||||
	current_item = {},
 | 
			
		||||
	current_craft_direction = {},
 | 
			
		||||
	registered_craft_types = {},
 | 
			
		||||
	crafts_for = {usage = {}, recipe = {} },
 | 
			
		||||
	players = {},
 | 
			
		||||
	items_list_size = 0,
 | 
			
		||||
	items_list = {},
 | 
			
		||||
	filtered_items_list_size = {},
 | 
			
		||||
	filtered_items_list = {},
 | 
			
		||||
	pages = {},
 | 
			
		||||
	buttons = {},
 | 
			
		||||
 | 
			
		||||
-- Homepos stuff
 | 
			
		||||
unified_inventory.home_pos = {}
 | 
			
		||||
unified_inventory.home_filename =
 | 
			
		||||
		worldpath.."/unified_inventory_home.home"
 | 
			
		||||
	-- Homepos stuff
 | 
			
		||||
	home_pos = {},
 | 
			
		||||
	home_filename =	worldpath.."/unified_inventory_home.home",
 | 
			
		||||
 | 
			
		||||
-- Default inventory page
 | 
			
		||||
unified_inventory.default = "craft"
 | 
			
		||||
	-- Default inventory page
 | 
			
		||||
	default = "craft",
 | 
			
		||||
 | 
			
		||||
	-- "Lite" mode
 | 
			
		||||
	lite_mode = minetest.settings:get_bool("unified_inventory_lite"),
 | 
			
		||||
 | 
			
		||||
	-- Trash enabled
 | 
			
		||||
	trash_enabled = (minetest.settings:get_bool("unified_inventory_trash") ~= false),
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- Disable default creative inventory
 | 
			
		||||
if creative_inventory then
 | 
			
		||||
	function creative_inventory.set_creative_formspec(player, start_i, pagenum)
 | 
			
		||||
local creative = rawget(_G, "creative") or rawget(_G, "creative_inventory")
 | 
			
		||||
if creative then
 | 
			
		||||
	function creative.set_creative_formspec(player, start_i, pagenum)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Disable sfinv inventory
 | 
			
		||||
local sfinv = rawget(_G, "sfinv")
 | 
			
		||||
if sfinv then
 | 
			
		||||
	sfinv.enabled = false
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
dofile(modpath.."/group.lua")
 | 
			
		||||
dofile(modpath.."/api.lua")
 | 
			
		||||
dofile(modpath.."/internal.lua")
 | 
			
		||||
dofile(modpath.."/callbacks.lua")
 | 
			
		||||
dofile(modpath.."/match_craft.lua")
 | 
			
		||||
dofile(modpath.."/register.lua")
 | 
			
		||||
dofile(modpath.."/bags.lua")
 | 
			
		||||
 | 
			
		||||
if minetest.settings:get_bool("unified_inventory_bags") ~= false then
 | 
			
		||||
	dofile(modpath.."/bags.lua")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
dofile(modpath.."/item_names.lua")
 | 
			
		||||
 | 
			
		||||
if minetest.get_modpath("datastorage") then
 | 
			
		||||
	dofile(modpath.."/waypoints.lua")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.log("action", "[unified_inventory] loaded.")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										393
									
								
								internal.lua
									
									
									
									
									
								
							
							
						
						@@ -1,139 +1,323 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
 | 
			
		||||
-- This pair of encoding functions is used where variable text must go in
 | 
			
		||||
-- button names, where the text might contain formspec metacharacters.
 | 
			
		||||
-- We can escape button names for the formspec, to avoid screwing up
 | 
			
		||||
-- form structure overall, but they then don't get de-escaped, and so
 | 
			
		||||
-- the input we get back from the button contains the formspec escaping.
 | 
			
		||||
-- 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)
 | 
			
		||||
	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)
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.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)
 | 
			
		||||
 | 
			
		||||
	unified_inventory.current_page[player_name] = page
 | 
			
		||||
	local pagedef = unified_inventory.pages[page]
 | 
			
		||||
 | 
			
		||||
	local formspec = "size[14,10]"
 | 
			
		||||
	local fsdata = nil
 | 
			
		||||
 | 
			
		||||
	-- Background
 | 
			
		||||
	formspec = formspec .. "background[-0.19,-0.25;14.4,10.75;ui_form_bg.png]"
 | 
			
		||||
	-- Current page
 | 
			
		||||
	if unified_inventory.pages[page] then
 | 
			
		||||
		fsdata = pagedef.get_formspec(player)
 | 
			
		||||
		formspec = formspec .. fsdata.formspec
 | 
			
		||||
	else
 | 
			
		||||
	if not pagedef then
 | 
			
		||||
		return "" -- Invalid page name
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local formspec = {
 | 
			
		||||
		"size[14,10]",
 | 
			
		||||
		pagedef.formspec_prepend and "" or "no_prepend[]",
 | 
			
		||||
		"background[-0.19,-0.25;14.4,10.75;ui_form_bg.png]" -- Background
 | 
			
		||||
	}
 | 
			
		||||
	local n = 4
 | 
			
		||||
 | 
			
		||||
	if draw_lite_mode then
 | 
			
		||||
		formspec[1] = "size[11,7.7]"
 | 
			
		||||
		formspec[3] = "background[-0.19,-0.2;11.4,8.4;ui_form_bg.png]"
 | 
			
		||||
	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 fsdata = pagedef.get_formspec(player, perplayer_formspec)
 | 
			
		||||
 | 
			
		||||
	formspec[n] = fsdata.formspec
 | 
			
		||||
	n = n+1
 | 
			
		||||
 | 
			
		||||
	local button_row = 0
 | 
			
		||||
	local button_col = 0
 | 
			
		||||
 | 
			
		||||
	-- Main buttons
 | 
			
		||||
 | 
			
		||||
	local filtered_inv_buttons = {}
 | 
			
		||||
 | 
			
		||||
	for i, def in pairs(unified_inventory.buttons) do
 | 
			
		||||
		if def.type == "image" then
 | 
			
		||||
			formspec = formspec.."image_button["
 | 
			
		||||
					..(0.65 * (i - 1))..",9;0.8,0.8;"
 | 
			
		||||
					..minetest.formspec_escape(def.image)..";"
 | 
			
		||||
					..minetest.formspec_escape(def.name)..";]"
 | 
			
		||||
		if not (draw_lite_mode and def.hide_lite) then
 | 
			
		||||
			table.insert(filtered_inv_buttons, def)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local j = 1 --Modif NALC (sys4 20/11/2018) 12 buttons max by row
 | 
			
		||||
	for i, def in pairs(filtered_inv_buttons) do
 | 
			
		||||
 | 
			
		||||
		if draw_lite_mode and i > 4 then
 | 
			
		||||
			button_row = 1
 | 
			
		||||
			button_col = 1
 | 
			
		||||
		elseif not draw_lite_mode and j > 12 then
 | 
			
		||||
			button_row = 1
 | 
			
		||||
			j = 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if def.type == "image" then
 | 
			
		||||
			if (def.condition == nil or def.condition(player) == true) then
 | 
			
		||||
				formspec[n] = "image_button["
 | 
			
		||||
				formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (j - 1) - button_col * 0.65 * 4) -- Modif NALC
 | 
			
		||||
				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
 | 
			
		||||
			else
 | 
			
		||||
				formspec[n] = "image["
 | 
			
		||||
				formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (j - 1) - button_col * 0.65 * 4) -- Modif NALC
 | 
			
		||||
				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
 | 
			
		||||
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		j = j + 1 -- Modif NALC
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if fsdata.draw_inventory ~= false then
 | 
			
		||||
		-- Player inventory
 | 
			
		||||
		formspec = formspec.."listcolors[#00000000;#00000000]"
 | 
			
		||||
		formspec = formspec .. "list[current_player;main;0,4.5;8,4;]"
 | 
			
		||||
		formspec[n] = "listcolors[#00000000;#00000000]"
 | 
			
		||||
		formspec[n+1] = "list[current_player;main;0,"..(ui_peruser.formspec_y + 3.5)..";8,4;]"
 | 
			
		||||
		n = n+2
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if fsdata.draw_item_list == false then
 | 
			
		||||
		return formspec
 | 
			
		||||
		return table.concat(formspec, "")
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Controls to flip items pages
 | 
			
		||||
	local start_x = 9.2
 | 
			
		||||
	formspec = formspec .. "image_button["..(start_x + 0.6 * 0)..",9;.8,.8;ui_skip_backward_icon.png;start_list;]"
 | 
			
		||||
	formspec = formspec .. "image_button["..(start_x + 0.6 * 1)..",9;.8,.8;ui_doubleleft_icon.png;rewind3;]"
 | 
			
		||||
	formspec = formspec .. "image_button["..(start_x + 0.6 * 2)..",9;.8,.8;ui_left_icon.png;rewind1;]"
 | 
			
		||||
	formspec = formspec .. "image_button["..(start_x + 0.6 * 3)..",9;.8,.8;ui_right_icon.png;forward1;]"
 | 
			
		||||
	formspec = formspec .. "image_button["..(start_x + 0.6 * 4)..",9;.8,.8;ui_doubleright_icon.png;forward3;]"
 | 
			
		||||
	formspec = formspec .. "image_button["..(start_x + 0.6 * 5)..",9;.8,.8;ui_skip_forward_icon.png;end_list;]"
 | 
			
		||||
 | 
			
		||||
	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 = formspec .. "field[9.5,8.325;3,1;searchbox;;]"
 | 
			
		||||
	formspec = formspec .. "image_button[12.2,8.1;.8,.8;ui_search_icon.png;searchbutton;]"
 | 
			
		||||
	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")) .. "]"
 | 
			
		||||
	end
 | 
			
		||||
	n = n+3
 | 
			
		||||
 | 
			
		||||
	local no_matches = S("No matching items")
 | 
			
		||||
	if draw_lite_mode then
 | 
			
		||||
		no_matches = S("No matches.")
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Items list
 | 
			
		||||
	local list_index = unified_inventory.current_index[player_name]
 | 
			
		||||
	local page = math.floor(list_index / (80) + 1)
 | 
			
		||||
	local pagemax = math.floor(
 | 
			
		||||
		(#unified_inventory.filtered_items_list[player_name] - 1)
 | 
			
		||||
			/ (80) + 1)
 | 
			
		||||
	local item = {}
 | 
			
		||||
	for y = 0, 9 do
 | 
			
		||||
	for x = 0, 7 do
 | 
			
		||||
		local name = unified_inventory.filtered_items_list[player_name][list_index]
 | 
			
		||||
		if minetest.registered_items[name] then
 | 
			
		||||
			formspec = formspec.."item_image_button["
 | 
			
		||||
					..(8.2 + x * 0.7)..","
 | 
			
		||||
					..(1   + y * 0.7)..";.81,.81;"
 | 
			
		||||
					..name..";item_button_"
 | 
			
		||||
					..name..";]"
 | 
			
		||||
			list_index = list_index + 1
 | 
			
		||||
	if #unified_inventory.filtered_items_list[player_name] == 0 then
 | 
			
		||||
		formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";" .. F(no_matches) .. "]"
 | 
			
		||||
	else
 | 
			
		||||
		local dir = unified_inventory.active_search_direction[player_name]
 | 
			
		||||
		local list_index = unified_inventory.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_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 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 cdir == "recipe" then
 | 
			
		||||
							dir = "usage"
 | 
			
		||||
						elseif cdir == "usage" then
 | 
			
		||||
							dir = "recipe"
 | 
			
		||||
						end
 | 
			
		||||
					else
 | 
			
		||||
					-- Default: use active search direction by default
 | 
			
		||||
						dir = unified_inventory.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,
 | 
			
		||||
						name, button_name
 | 
			
		||||
					)
 | 
			
		||||
					formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format(
 | 
			
		||||
						button_name, minetest.formspec_escape(item.description),
 | 
			
		||||
						item.mod_origin or "??"
 | 
			
		||||
					)
 | 
			
		||||
					n = n + 2
 | 
			
		||||
					list_index = list_index + 1
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		formspec[n] = "label[8.2,"..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]).."]"
 | 
			
		||||
	end
 | 
			
		||||
	formspec = formspec.."label[8.2,0;Page:]"
 | 
			
		||||
	formspec = formspec.."label[9,0;"..page.." of "..pagemax.."]"
 | 
			
		||||
	formspec = formspec.."label[8.2,0.4;Filter:]"
 | 
			
		||||
	formspec = formspec.."label[9,0.4;"..unified_inventory.activefilter[player_name].."]"
 | 
			
		||||
	return formspec
 | 
			
		||||
	return table.concat(formspec, "")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.set_inventory_formspec(player, page)
 | 
			
		||||
	if player then
 | 
			
		||||
		local formspec = unified_inventory.get_formspec(player, page)
 | 
			
		||||
		player:set_inventory_formspec(formspec)
 | 
			
		||||
		player:set_inventory_formspec(unified_inventory.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)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local size = 0
 | 
			
		||||
	local lfilter = string.lower(filter)
 | 
			
		||||
	if not pcall(function() ("technic:test"):find(lfilter) end) then
 | 
			
		||||
		-- Filter is invalid
 | 
			
		||||
		lfilter = ""
 | 
			
		||||
function unified_inventory.apply_filter(player, filter, search_dir)
 | 
			
		||||
	if not player then
 | 
			
		||||
		return false
 | 
			
		||||
	end
 | 
			
		||||
	unified_inventory.filtered_items_list[player_name]={}
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local lfilter = string.lower(filter)
 | 
			
		||||
	local ffilter
 | 
			
		||||
	if lfilter:sub(1, 6) == "group:" then
 | 
			
		||||
		local groups = lfilter:sub(7):split(",")
 | 
			
		||||
		for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
			if def.groups then
 | 
			
		||||
				local all = true
 | 
			
		||||
				for _, group in ipairs(groups) do
 | 
			
		||||
					if not (def.groups[group] and (def.groups[group] > 0)) then
 | 
			
		||||
						all = false
 | 
			
		||||
						break
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				if all then
 | 
			
		||||
					table.insert(unified_inventory.filtered_items_list[player_name], name)
 | 
			
		||||
					size = size + 1
 | 
			
		||||
		ffilter = function(name, def)
 | 
			
		||||
			for _, group in ipairs(groups) do
 | 
			
		||||
				if not def.groups[group]
 | 
			
		||||
				or def.groups[group] <= 0 then
 | 
			
		||||
					return false
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			return true
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		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
 | 
			
		||||
				local lname = string.lower(name)
 | 
			
		||||
				local ldesc = string.lower(def.description)
 | 
			
		||||
				if string.find(lname, lfilter) or string.find(ldesc, lfilter) then
 | 
			
		||||
					table.insert(unified_inventory.filtered_items_list[player_name], name)
 | 
			
		||||
					size = size + 1
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		ffilter = function(name, def)
 | 
			
		||||
			local lname = string.lower(name)
 | 
			
		||||
			local ldesc = string.lower(def.description)
 | 
			
		||||
			return string.find(lname, lfilter, 1, true) or string.find(ldesc, lfilter, 1, true)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	unified_inventory.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)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	table.sort(unified_inventory.filtered_items_list[player_name])
 | 
			
		||||
	unified_inventory.filtered_items_list_size[player_name] = size
 | 
			
		||||
	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])
 | 
			
		||||
	unified_inventory.current_page[player_name])
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.items_in_group(groups)
 | 
			
		||||
@@ -147,3 +331,48 @@ function unified_inventory.items_in_group(groups)
 | 
			
		||||
	end
 | 
			
		||||
	return items
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function unified_inventory.sort_inventory(inv)
 | 
			
		||||
	local inlist = inv:get_list("main")
 | 
			
		||||
	local typecnt = {}
 | 
			
		||||
	local typekeys = {}
 | 
			
		||||
	for _, st in ipairs(inlist) do
 | 
			
		||||
		if not st:is_empty() then
 | 
			
		||||
			local n = st:get_name()
 | 
			
		||||
			local w = st:get_wear()
 | 
			
		||||
			local m = st:get_metadata()
 | 
			
		||||
			local k = string.format("%s %05d %s", n, w, m)
 | 
			
		||||
			if not typecnt[k] then
 | 
			
		||||
				typecnt[k] = {
 | 
			
		||||
					name = n,
 | 
			
		||||
					wear = w,
 | 
			
		||||
					metadata = m,
 | 
			
		||||
					stack_max = st:get_stack_max(),
 | 
			
		||||
					count = 0,
 | 
			
		||||
				}
 | 
			
		||||
				table.insert(typekeys, k)
 | 
			
		||||
			end
 | 
			
		||||
			typecnt[k].count = typecnt[k].count + st:get_count()
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	table.sort(typekeys)
 | 
			
		||||
	local outlist = {}
 | 
			
		||||
	for _, k in ipairs(typekeys) do
 | 
			
		||||
		local tc = typecnt[k]
 | 
			
		||||
		while tc.count > 0 do
 | 
			
		||||
			local c = math.min(tc.count, tc.stack_max)
 | 
			
		||||
			table.insert(outlist, ItemStack({
 | 
			
		||||
				name = tc.name,
 | 
			
		||||
				wear = tc.wear,
 | 
			
		||||
				metadata = tc.metadata,
 | 
			
		||||
				count = c,
 | 
			
		||||
			}))
 | 
			
		||||
			tc.count = tc.count - c
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	if #outlist > #inlist then return end
 | 
			
		||||
	while #outlist < #inlist do
 | 
			
		||||
		table.insert(outlist, ItemStack(nil))
 | 
			
		||||
	end
 | 
			
		||||
	inv:set_list("main", outlist)
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								item_names.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,76 @@
 | 
			
		||||
-- Based on 4itemnames mod by 4aiman
 | 
			
		||||
 | 
			
		||||
local item_names = {} -- [player_name] = { hud, dtime, itemname }
 | 
			
		||||
local dlimit = 3  -- HUD element will be hidden after this many seconds
 | 
			
		||||
local hudbars_mod = minetest.get_modpath("hudbars")
 | 
			
		||||
 | 
			
		||||
local function set_hud(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local off = {x=0, y=-65}
 | 
			
		||||
	if hudbars_mod then
 | 
			
		||||
		-- Assume no alignment (2 per line)
 | 
			
		||||
		off.y = off.y - math.ceil(hb.hudbars_count / 2) * 25
 | 
			
		||||
	else
 | 
			
		||||
		off.y = off.y - 25
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	item_names[player_name] = {
 | 
			
		||||
		hud = player:hud_add({
 | 
			
		||||
			hud_elem_type = "text",
 | 
			
		||||
			position = {x=0.5, y=1},
 | 
			
		||||
			offset = off,
 | 
			
		||||
			alignment = {x=0, y=-1},
 | 
			
		||||
			number = 0xFFFFFF,
 | 
			
		||||
			text = "",
 | 
			
		||||
		}),
 | 
			
		||||
		dtime = dlimit,
 | 
			
		||||
		index = 1,
 | 
			
		||||
		itemname = ""
 | 
			
		||||
	}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	minetest.after(0, set_hud, player)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
	item_names[player:get_player_name()] = nil
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_globalstep(function(dtime)
 | 
			
		||||
	for _, player in pairs(minetest.get_connected_players()) do
 | 
			
		||||
		local data = item_names[player:get_player_name()]
 | 
			
		||||
		if not data or not data.hud then
 | 
			
		||||
			data = {} -- Update on next step
 | 
			
		||||
			set_hud(player)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local index = player:get_wield_index()
 | 
			
		||||
		local stack = player:get_wielded_item()
 | 
			
		||||
		local itemname = stack:get_name()
 | 
			
		||||
 | 
			
		||||
		if data.hud and data.dtime < dlimit then
 | 
			
		||||
			data.dtime = data.dtime + dtime
 | 
			
		||||
			if data.dtime > dlimit then
 | 
			
		||||
				player:hud_change(data.hud, 'text', "")
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if data.hud and (itemname ~= data.itemname or index ~= data.index) then
 | 
			
		||||
			data.itemname = itemname
 | 
			
		||||
			data.index = index
 | 
			
		||||
			data.dtime = 0
 | 
			
		||||
 | 
			
		||||
			local desc = stack.get_meta
 | 
			
		||||
				and stack:get_meta():get_string("description")
 | 
			
		||||
 | 
			
		||||
			if not desc or desc == "" then
 | 
			
		||||
				-- Try to use default description when none is set in the meta
 | 
			
		||||
				local def = minetest.registered_items[itemname]
 | 
			
		||||
				desc = def and def.description or ""
 | 
			
		||||
			end
 | 
			
		||||
			player:hud_change(data.hud, 'text', desc)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										358
									
								
								locale/template.pot
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,358 @@
 | 
			
		||||
# LANGUAGE translation for the unified_inventory mod.
 | 
			
		||||
# Copyright (C) 2018 Maciej Kasatkin (RealBadAngel)
 | 
			
		||||
# This file is distributed under the same license as the unified_inventory package.
 | 
			
		||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
 | 
			
		||||
#
 | 
			
		||||
#, fuzzy
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: unified_inventory\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2018-04-02 03:34+0200\n"
 | 
			
		||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
			
		||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
			
		||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
			
		||||
"Language: \n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
 | 
			
		||||
#: api.lua register.lua
 | 
			
		||||
msgid "Crafting"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: api.lua
 | 
			
		||||
msgid "Mixing"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: api.lua
 | 
			
		||||
msgid "Cooking"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: api.lua
 | 
			
		||||
msgid "Digging"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Bags"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Bag @1"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Small Bag"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Medium Bag"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: bags.lua
 | 
			
		||||
msgid "Large Bag"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: group.lua
 | 
			
		||||
msgid " and "
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "First page"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Back three pages"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Back one page"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Forward one page"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Forward three pages"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Last page"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Reset search and display everything"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "No matching items"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "No matches."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Page"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "%s of %s"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: internal.lua
 | 
			
		||||
msgid "Filter"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Can use the creative inventory"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid ""
 | 
			
		||||
"Forces Unified Inventory to be displayed in Full mode if Lite mode is "
 | 
			
		||||
"configured globally"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Crafting Grid"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Crafting Guide"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Set home position"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Home position set to: %s"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "You don't have the \"home\" privilege!"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Go home"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Set time to day"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Time of day set to 6am"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "You don't have the settime privilege!"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Set time to night"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Time of day set to 9pm"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Clear inventory"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid ""
 | 
			
		||||
"This button has been disabled outside of creative mode to prevent accidental "
 | 
			
		||||
"inventory trashing.\n"
 | 
			
		||||
"Use the trash slot instead."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Inventory cleared!"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Trash:"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Refill:"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Any item belonging to the %s group"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Any item belonging to the groups %s"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Recipe %d of %d"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Usage %d of %d"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "No recipes"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "No usages"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Result"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Ingredient"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show next recipe"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show next usage"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show previous recipe"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Show previous usage"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "%s (%s)"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "Give me:"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid ""
 | 
			
		||||
"This recipe is too\n"
 | 
			
		||||
"large to be displayed."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "To craft grid:"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: register.lua
 | 
			
		||||
msgid "All"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "White"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Yellow"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Red"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Green"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Blue"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Waypoints"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Select Waypoint #%d"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
#, lua-format
 | 
			
		||||
msgid "Waypoint %d"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Set waypoint to current location"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "invisible"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "visible"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Make waypoint @1"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Disable"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Enable"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "@1 display of waypoint coordinates"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Change color of waypoint display"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Edit waypoint name"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Waypoint active"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Waypoint inactive"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Finish editing"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "World position"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "Name"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: waypoints.lua
 | 
			
		||||
msgid "HUD text color"
 | 
			
		||||
msgstr ""
 | 
			
		||||
							
								
								
									
										79
									
								
								locale/unified_inventory.de.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,79 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Crafting=Fertigung
 | 
			
		||||
Mixing=Mischen
 | 
			
		||||
Cooking=Kochen
 | 
			
		||||
Digging=Graben
 | 
			
		||||
Bags=Taschen
 | 
			
		||||
Bag @1=Tasche @1
 | 
			
		||||
Small Bag=Kleine Tasche
 | 
			
		||||
Medium Bag=Mittelgroße Tasche
 | 
			
		||||
Large Bag=Große Tasche
 | 
			
		||||
 and = und 
 | 
			
		||||
First page=Erste Seite
 | 
			
		||||
Back three pages=3 Seiten zurückblättern
 | 
			
		||||
Back one page=1 Seite zurückblättern
 | 
			
		||||
Forward one page=1 Seite vorblättern
 | 
			
		||||
Forward three pages=3 Seiten vorblättern
 | 
			
		||||
Last page=Letzte Seite
 | 
			
		||||
Search=Suchen
 | 
			
		||||
Reset search and display everything=Suche zurücksetzen und alles anzeigen
 | 
			
		||||
No matching items=Keine passenden Gegenstände
 | 
			
		||||
No matches.=Keine Treffer
 | 
			
		||||
Page=Seite
 | 
			
		||||
@1 of @2=@1 von @2
 | 
			
		||||
Filter=Filter
 | 
			
		||||
Can use the creative inventory=Kann das Kreativinventar nutzen
 | 
			
		||||
Crafting Grid=Fertigungsraster
 | 
			
		||||
Crafting Guide=Fertigungsführer
 | 
			
		||||
Set home position=Heimatposition setzen
 | 
			
		||||
Home position set to: @1=Heimatposition nach @1 gesetzt
 | 
			
		||||
You don't have the "home" privilege!=Du hast das „home“-Privileg nicht!
 | 
			
		||||
Go home=Nach Hause gehen
 | 
			
		||||
Set time to day=Zur Tageszeit wechseln
 | 
			
		||||
Time of day set to 6am=Tageszeit auf 6 Uhr gesetzt
 | 
			
		||||
You don't have the settime privilege!=Du hast das „settime“-Privileg nicht!
 | 
			
		||||
Set time to night=Zur Nachtzeit wechseln
 | 
			
		||||
Time of day set to 9pm=Tageszeit auf 21 Uhr gesetzt
 | 
			
		||||
Clear inventory=Inventar leeren
 | 
			
		||||
Inventory cleared!=Inventar geleert!
 | 
			
		||||
Trash:=Müll:
 | 
			
		||||
Refill:=Nachfüllen:
 | 
			
		||||
Any item belonging to the @1 group=Irgendein Gegenstand, der zur Gruppe @1 gehört
 | 
			
		||||
Any item belonging to the groups @1=Irgendein Gegenstand, der zu den Gruppen @1 gehört
 | 
			
		||||
Recipe @1 of @2=Rezept @1 von @2
 | 
			
		||||
Usage @1 of @2=Verwendung @1 von @2
 | 
			
		||||
No recipes=Keine Rezepte
 | 
			
		||||
No usages=Keine Verwendungen
 | 
			
		||||
Result=Ergebnis
 | 
			
		||||
Ingredient=Zutat
 | 
			
		||||
Show next recipe=Nächstes Rezept zeigen
 | 
			
		||||
Show next usage=Nächste Verwendung zeigen
 | 
			
		||||
Show previous recipe=Vorheriges Rezept zeigen
 | 
			
		||||
Show previous usage=Vorherige Verwendung zeigen
 | 
			
		||||
Give me:=Gib mir:
 | 
			
		||||
To craft grid:=Ins Fertigungsraster:
 | 
			
		||||
All=Alles
 | 
			
		||||
White=Weiß
 | 
			
		||||
Yellow=Gelb
 | 
			
		||||
Red=Rot
 | 
			
		||||
Green=Grün
 | 
			
		||||
Blue=Blau
 | 
			
		||||
Waypoints=Wegpunkte
 | 
			
		||||
Select Waypoint #@1=Wegpunkt Nr. @1 auswählen
 | 
			
		||||
Waypoint @1=Wegpunkt Nr. @1
 | 
			
		||||
Set waypoint to current location=Setze Wegpunkt zur derzeitigen Position
 | 
			
		||||
invisible=unsichtbar
 | 
			
		||||
visible=sichtbar
 | 
			
		||||
Make waypoint @1=Wegpunkt @1 machen
 | 
			
		||||
Disable=ausschalten
 | 
			
		||||
Enable=einschalten
 | 
			
		||||
@1 display of waypoint coordinates=Anzeige der Wegpunktkoordinaten @1
 | 
			
		||||
Change color of waypoint display=Farbe der Darstellung der Wegpunkte ändern
 | 
			
		||||
Edit waypoint name=Name des Wegpunkts ändern
 | 
			
		||||
Waypoint active=Wegpunkt aktiv
 | 
			
		||||
Waypoint inactive=Wegpunkt inaktiv
 | 
			
		||||
Finish editing=Bearbeitung abschließen
 | 
			
		||||
World position=Weltposition
 | 
			
		||||
Name=Name
 | 
			
		||||
HUD text color=HUD-Textfarbe
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Zwingt Unified Inventory, im Vollmodus angezeigt zu werden, wenn der Minimalmodus global eingestellt ist
 | 
			
		||||
							
								
								
									
										100
									
								
								locale/unified_inventory.es.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,100 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
 | 
			
		||||
# waypoints.lua
 | 
			
		||||
 | 
			
		||||
White=Blanco
 | 
			
		||||
Yellow=Amarillo
 | 
			
		||||
Red=Rojo
 | 
			
		||||
Green=Verde
 | 
			
		||||
Blue=Azul
 | 
			
		||||
Waypoints=Puntos
 | 
			
		||||
Select Waypoint #@1=Seleccionar Punto #@1
 | 
			
		||||
Waypoint @1=Punto @1
 | 
			
		||||
Set waypoint to current location=Establecer el punto a la ubicación actual
 | 
			
		||||
Make waypoint @1=Hacer punto @1
 | 
			
		||||
invisible=invisible
 | 
			
		||||
visible=visible
 | 
			
		||||
@1 display of waypoint coordinates=Visualizar coordenadas del punto @1
 | 
			
		||||
Disable=Deshabilitado
 | 
			
		||||
Enable=Habilitado
 | 
			
		||||
Change color of waypoint display=Cambiar el color del punto
 | 
			
		||||
Edit waypoint name=Editar nombre del punto
 | 
			
		||||
Waypoint active=Punto activo
 | 
			
		||||
Waypoint inactive=Punto inactivo
 | 
			
		||||
Finish editing=Terminar edición
 | 
			
		||||
World position=Posición en el mundo
 | 
			
		||||
Name=Nombre
 | 
			
		||||
HUD text color=Color del texto de la Interfaz
 | 
			
		||||
 | 
			
		||||
# group.lua
 | 
			
		||||
 | 
			
		||||
 and = y
 | 
			
		||||
 | 
			
		||||
# register.lua
 | 
			
		||||
 | 
			
		||||
Can use the creative inventory=Puede usar el inventario creativo
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Obliga al Inventario Unificado a mostrarse en modo Completo si el modo Simple está configurado globalmente
 | 
			
		||||
Crafting Grid=Cuadricula de Elaboración
 | 
			
		||||
Crafting Guide=Guía de Elaboración
 | 
			
		||||
Set home position=Establecer posición de la casa
 | 
			
		||||
Home position set to: @1=Posición de la casa cambiada a: @1
 | 
			
		||||
You don't have the \"home\" privilege!=¡No tienes el privilegio \"home\"!
 | 
			
		||||
Go home=Ir a casa
 | 
			
		||||
Set time to day=Cambiar a dia
 | 
			
		||||
Set time to night=Cambiar a noche
 | 
			
		||||
Time of day set to 6am=Hora del día cambiada a 6 AM
 | 
			
		||||
Time of day set to 9pm=Hora del día cambiada a 9 PM
 | 
			
		||||
You don't have the settime privilege!=¡No tienes el privilegio "settime"!
 | 
			
		||||
Clear inventory=Limpiar inventario
 | 
			
		||||
Inventory cleared!=¡Inventario limpio!
 | 
			
		||||
This button has been disabled outside=Este botón ha sido deshabilitado
 | 
			
		||||
Crafting=Elaboración
 | 
			
		||||
Trash:=Basura:
 | 
			
		||||
Refill:=Rellenar:
 | 
			
		||||
Any item belonging to the @1 group=Cualquier elemento que pertenezca al grupo @1
 | 
			
		||||
Any item belonging to the groups @1=Cualquier elemento perteneciente a los grupos @1
 | 
			
		||||
Recipe @1 of @2=Receta @1 de @2
 | 
			
		||||
Usage @1 of @2=Uso @1 de @2
 | 
			
		||||
No recipes=No tiene receta
 | 
			
		||||
No usages=No tiene uso
 | 
			
		||||
Result=Resultado
 | 
			
		||||
Ingredient=Ingrediente
 | 
			
		||||
Show next recipe=Mostrar la siguiente receta
 | 
			
		||||
Show next usage=Mostrar el siguiente uso
 | 
			
		||||
Show previous recipe=Mostrar la receta anterior
 | 
			
		||||
Show previous usage=Mostrar el uso anterior
 | 
			
		||||
@1 (@2)=@1 (@2)
 | 
			
		||||
Give me:=Dame:
 | 
			
		||||
This recipe is too@nlarge to be displayed.=Esta receta es demasiado@ngrande para ser mostrada.
 | 
			
		||||
To craft grid:=Construir:
 | 
			
		||||
All=Todos
 | 
			
		||||
 | 
			
		||||
# api.lua
 | 
			
		||||
 | 
			
		||||
Mixing=Mezclar
 | 
			
		||||
Cooking=Hornear
 | 
			
		||||
Digging=Recoger
 | 
			
		||||
 | 
			
		||||
# internal.lua
 | 
			
		||||
 | 
			
		||||
First page=Primera página
 | 
			
		||||
Back three pages=Volver tres páginas
 | 
			
		||||
Back one page=Volver una página
 | 
			
		||||
Forward one page=Avanzar una página
 | 
			
		||||
Forward three pages=Avanzar tres páginas
 | 
			
		||||
Last page=Ultima Pagina
 | 
			
		||||
Search=Buscar
 | 
			
		||||
Reset search and display everything=Limpiar la busqueda y mostrar todo
 | 
			
		||||
No matching items=No se encontraron elementos
 | 
			
		||||
No matches.=No hay resultados.
 | 
			
		||||
Page=Página
 | 
			
		||||
@1 of @2=@1 de @2
 | 
			
		||||
Filter=Filtro
 | 
			
		||||
 | 
			
		||||
# bags.lua
 | 
			
		||||
 | 
			
		||||
Bags=Bolsos
 | 
			
		||||
Bag @1=Bolso @1
 | 
			
		||||
Small Bag=Bolso Pequeño
 | 
			
		||||
Medium Bag=Bolso Mediano
 | 
			
		||||
Large Bag=Bolso Grande
 | 
			
		||||
							
								
								
									
										57
									
								
								locale/unified_inventory.fr.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,57 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Crafting=Création
 | 
			
		||||
Cooking=Cuisson
 | 
			
		||||
Digging=Creuser
 | 
			
		||||
Bags=Sacs
 | 
			
		||||
Bag @1=Sac @1
 | 
			
		||||
Small Bag=Petit sac
 | 
			
		||||
Medium Bag=Sac moyen
 | 
			
		||||
Large Bag=Grand sac
 | 
			
		||||
 and = et 
 | 
			
		||||
First page=1ère page
 | 
			
		||||
Back three pages=3 pages en arrière
 | 
			
		||||
Back one page=Page précédente
 | 
			
		||||
Forward one page=Page suivante
 | 
			
		||||
Forward three pages=3 pages en avant
 | 
			
		||||
Last page=Dernière page
 | 
			
		||||
Search=Rechercher
 | 
			
		||||
No matching items=Aucun élément correspondant
 | 
			
		||||
No matches.=Aucun match
 | 
			
		||||
Page=Page
 | 
			
		||||
@1 of @2=@1 de @2
 | 
			
		||||
Filter=Filtre
 | 
			
		||||
Can use the creative inventory=Vous pouvez utiliser l'inventaire créatif
 | 
			
		||||
Crafting Grid=Grille de création
 | 
			
		||||
Crafting Guide=Guide de création
 | 
			
		||||
Set home position=Position dans le monde
 | 
			
		||||
Home position set to: @1=Position de votre base fixée à: @1
 | 
			
		||||
You don't have the "home" privilege!=Vous n'avez pas le privilège "home"!
 | 
			
		||||
Time of day set to 6am=Heure fixée à 6h
 | 
			
		||||
You don't have the settime privilege!=Vous n'avez pas le privilège "settime"!
 | 
			
		||||
Time of day set to 9pm=Heure fixée à 21h
 | 
			
		||||
Inventory cleared!=Inventaire vidé !
 | 
			
		||||
Trash:=Poubelle :
 | 
			
		||||
Refill:=Remplir :
 | 
			
		||||
Recipe @1 of @2=Recette @1 de @2
 | 
			
		||||
Result=Résultat
 | 
			
		||||
To craft grid:=Sur de création:
 | 
			
		||||
All=Tout
 | 
			
		||||
White=Blanc
 | 
			
		||||
Yellow=Jaune
 | 
			
		||||
Red=Rouge
 | 
			
		||||
Green=Vert
 | 
			
		||||
Blue=Bleu
 | 
			
		||||
Waypoints=Point de passage
 | 
			
		||||
Select Waypoint #@1=Choisir un point de passage #@1
 | 
			
		||||
Waypoint @1=Point de passage @1
 | 
			
		||||
Set waypoint to current location=Marquer un point de passage à la position actuelle
 | 
			
		||||
Make waypoint @1=Rendre @1 le point de passage
 | 
			
		||||
@1 display of waypoint coordinates=@1 montrer les coordonnées des points de passages
 | 
			
		||||
Change color of waypoint display=Changer la couleur du point de passage
 | 
			
		||||
Edit waypoint name=Editer le nom du point de passage
 | 
			
		||||
Waypoint active=Point de passage actif
 | 
			
		||||
Waypoint inactive=Point de passage inactif
 | 
			
		||||
Finish editing=Terminer l'édition
 | 
			
		||||
World position=Position dans le monde
 | 
			
		||||
Name=Nom
 | 
			
		||||
HUD text color=Couleur de texte du HUD
 | 
			
		||||
							
								
								
									
										79
									
								
								locale/unified_inventory.it.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,79 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Crafting=Assemblaggio
 | 
			
		||||
Mixing=Unione
 | 
			
		||||
Cooking=Cottura
 | 
			
		||||
Digging=Scavo
 | 
			
		||||
Bags=Borse
 | 
			
		||||
Bag @1=Borsa @1
 | 
			
		||||
Small Bag=Borsa piccola
 | 
			
		||||
Medium Bag=Borsa media
 | 
			
		||||
Large Bag=Borsa grande
 | 
			
		||||
 and = e 
 | 
			
		||||
First page=Prima pagina
 | 
			
		||||
Back three pages=Indietro di tre pagine
 | 
			
		||||
Back one page=Indietro di una pagina
 | 
			
		||||
Forward one page=Avanti di una pagina
 | 
			
		||||
Forward three pages=Avanti di tre pagine
 | 
			
		||||
Last page=Ultima pagina
 | 
			
		||||
Search=Cerca
 | 
			
		||||
Reset search and display everything=Azzera la ricerca e mostra tutto
 | 
			
		||||
No matching items=Nessun oggetto corrispondente
 | 
			
		||||
No matches.=Nessuna corrispondenza.
 | 
			
		||||
Page=Pagina
 | 
			
		||||
@1 of @2=@1 di @2
 | 
			
		||||
Filter=Filtro
 | 
			
		||||
Can use the creative inventory=Può usare l'inventario creativo
 | 
			
		||||
Crafting Grid=Griglia di assemblaggio
 | 
			
		||||
Crafting Guide=Guida di assemblaggio
 | 
			
		||||
Set home position=Imposta la residenza
 | 
			
		||||
Home position set to: @1=Residenza impostata su: @1
 | 
			
		||||
You don't have the "home" privilege!=Non hai il privilegio "home"!
 | 
			
		||||
Go home=Torna a casa
 | 
			
		||||
Set time to day=Imposta l'orario sul giorno
 | 
			
		||||
Time of day set to 6am=Orario impostato sulle 6am
 | 
			
		||||
You don't have the settime privilege!=Non hai il privilegio "time"!
 | 
			
		||||
Set time to night=Imposta l'orario sulla notte
 | 
			
		||||
Time of day set to 9pm=Orario impostato sulle 9am
 | 
			
		||||
Clear inventory=Ripulisci l'inventario
 | 
			
		||||
Inventory cleared!=Inventario ripulito!
 | 
			
		||||
Trash:=Butta:
 | 
			
		||||
Refill:=Riempi:
 | 
			
		||||
Any item belonging to the @1 group=Qualunque oggetto appartenente al gruppo @1
 | 
			
		||||
Any item belonging to the groups @1=Qualunque oggetto appartenente ai gruppi @1
 | 
			
		||||
Recipe @1 of @2=Ricetta @1 di @2
 | 
			
		||||
Usage @1 of @2=Uso @1 di @2
 | 
			
		||||
No recipes=Nessuna ricetta
 | 
			
		||||
No usages=Nessun utilizzo
 | 
			
		||||
Result=Risultato
 | 
			
		||||
Ingredient=Ingrediente
 | 
			
		||||
Show next recipe=Mostra la prossima ricetta
 | 
			
		||||
Show next usage=Mostra il prossimo utilizzo
 | 
			
		||||
Show previous recipe=Mostra la ricetta precedente
 | 
			
		||||
Show previous usage=Mostra l'utilizzo precedente
 | 
			
		||||
Give me:=Dammi:
 | 
			
		||||
To craft grid:=Alla griglia di assemblaggio:
 | 
			
		||||
All=Tutto
 | 
			
		||||
White=Bianco
 | 
			
		||||
Yellow=Giallo
 | 
			
		||||
Red=Rosso
 | 
			
		||||
Green=Verde
 | 
			
		||||
Blue=Blu
 | 
			
		||||
Waypoints=Tappe
 | 
			
		||||
Select Waypoint #@1=Seleziona tappa n°@1
 | 
			
		||||
Waypoint @1=Tappa @1
 | 
			
		||||
Set waypoint to current location=Imposta tappa alla posizione attuale
 | 
			
		||||
invisible=invisibile
 | 
			
		||||
visible=visibile
 | 
			
		||||
Make waypoint @1=Crea tappa @1
 | 
			
		||||
Disable=Disabilita
 | 
			
		||||
Enable=Abilita
 | 
			
		||||
@1 display of waypoint coordinates=@1 la visualizzazione delle coordinate della tappa
 | 
			
		||||
Change color of waypoint display=Modifica il colore della visualizzazione della tappa
 | 
			
		||||
Edit waypoint name=Modifica il nome della tappa
 | 
			
		||||
Waypoint active=Tappa attiva
 | 
			
		||||
Waypoint inactive=Tappa inattiva
 | 
			
		||||
Finish editing=Termina la modifica
 | 
			
		||||
World position=Posizione del mondo
 | 
			
		||||
Name=Nome
 | 
			
		||||
HUD text color=Colore del testo del visore
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Forza la visualizzazione di Unified Inventory in modalità completa se è configurata globalmente la visualizzazione semplice
 | 
			
		||||
							
								
								
									
										78
									
								
								locale/unified_inventory.ms.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,78 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Crafting=Pertukangan
 | 
			
		||||
Mixing=Pencampuran
 | 
			
		||||
Cooking=Pemasakan
 | 
			
		||||
Digging=Penggalian
 | 
			
		||||
Bags=Beg
 | 
			
		||||
Bag @1=Beg @1
 | 
			
		||||
Small Bag=Beg Kecil
 | 
			
		||||
Medium Bag=Beg Sederhana
 | 
			
		||||
Large Bag=Beg Besar
 | 
			
		||||
 and = dan 
 | 
			
		||||
First page=Halaman pertama
 | 
			
		||||
Back three pages=Tiga halaman sebelumnya
 | 
			
		||||
Back one page=Halaman sebelumnya
 | 
			
		||||
Forward one page=Halaman seterusnya
 | 
			
		||||
Forward three pages=Tiga halaman seterusnya
 | 
			
		||||
Last page=Halaman terakhir
 | 
			
		||||
Search=Cari
 | 
			
		||||
Reset search and display everything=Set semula carian dan tunjukkan semua benda
 | 
			
		||||
No matching items=Tiada item sepadan
 | 
			
		||||
No matches.=Tiada padanan.
 | 
			
		||||
Page=Halaman
 | 
			
		||||
@1 of @2=@1 drpd @2
 | 
			
		||||
Filter=Tapis
 | 
			
		||||
Can use the creative inventory=Boleh guna inventori kreatif
 | 
			
		||||
Crafting Grid=Grid Pertukangan
 | 
			
		||||
Crafting Guide=Panduan Pertukangan
 | 
			
		||||
Set home position=Tetapkan kedudukan rumah
 | 
			
		||||
Home position set to: @1=Kedudukan rumah ditetapkan ke: @1
 | 
			
		||||
You don't have the "home" privilege!=Anda tidak ada keistimewaan "home"!
 | 
			
		||||
Go home=Balik rumah
 | 
			
		||||
Set time to day=Tetapkan masa jadi siang
 | 
			
		||||
Time of day set to 6am=Masa ditetapkan ke 6 pagi
 | 
			
		||||
You don't have the settime privilege!=Anda tidak ada keistimewaan settime!
 | 
			
		||||
Set time to night=Tetapkan masa jadi malam
 | 
			
		||||
Time of day set to 9pm=Masa ditetapkan ke 9 malam
 | 
			
		||||
Clear inventory=Kosongkan inventori
 | 
			
		||||
Inventory cleared!=Inventori dikosongkan!
 | 
			
		||||
Trash:=Buang:
 | 
			
		||||
Refill:=Isi balik:
 | 
			
		||||
Any item belonging to the @1 group=Sebarang item dari kumpulan @1
 | 
			
		||||
Any item belonging to the groups @1=Sebarang item dari kumpulan @1
 | 
			
		||||
Recipe @1 of @2=Resipi @1 drpd @2
 | 
			
		||||
Usage @1 of @2=Kegunaan @1 drpd @2
 | 
			
		||||
No recipes=Tiada resipi
 | 
			
		||||
No usages=Tiada kegunaan
 | 
			
		||||
Result=Hasil
 | 
			
		||||
Ingredient=Bahan
 | 
			
		||||
Show next recipe=Tunjuk resipi seterusnya
 | 
			
		||||
Show next usage=Tunjuk kegunaan seterusnya
 | 
			
		||||
Show previous recipe=Tunjuk resipi sebelumnya
 | 
			
		||||
Show previous usage=Tunjuk kegunaan sebelumnya
 | 
			
		||||
@1 (@2)=@1 (@2)
 | 
			
		||||
Give me:=Beri saya:
 | 
			
		||||
To craft grid:=Ke grid pertukangan:
 | 
			
		||||
White=Putih
 | 
			
		||||
Yellow=Kuning
 | 
			
		||||
Red=Merah
 | 
			
		||||
Green=Hijau
 | 
			
		||||
Blue=Biru
 | 
			
		||||
Waypoints=Titik Arah
 | 
			
		||||
Select Waypoint #@1=Pilih Titik Arah #@1
 | 
			
		||||
Waypoint @1=Titik Arah @1
 | 
			
		||||
Set waypoint to current location=Tetapkan titik arah ke lokasi semasa
 | 
			
		||||
invisible=Sembunyikan
 | 
			
		||||
visible=Paparkan
 | 
			
		||||
Make waypoint @1=@1 titik arah
 | 
			
		||||
Disable=Sembunyikan
 | 
			
		||||
Enable=Paparkan
 | 
			
		||||
@1 display of waypoint coordinates=@1 koordinat untuk titik arah
 | 
			
		||||
Change color of waypoint display=Tukar warna paparan titik arah
 | 
			
		||||
Edit waypoint name=Edit nama titik arah
 | 
			
		||||
Waypoint active=Titik arah aktif
 | 
			
		||||
Waypoint inactive=Titik arah tidak aktif
 | 
			
		||||
Finish editing=Selesai edit
 | 
			
		||||
World position=Kedudukan dunia
 | 
			
		||||
Name=Nama
 | 
			
		||||
HUD text color=Warna tulisan HUD
 | 
			
		||||
							
								
								
									
										61
									
								
								locale/unified_inventory.pl.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,61 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Bags=Plecaki
 | 
			
		||||
Bag @1=Plecak @1
 | 
			
		||||
Small Bag=Maly plecak
 | 
			
		||||
Medium Bag=Sredni plecak
 | 
			
		||||
Large Bag=Duzy plecak
 | 
			
		||||
 and = i 
 | 
			
		||||
First page=Pierwsza strona
 | 
			
		||||
Back three pages=3 strony w tyl
 | 
			
		||||
Back one page=1 strona w tyl
 | 
			
		||||
Forward one page=1 strona do przodu
 | 
			
		||||
Forward three pages=3 strony do przodu
 | 
			
		||||
Last page=Ostatnia strona
 | 
			
		||||
Search=Szukaj
 | 
			
		||||
No matching items=Brak pasujacych przedmiotow
 | 
			
		||||
No matches.=Brak wyników
 | 
			
		||||
Page=Strona
 | 
			
		||||
@1 of @2=@1 z @2
 | 
			
		||||
Filter=Filtr
 | 
			
		||||
Set home position=Ustaw pozycję wyjściową
 | 
			
		||||
Home position set to: @1=Pozycja domowa ustawiona na: @1
 | 
			
		||||
You don't have the "home" privilege!=Nie masz uprawnien do zmiany czasu "home"!
 | 
			
		||||
Go home=Idź do domu
 | 
			
		||||
Set time to day=Ustaw czas na dzień
 | 
			
		||||
Time of day set to 6am=Czas ustawiony na 6:00
 | 
			
		||||
You don't have the settime privilege!=Nie masz uprawnien do zmiany czasu "settime"!
 | 
			
		||||
Set time to night=Ustaw czas na noc
 | 
			
		||||
Time of day set to 9pm=Czas ustawiony na 21:00
 | 
			
		||||
Clear inventory=Wyczyść zapasy
 | 
			
		||||
Inventory cleared!=Zapasy zostały wyczyszczone!
 | 
			
		||||
Trash:=Smietnik:
 | 
			
		||||
Refill:=Uzupelnianie:
 | 
			
		||||
Recipe @1 of @2=Recepta @1 z @2
 | 
			
		||||
Usage @1 of @2=Użycie @1 z @2
 | 
			
		||||
No recipes=Brak recepty
 | 
			
		||||
No usages=Bez użycia
 | 
			
		||||
Result=Wynik
 | 
			
		||||
Ingredient=Składnik
 | 
			
		||||
Give me:=Daj mi:
 | 
			
		||||
All=Wszystko
 | 
			
		||||
White=Bialy
 | 
			
		||||
Yellow=Zolty
 | 
			
		||||
Red=Czerwony
 | 
			
		||||
Green=Zielony
 | 
			
		||||
Blue=Niebieski
 | 
			
		||||
Waypoints=Punkty orientacyjne
 | 
			
		||||
Select Waypoint #@1=Wybierz punkt #@1
 | 
			
		||||
Waypoint @1=Punkty orientacyjne @1
 | 
			
		||||
Set waypoint to current location=Ustaw punkt orientacyjny na biezacej pozycji
 | 
			
		||||
invisible=niewidzialny
 | 
			
		||||
visible=widomy
 | 
			
		||||
Make waypoint @1=Robić punkt @1
 | 
			
		||||
@1 display of waypoint coordinates=@1 koordynatow punktu
 | 
			
		||||
Change color of waypoint display=Zmien kolor punktu
 | 
			
		||||
Edit waypoint name=Edytuj nazwe punktu
 | 
			
		||||
Waypoint active=Punkt wlaczony
 | 
			
		||||
Waypoint inactive=Punkt wylaczony
 | 
			
		||||
Finish editing=Zakoncz edycje
 | 
			
		||||
World position=Pozycja
 | 
			
		||||
Name=Nazwa
 | 
			
		||||
HUD text color=Kolor tekstu HUD
 | 
			
		||||
							
								
								
									
										76
									
								
								locale/unified_inventory.pt.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,76 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Crafting=Artesanato
 | 
			
		||||
Mixing=Muistura
 | 
			
		||||
Cooking=Cozimento
 | 
			
		||||
Digging=Escavação
 | 
			
		||||
Bags=Bolsas
 | 
			
		||||
Bag @1=Bolsa @1
 | 
			
		||||
Small Bag=Bolsa Pequena
 | 
			
		||||
Medium Bag=Bolsa Média
 | 
			
		||||
Large Bag=Bolsa Grande
 | 
			
		||||
 and = e 
 | 
			
		||||
First page=Primeira Página
 | 
			
		||||
Back three pages=Voltar 3 Páginas
 | 
			
		||||
Back one page=Voltar 1 Página
 | 
			
		||||
Forward one page=Avançar 1 Página
 | 
			
		||||
Forward three pages=Avançar 3 Páginas
 | 
			
		||||
Last page=Ultima Página
 | 
			
		||||
Search=Pesquisar
 | 
			
		||||
Reset search and display everything=Redefinir pesquisa e exibir tudo
 | 
			
		||||
No matching items=Nenhum item correspondente
 | 
			
		||||
No matches.=Sem correspondências
 | 
			
		||||
Page=Página
 | 
			
		||||
@1 of @2=@1 de @2
 | 
			
		||||
Filter=Filtro
 | 
			
		||||
Can use the creative inventory=Pode usar o inventário do criativo
 | 
			
		||||
Crafting Grid=Grade de Artesanato
 | 
			
		||||
Crafting Guide=Guia de Artesanato
 | 
			
		||||
Set home position=Definir posição de casa
 | 
			
		||||
Home position set to: @1=Posição inicial definida para: @1
 | 
			
		||||
You don't have the "home" privilege!=Você não tem o privilégio de "home"!
 | 
			
		||||
Go home=Transportar para Casa
 | 
			
		||||
Set time to day=Definir turno para dia
 | 
			
		||||
Time of day set to 6am=Hora do dia definida para 06h
 | 
			
		||||
You don't have the settime privilege!=Você não tem o privilégio de "settime"!
 | 
			
		||||
Set time to night=Definir turno para noite
 | 
			
		||||
Time of day set to 9pm=Hora do dia ajustada para 21h
 | 
			
		||||
Clear inventory=Limpar Inventário
 | 
			
		||||
Inventory cleared!=Inventário Apagado!
 | 
			
		||||
Trash:=Lixo:
 | 
			
		||||
Refill:=Recarga:
 | 
			
		||||
Any item belonging to the @1 group=Qualquer item pertencente ao grupo '@1'.
 | 
			
		||||
Any item belonging to the groups @1=Qualquer item pertencente aos grupos '@1'.
 | 
			
		||||
Recipe @1 of @2=Receita @1 de @2
 | 
			
		||||
Usage @1 of @2=Utilização @1 de @2
 | 
			
		||||
No recipes=Sem Receita
 | 
			
		||||
No usages=Sem Utilização
 | 
			
		||||
Result=Resultado
 | 
			
		||||
Ingredient=Ingrediente
 | 
			
		||||
Show next recipe=Exibir Próxima Receita
 | 
			
		||||
Show next usage=Mostrar Próxima Utilização
 | 
			
		||||
Show previous recipe=Exibir Receita Anterior
 | 
			
		||||
Show previous usage=Exibir Utilização Anterior
 | 
			
		||||
Give me:=Gerado:
 | 
			
		||||
To craft grid:=Para Grade de Artesanato
 | 
			
		||||
All=MAX
 | 
			
		||||
White=Branco
 | 
			
		||||
Yellow=Amarelo
 | 
			
		||||
Red=Vermelho
 | 
			
		||||
Green=Verde
 | 
			
		||||
Blue=Azul
 | 
			
		||||
Waypoints=Apontador de Direção
 | 
			
		||||
Select Waypoint #@1=Seleção de Apontador de Direção #@1
 | 
			
		||||
Waypoint @1=Apontador de Direção @1
 | 
			
		||||
Set waypoint to current location=Configurar localização atual do Apontador de Direção
 | 
			
		||||
invisible=invisível
 | 
			
		||||
visible=visível
 | 
			
		||||
Make waypoint @1=Fazer Apontador de Direção @1
 | 
			
		||||
@1 display of waypoint coordinates=@1 exibição de coordenadas de Fazer Apontador de Direção
 | 
			
		||||
Change color of waypoint display=Mudar cor exibida do Apontador de Direção
 | 
			
		||||
Edit waypoint name=Editar Nome de Apontador de Direção
 | 
			
		||||
Waypoint active=Apontador de Direção Ativo
 | 
			
		||||
Waypoint inactive=Apontador de Direção Inativo
 | 
			
		||||
Finish editing=Edição Finalizada
 | 
			
		||||
World position=Posição Mundial
 | 
			
		||||
Name=Nome
 | 
			
		||||
HUD text color=Cor de HUD
 | 
			
		||||
							
								
								
									
										78
									
								
								locale/unified_inventory.ru.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,78 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Crafting=Крафт
 | 
			
		||||
Mixing=Мешать
 | 
			
		||||
Cooking=Варить
 | 
			
		||||
Digging=Копать
 | 
			
		||||
Bags=Сумки
 | 
			
		||||
Bag @1=Сумка @1
 | 
			
		||||
Small Bag=Малая сумка
 | 
			
		||||
Medium Bag=Средняя сумка
 | 
			
		||||
Large Bag=Большая сумка
 | 
			
		||||
 and = и 
 | 
			
		||||
First page=Первая страница
 | 
			
		||||
Back three pages=3 страницы назад
 | 
			
		||||
Back one page=1 страницу назад
 | 
			
		||||
Forward one page=1 страницу вперёд
 | 
			
		||||
Forward three pages=3 страницы вперёд
 | 
			
		||||
Last page=Последняя страница
 | 
			
		||||
Search=Поиск
 | 
			
		||||
Reset search and display everything=Сброс поиска, показать всё
 | 
			
		||||
No matching items=Нет подходящих элементов
 | 
			
		||||
No matches.=Ничего не найдено
 | 
			
		||||
Page=Страница
 | 
			
		||||
@1 of @2=@1 из @2
 | 
			
		||||
Filter=Фильтр
 | 
			
		||||
Can use the creative inventory=Можно использовать инвентарь творческого режима
 | 
			
		||||
Crafting Grid=Решетка крафта
 | 
			
		||||
Crafting Guide=Книга рецептов
 | 
			
		||||
Set home position=Установить позицию дома
 | 
			
		||||
Home position set to: @1=Дом теперь расположен по коодинатам: @1
 | 
			
		||||
You don't have the "home" privilege!=У вас нет привилегии "home"!
 | 
			
		||||
Go home=Отправиться домой
 | 
			
		||||
Set time to day=День
 | 
			
		||||
Time of day set to 6am=Установлено время 6 утра
 | 
			
		||||
You don't have the settime privilege!=Вам не разрешено устанавливать время! (нет привилегии "settime")
 | 
			
		||||
Set time to night=Ночь
 | 
			
		||||
Time of day set to 9pm=Установлено время 9 вечера
 | 
			
		||||
Clear inventory=Очистить инвентарь
 | 
			
		||||
Inventory cleared!=Инвентарь очищен!
 | 
			
		||||
Trash:=Мусор:
 | 
			
		||||
Refill:=Наполнить:
 | 
			
		||||
Any item belonging to the @1 group=Любой элемент из группы: @1
 | 
			
		||||
Any item belonging to the groups @1=Любой элемент из группы: @1
 | 
			
		||||
Recipe @1 of @2=Рецепт @1 из @2
 | 
			
		||||
Usage @1 of @2=Вариант @1 of @2
 | 
			
		||||
No recipes=Рецептов нет
 | 
			
		||||
No usages=Не используется
 | 
			
		||||
Result=Результат
 | 
			
		||||
Ingredient=Состав
 | 
			
		||||
Show next recipe=Следующий рецепт
 | 
			
		||||
Show next usage=Следующее использование
 | 
			
		||||
Show previous recipe=Прошлый рецепт
 | 
			
		||||
Show previous usage=Прошлая страница
 | 
			
		||||
Give me:=Дай мне:
 | 
			
		||||
To craft grid:=На решeтку крафта:
 | 
			
		||||
All=Все
 | 
			
		||||
White=Белый
 | 
			
		||||
Yellow=Желтый
 | 
			
		||||
Red=Красный
 | 
			
		||||
Green=Зелёный
 | 
			
		||||
Blue=Синий
 | 
			
		||||
Waypoints=Путевые точки
 | 
			
		||||
Select Waypoint #@1=Выбрать путевую точку №@1
 | 
			
		||||
Waypoint @1=Путевая точка @1
 | 
			
		||||
Set waypoint to current location=Установить путевую точку по текущей позиции
 | 
			
		||||
invisible=невидимой
 | 
			
		||||
visible=видимой
 | 
			
		||||
Make waypoint @1=Сделать путевую точку @1
 | 
			
		||||
Disable=Выключить
 | 
			
		||||
Enable=Включить
 | 
			
		||||
@1 display of waypoint coordinates=@1 показ координат путевых точек
 | 
			
		||||
Change color of waypoint display=Поменять цвет путевой точки
 | 
			
		||||
Edit waypoint name=Переименовать путевую точку
 | 
			
		||||
Waypoint active=Путевая точка включена
 | 
			
		||||
Waypoint inactive=Путевая точка выключена
 | 
			
		||||
Finish editing=Закончить редакцию
 | 
			
		||||
World position=Позиция мира
 | 
			
		||||
Name=Имя
 | 
			
		||||
HUD text color=Цвет текста HUDа
 | 
			
		||||
							
								
								
									
										100
									
								
								locale/unified_inventory.template.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,100 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
 | 
			
		||||
# waypoints.lua
 | 
			
		||||
 | 
			
		||||
White=
 | 
			
		||||
Yellow=
 | 
			
		||||
Red=
 | 
			
		||||
Green=
 | 
			
		||||
Blue=
 | 
			
		||||
Waypoints=
 | 
			
		||||
Select Waypoint #@1=
 | 
			
		||||
Waypoint @1=
 | 
			
		||||
Set waypoint to current location=
 | 
			
		||||
Make waypoint @1=
 | 
			
		||||
invisible=
 | 
			
		||||
visible=
 | 
			
		||||
@1 display of waypoint coordinates=
 | 
			
		||||
Disable=
 | 
			
		||||
Enable=
 | 
			
		||||
Change color of waypoint display=
 | 
			
		||||
Edit waypoint name=
 | 
			
		||||
Waypoint active=
 | 
			
		||||
Waypoint inactive=
 | 
			
		||||
Finish editing=
 | 
			
		||||
World position=
 | 
			
		||||
Name=
 | 
			
		||||
HUD text color=
 | 
			
		||||
 | 
			
		||||
# group.lua
 | 
			
		||||
 | 
			
		||||
 and =
 | 
			
		||||
 | 
			
		||||
# register.lua
 | 
			
		||||
 | 
			
		||||
Can use the creative inventory=
 | 
			
		||||
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
 | 
			
		||||
Crafting Grid=
 | 
			
		||||
Crafting Guide=
 | 
			
		||||
Set home position=
 | 
			
		||||
Home position set to: @1=
 | 
			
		||||
You don't have the \"home\" privilege!=
 | 
			
		||||
Go home=
 | 
			
		||||
Set time to day=
 | 
			
		||||
Set time to night=
 | 
			
		||||
Time of day set to 6am=
 | 
			
		||||
Time of day set to 9pm=
 | 
			
		||||
You don't have the settime privilege!=
 | 
			
		||||
Clear inventory=
 | 
			
		||||
Inventory cleared!=
 | 
			
		||||
This button has been disabled outside=
 | 
			
		||||
Crafting=
 | 
			
		||||
Trash:=
 | 
			
		||||
Refill:=
 | 
			
		||||
Any item belonging to the @1 group=
 | 
			
		||||
Any item belonging to the groups @1=
 | 
			
		||||
Recipe @1 of @2=
 | 
			
		||||
Usage @1 of @2=
 | 
			
		||||
No recipes=
 | 
			
		||||
No usages=
 | 
			
		||||
Result=
 | 
			
		||||
Ingredient=
 | 
			
		||||
Show next recipe=
 | 
			
		||||
Show next usage=
 | 
			
		||||
Show previous recipe=
 | 
			
		||||
Show previous usage=
 | 
			
		||||
@1 (@2)=
 | 
			
		||||
Give me:=
 | 
			
		||||
This recipe is too@nlarge to be displayed.=
 | 
			
		||||
To craft grid:=
 | 
			
		||||
All=
 | 
			
		||||
 | 
			
		||||
# api.lua
 | 
			
		||||
 | 
			
		||||
Mixing=
 | 
			
		||||
Cooking=
 | 
			
		||||
Digging=
 | 
			
		||||
 | 
			
		||||
# internal.lua
 | 
			
		||||
 | 
			
		||||
First page=
 | 
			
		||||
Back three pages=
 | 
			
		||||
Back one page=
 | 
			
		||||
Forward one page=
 | 
			
		||||
Forward three pages=
 | 
			
		||||
Last page=
 | 
			
		||||
Search=
 | 
			
		||||
Reset search and display everything=
 | 
			
		||||
No matching items=
 | 
			
		||||
No matches.=
 | 
			
		||||
Page=
 | 
			
		||||
@1 of @2=
 | 
			
		||||
Filter=
 | 
			
		||||
 | 
			
		||||
# bags.lua
 | 
			
		||||
 | 
			
		||||
Bags=
 | 
			
		||||
Bag @1=
 | 
			
		||||
Small Bag=
 | 
			
		||||
Medium Bag=
 | 
			
		||||
Large Bag=
 | 
			
		||||
							
								
								
									
										69
									
								
								locale/unified_inventory.tr.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,69 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
Crafting=Üretim
 | 
			
		||||
Mixing=Karıştırma
 | 
			
		||||
Cooking=Pişirme
 | 
			
		||||
Digging=Kazma
 | 
			
		||||
Bags=Çantalarım
 | 
			
		||||
Bag @1=@1. Çanta
 | 
			
		||||
Small Bag=Küçük Çanta
 | 
			
		||||
Medium Bag=Çanta
 | 
			
		||||
Large Bag=Büyük Çanta
 | 
			
		||||
 and = ve 
 | 
			
		||||
First page=İlk Sayfa
 | 
			
		||||
Back three pages=3 Sayfa Gerile
 | 
			
		||||
Back one page=Geri
 | 
			
		||||
Forward one page=İleri
 | 
			
		||||
Forward three pages=3 Sayfa İlerile
 | 
			
		||||
Last page=Son Sayfa
 | 
			
		||||
Search=Ara
 | 
			
		||||
No matching items=Eşleşme yok
 | 
			
		||||
No matches.=Eşleşme yok
 | 
			
		||||
Page=Sayfa
 | 
			
		||||
@1 of @2=@1 dan @2
 | 
			
		||||
Filter=Süzgeç
 | 
			
		||||
Can use the creative inventory=Yaratıcı envanteri kullanabilir
 | 
			
		||||
Crafting Grid=Üretim tablosu
 | 
			
		||||
Crafting Guide=Kılavuz
 | 
			
		||||
Set home position=Set ev pozisyon
 | 
			
		||||
Home position set to: @1=Yeni eviniz: @1
 | 
			
		||||
You don't have the "home" privilege!="home" yetkiniz yok!
 | 
			
		||||
Go home=Eve git
 | 
			
		||||
Set time to day=Güne zaman ayarla
 | 
			
		||||
Time of day set to 6am=Saat 06:00 olarak ayarlandı
 | 
			
		||||
You don't have the settime privilege!="settime" yetkiniz yok!
 | 
			
		||||
Set time to night=Geceye zaman ayarla
 | 
			
		||||
Time of day set to 9pm=Saat 19:00 olarak ayarlandı
 | 
			
		||||
msgid ""=Yaratıcı modu dışında iken bu tuş kullanılamaz.
 | 
			
		||||
Inventory cleared!=Envanter temizlendi!
 | 
			
		||||
Trash:=Çöp
 | 
			
		||||
Refill:=Doldur
 | 
			
		||||
Recipe @1 of @2=@1 dan @2 tarifi
 | 
			
		||||
Usage @1 of @2=Kullanım @1/@2
 | 
			
		||||
No recipes=Tarifi yok
 | 
			
		||||
No usages=Kullanım yok
 | 
			
		||||
Result=Çıktı
 | 
			
		||||
Ingredient=Bileşen
 | 
			
		||||
Give me:=Ver bana:
 | 
			
		||||
To craft grid:=Üretim tablosuna kopyala
 | 
			
		||||
All=Tümü
 | 
			
		||||
White=Beyaz
 | 
			
		||||
Yellow=Sarı
 | 
			
		||||
Red=Kırmızı
 | 
			
		||||
Green=Yeşil
 | 
			
		||||
Blue=Mavi
 | 
			
		||||
Waypoints=Konum Noktaları
 | 
			
		||||
Select Waypoint #@1=#@1 konum noktası seç
 | 
			
		||||
Waypoint @1=@1 Konum Noktaları
 | 
			
		||||
Set waypoint to current location=Bulunduğun noktayı işaretle
 | 
			
		||||
invisible=görünmez
 | 
			
		||||
visible=görünür
 | 
			
		||||
Make waypoint @1=Yol noktası @1
 | 
			
		||||
@1 display of waypoint coordinates=Yol noktası koordinatlarının görüntülenmesini @1
 | 
			
		||||
Change color of waypoint display=Konum Gösterge Rengi
 | 
			
		||||
Edit waypoint name=Konum Noktasını Düzenle
 | 
			
		||||
Waypoint active=Konum Etkin
 | 
			
		||||
Waypoint inactive=Konum Devredışı
 | 
			
		||||
Finish editing=Düzenleme bitti
 | 
			
		||||
World position=Dünya konumu
 | 
			
		||||
Name=İsim
 | 
			
		||||
HUD text color=Metin rengi
 | 
			
		||||
							
								
								
									
										78
									
								
								locale/unified_inventory.zh_CN.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,78 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
# traslation by: IFRFSX(BingFengFSX)
 | 
			
		||||
#Email: IFRFSX@Protonmail.com
 | 
			
		||||
 | 
			
		||||
Crafting=合成
 | 
			
		||||
Mixing=混合
 | 
			
		||||
Cooking=烹饪
 | 
			
		||||
Digging=挖出
 | 
			
		||||
Bags=背包
 | 
			
		||||
Bag @1=背包@1
 | 
			
		||||
Small Bag=小背包
 | 
			
		||||
Medium Bag=中背包
 | 
			
		||||
Large Bag=大背包
 | 
			
		||||
 and = 和 
 | 
			
		||||
First page=第一页
 | 
			
		||||
Back three pages=后退三页
 | 
			
		||||
Back one page=后退一页
 | 
			
		||||
Forward one page=前进一页
 | 
			
		||||
Forward three pages=前进三页
 | 
			
		||||
Last page=最后一页
 | 
			
		||||
Search=搜索
 | 
			
		||||
No matching items=没有匹配物品
 | 
			
		||||
No matches.=没有匹配
 | 
			
		||||
Page=页面
 | 
			
		||||
@1 of @2=第@1页,共@2页
 | 
			
		||||
Filter=过滤器
 | 
			
		||||
Can use the creative inventory=可以使用创造背包
 | 
			
		||||
Crafting Grid=合成表
 | 
			
		||||
Crafting Guide=合成指南
 | 
			
		||||
Set home position=设置家的位置
 | 
			
		||||
Home position set to: @1=家的位置设置到: @1
 | 
			
		||||
You don't have the "home" privilege!=你没有“home”权限!
 | 
			
		||||
Go home=回家
 | 
			
		||||
Set time to day=设置时间到白天
 | 
			
		||||
Time of day set to 6am=时间设置到早晨6点
 | 
			
		||||
You don't have the settime privilege!=你没有“settime”权限!
 | 
			
		||||
Set time to night=设置时间到晚上
 | 
			
		||||
Time of day set to 9pm=时间设置到晚上9点
 | 
			
		||||
 | 
			
		||||
Inventory cleared!=清空背包
 | 
			
		||||
Clear inventory=清空背包
 | 
			
		||||
 | 
			
		||||
Trash:=丢弃:
 | 
			
		||||
Refill:=填满:
 | 
			
		||||
Recipe @1 of @2=第@1配方,共@2个
 | 
			
		||||
Usage @1 of @2=第@1用法,共@2个
 | 
			
		||||
No recipes=没有配方
 | 
			
		||||
No usages=没有用法
 | 
			
		||||
Result=结果
 | 
			
		||||
Ingredient=原料
 | 
			
		||||
Give me:=给予:
 | 
			
		||||
To craft grid:=填充物品到合成表
 | 
			
		||||
All=全部
 | 
			
		||||
White=白
 | 
			
		||||
Yellow=黄
 | 
			
		||||
Red=红
 | 
			
		||||
Green=绿
 | 
			
		||||
Blue=蓝
 | 
			
		||||
Waypoints=航路点
 | 
			
		||||
Select Waypoint #@1=查询航路点 #@1
 | 
			
		||||
Waypoint @1=航路点 @1
 | 
			
		||||
Set waypoint to current location=将航路点设置到当前位置
 | 
			
		||||
invisible=不可见的
 | 
			
		||||
visible=可见的
 | 
			
		||||
Make waypoint @1=设置航路点 @1
 | 
			
		||||
@1 display of waypoint coordinates=显示航路点@1坐标
 | 
			
		||||
Change color of waypoint display=改变航路点显示的颜色
 | 
			
		||||
Edit waypoint name=编辑航路点名称
 | 
			
		||||
Waypoint active=航路点已激活
 | 
			
		||||
Waypoint inactive=航路点未激活
 | 
			
		||||
Finish editing=完成编辑
 | 
			
		||||
World position=世界位置
 | 
			
		||||
Name=名称
 | 
			
		||||
HUD text color=HUD文本颜色
 | 
			
		||||
 | 
			
		||||
#new
 | 
			
		||||
 | 
			
		||||
Reset search and display everything=重置搜索并显示所有物品
 | 
			
		||||
							
								
								
									
										78
									
								
								locale/unified_inventory.zh_TW.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,78 @@
 | 
			
		||||
# textdomain: unified_inventory
 | 
			
		||||
# traslation by: IFRFSX(BingFengFSX)
 | 
			
		||||
#Email: IFRFSX@Protonmail.com
 | 
			
		||||
 | 
			
		||||
Crafting=合成
 | 
			
		||||
Mixing=混合
 | 
			
		||||
Cooking=烹飪
 | 
			
		||||
Digging=挖出
 | 
			
		||||
Bags=揹包
 | 
			
		||||
Bag @1=揹包@1
 | 
			
		||||
Small Bag=小揹包
 | 
			
		||||
Medium Bag=中揹包
 | 
			
		||||
Large Bag=大揹包
 | 
			
		||||
 and = 和 
 | 
			
		||||
First page=第一頁
 | 
			
		||||
Back three pages=後退三頁
 | 
			
		||||
Back one page=後退一頁
 | 
			
		||||
Forward one page=前進一頁
 | 
			
		||||
Forward three pages=前進三頁
 | 
			
		||||
Last page=最後一頁
 | 
			
		||||
Search=搜索
 | 
			
		||||
No matching items=沒有匹配物品
 | 
			
		||||
No matches.=沒有匹配
 | 
			
		||||
Page=頁面
 | 
			
		||||
@1 of @2=第@1頁,共@2頁
 | 
			
		||||
Filter=過濾器
 | 
			
		||||
Can use the creative inventory=可以使用創造揹包
 | 
			
		||||
Crafting Grid=合成表
 | 
			
		||||
Crafting Guide=合成指南
 | 
			
		||||
Set home position=設置家的位置
 | 
			
		||||
Home position set to: @1=家的位置設置到: @1
 | 
			
		||||
You don't have the "home" privilege!=你沒有“home”權限!
 | 
			
		||||
Go home=回家
 | 
			
		||||
Set time to day=設置時間到白天
 | 
			
		||||
Time of day set to 6am=時間設置到早晨6點
 | 
			
		||||
You don't have the settime privilege!=你沒有“settime”權限!
 | 
			
		||||
Set time to night=設置時間到晚上
 | 
			
		||||
Time of day set to 9pm=時間設置到晚上9點
 | 
			
		||||
 | 
			
		||||
Inventory cleared!=清空揹包
 | 
			
		||||
Clear inventory=清空揹包
 | 
			
		||||
 | 
			
		||||
Trash:=丟棄:
 | 
			
		||||
Refill:=填滿:
 | 
			
		||||
Recipe @1 of @2=第@1配方,共@2個
 | 
			
		||||
Usage @1 of @2=第@1用法,共@2個
 | 
			
		||||
No recipes=沒有配方
 | 
			
		||||
No usages=沒有用法
 | 
			
		||||
Result=結果
 | 
			
		||||
Ingredient=原料
 | 
			
		||||
Give me:=給予:
 | 
			
		||||
To craft grid:=填充物品到合成表
 | 
			
		||||
All=全部
 | 
			
		||||
White=白
 | 
			
		||||
Yellow=黃
 | 
			
		||||
Red=紅
 | 
			
		||||
Green=綠
 | 
			
		||||
Blue=藍
 | 
			
		||||
Waypoints=航路點
 | 
			
		||||
Select Waypoint #@1=查詢航路點 #@1
 | 
			
		||||
Waypoint @1=航路點 @1
 | 
			
		||||
Set waypoint to current location=將航路點設置到當前位置
 | 
			
		||||
invisible=不可見的
 | 
			
		||||
visible=可見的
 | 
			
		||||
Make waypoint @1=設置航路點 @1
 | 
			
		||||
@1 display of waypoint coordinates=顯示航路點@1座標
 | 
			
		||||
Change color of waypoint display=改變航路點顯示的顏色
 | 
			
		||||
Edit waypoint name=編輯航路點名稱
 | 
			
		||||
Waypoint active=航路點已激活
 | 
			
		||||
Waypoint inactive=航路點未激活
 | 
			
		||||
Finish editing=完成編輯
 | 
			
		||||
World position=世界位置
 | 
			
		||||
Name=名稱
 | 
			
		||||
HUD text color=HUD文本顏色
 | 
			
		||||
 | 
			
		||||
#new
 | 
			
		||||
 | 
			
		||||
Reset search and display everything=重置搜索並顯示所有物品
 | 
			
		||||
							
								
								
									
										409
									
								
								match_craft.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,409 @@
 | 
			
		||||
-- match_craft.lua
 | 
			
		||||
-- Find and automatically move inventory items to the crafting grid
 | 
			
		||||
-- according to the recipe.
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Retrieve items from inventory lists and calculate their total count.
 | 
			
		||||
Return a table of "item name" - "total count" pairs.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	inv: minetest inventory reference
 | 
			
		||||
	lists: names of inventory lists to use
 | 
			
		||||
 | 
			
		||||
Example usage:
 | 
			
		||||
	-- Count items in "main" and "craft" lists of player inventory
 | 
			
		||||
	unified_inventory.count_items(player_inv_ref, {"main", "craft"})
 | 
			
		||||
 | 
			
		||||
Example output:
 | 
			
		||||
	{
 | 
			
		||||
		["default:pine_wood"] = 2,
 | 
			
		||||
		["default:acacia_wood"] = 4,
 | 
			
		||||
		["default:chest"] = 3,
 | 
			
		||||
		["default:axe_diamond"] = 2, -- unstackable item are counted too
 | 
			
		||||
		["wool:white"] = 6
 | 
			
		||||
	}
 | 
			
		||||
]]--
 | 
			
		||||
function unified_inventory.count_items(inv, lists)
 | 
			
		||||
	local counts = {}
 | 
			
		||||
 | 
			
		||||
	for i = 1, #lists do
 | 
			
		||||
		local name = lists[i]
 | 
			
		||||
		local size = inv:get_size(name)
 | 
			
		||||
		local list = inv:get_list(name)
 | 
			
		||||
 | 
			
		||||
		for j = 1, size do
 | 
			
		||||
			local stack = list[j]
 | 
			
		||||
 | 
			
		||||
			if not stack:is_empty() then
 | 
			
		||||
				local item = stack:get_name()
 | 
			
		||||
				local count = stack:get_count()
 | 
			
		||||
 | 
			
		||||
				counts[item] = (counts[item] or 0) + count
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return counts
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Retrieve craft recipe items and their positions in the crafting grid.
 | 
			
		||||
Return a table of "craft item name" - "set of positions" pairs.
 | 
			
		||||
 | 
			
		||||
Note that if craft width is not 3 then positions are recalculated as
 | 
			
		||||
if items were placed on a 3x3 grid. Also note that craft can contain
 | 
			
		||||
groups of items with "group:" prefix.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	craft: minetest craft recipe
 | 
			
		||||
 | 
			
		||||
Example output:
 | 
			
		||||
	-- Bed recipe
 | 
			
		||||
	{
 | 
			
		||||
		["wool:white"] = {[1] = true, [2] = true, [3] = true}
 | 
			
		||||
		["group:wood"] = {[4] = true, [5] = true, [6] = true}
 | 
			
		||||
	}
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.count_craft_positions(craft)
 | 
			
		||||
	local positions = {}
 | 
			
		||||
	local craft_items = craft.items
 | 
			
		||||
	local craft_type = unified_inventory.registered_craft_types[craft.type]
 | 
			
		||||
	                   or unified_inventory.craft_type_defaults(craft.type, {})
 | 
			
		||||
	local display_width = craft_type.dynamic_display_size
 | 
			
		||||
	                      and craft_type.dynamic_display_size(craft).width
 | 
			
		||||
	                      or craft_type.width
 | 
			
		||||
	local craft_width = craft_type.get_shaped_craft_width
 | 
			
		||||
	                    and craft_type.get_shaped_craft_width(craft)
 | 
			
		||||
	                    or display_width
 | 
			
		||||
	local i = 0
 | 
			
		||||
 | 
			
		||||
	for y = 1, 3 do
 | 
			
		||||
		for x = 1, craft_width do
 | 
			
		||||
			i = i + 1
 | 
			
		||||
			local item = craft_items[i]
 | 
			
		||||
 | 
			
		||||
			if item ~= nil then
 | 
			
		||||
				local pos = 3 * (y - 1) + x
 | 
			
		||||
				local set = positions[item]
 | 
			
		||||
 | 
			
		||||
				if set ~= nil then
 | 
			
		||||
					set[pos] = true
 | 
			
		||||
				else
 | 
			
		||||
					positions[item] = {[pos] = true}
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return positions
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
For every craft item find all matching inventory items.
 | 
			
		||||
- If craft item is a group then find all inventory items that matches
 | 
			
		||||
  this group.
 | 
			
		||||
- If craft item is not a group (regular item) then find only this item.
 | 
			
		||||
 | 
			
		||||
If inventory doesn't contain needed item then found set is empty for
 | 
			
		||||
this item.
 | 
			
		||||
 | 
			
		||||
Return a table of "craft item name" - "set of matching inventory items"
 | 
			
		||||
pairs.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	inv_items: table with items names as keys
 | 
			
		||||
	craft_items: table with items names or groups as keys
 | 
			
		||||
 | 
			
		||||
Example output:
 | 
			
		||||
	{
 | 
			
		||||
		["group:wood"] = {
 | 
			
		||||
			["default:pine_wood"] = true,
 | 
			
		||||
			["default:acacia_wood"] = true
 | 
			
		||||
		},
 | 
			
		||||
		["wool:white"] = {
 | 
			
		||||
			["wool:white"] = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.find_usable_items(inv_items, craft_items)
 | 
			
		||||
	local get_group = minetest.get_item_group
 | 
			
		||||
	local result = {}
 | 
			
		||||
 | 
			
		||||
	for craft_item in pairs(craft_items) do
 | 
			
		||||
		local group = craft_item:match("^group:(.+)")
 | 
			
		||||
		local found = {}
 | 
			
		||||
 | 
			
		||||
		if group ~= nil then
 | 
			
		||||
			for inv_item in pairs(inv_items) do
 | 
			
		||||
				if get_group(inv_item, group) > 0 then
 | 
			
		||||
					found[inv_item] = true
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			if inv_items[craft_item] ~= nil then
 | 
			
		||||
				found[craft_item] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		result[craft_item] = found
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return result
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Match inventory items with craft grid positions.
 | 
			
		||||
For every position select the matching inventory item with maximum
 | 
			
		||||
(total_count / (times_matched + 1)) value.
 | 
			
		||||
 | 
			
		||||
If for some position matching item cannot be found or match count is 0
 | 
			
		||||
then return nil.
 | 
			
		||||
 | 
			
		||||
Return a table of "matched item name" - "set of craft positions" pairs
 | 
			
		||||
and overall match count.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	inv_counts: table of inventory items counts from "count_items"
 | 
			
		||||
	craft_positions: table of craft positions from "count_craft_positions"
 | 
			
		||||
 | 
			
		||||
Example output:
 | 
			
		||||
	match_table = {
 | 
			
		||||
		["wool:white"] = {[1] = true, [2] = true, [3] = true}
 | 
			
		||||
		["default:acacia_wood"] = {[4] = true, [6] = true}
 | 
			
		||||
		["default:pine_wood"] = {[5] = true}
 | 
			
		||||
	}
 | 
			
		||||
	match_count = 2
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.match_items(inv_counts, craft_positions)
 | 
			
		||||
	local usable = unified_inventory.find_usable_items(inv_counts, craft_positions)
 | 
			
		||||
	local match_table = {}
 | 
			
		||||
	local match_count
 | 
			
		||||
	local matches = {}
 | 
			
		||||
 | 
			
		||||
	for craft_item, pos_set in pairs(craft_positions) do
 | 
			
		||||
		local use_set = usable[craft_item]
 | 
			
		||||
 | 
			
		||||
		for pos in pairs(pos_set) do
 | 
			
		||||
			local pos_item
 | 
			
		||||
			local pos_count
 | 
			
		||||
 | 
			
		||||
			for use_item in pairs(use_set) do
 | 
			
		||||
				local count = inv_counts[use_item]
 | 
			
		||||
				local times_matched = matches[use_item] or 0
 | 
			
		||||
				local new_pos_count = math.floor(count / (times_matched + 1))
 | 
			
		||||
 | 
			
		||||
				if pos_count == nil or pos_count < new_pos_count then
 | 
			
		||||
					pos_item = use_item
 | 
			
		||||
					pos_count = new_pos_count
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			if pos_item == nil or pos_count == 0 then
 | 
			
		||||
				return nil
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			local set = match_table[pos_item]
 | 
			
		||||
 | 
			
		||||
			if set ~= nil then
 | 
			
		||||
				set[pos] = true
 | 
			
		||||
			else
 | 
			
		||||
				match_table[pos_item] = {[pos] = true}
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			matches[pos_item] = (matches[pos_item] or 0) + 1
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	for match_item, times_matched in pairs(matches) do
 | 
			
		||||
		local count = inv_counts[match_item]
 | 
			
		||||
		local item_count = math.floor(count / times_matched)
 | 
			
		||||
 | 
			
		||||
		if match_count == nil or item_count < match_count then
 | 
			
		||||
			match_count = item_count
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return match_table, match_count
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Remove item from inventory lists.
 | 
			
		||||
Return stack of actually removed items.
 | 
			
		||||
 | 
			
		||||
This function replicates the inv:remove_item function but can accept
 | 
			
		||||
multiple lists.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	inv: minetest inventory reference
 | 
			
		||||
	lists: names of inventory lists
 | 
			
		||||
	stack: minetest item stack
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.remove_item(inv, lists, stack)
 | 
			
		||||
	local removed = ItemStack(nil)
 | 
			
		||||
	local leftover = ItemStack(stack)
 | 
			
		||||
 | 
			
		||||
	for i = 1, #lists do
 | 
			
		||||
		if leftover:is_empty() then
 | 
			
		||||
			break
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local cur_removed = inv:remove_item(lists[i], leftover)
 | 
			
		||||
		removed:add_item(cur_removed)
 | 
			
		||||
		leftover:take_item(cur_removed:get_count())
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return removed
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Add item to inventory lists.
 | 
			
		||||
Return leftover stack.
 | 
			
		||||
 | 
			
		||||
This function replicates the inv:add_item function but can accept
 | 
			
		||||
multiple lists.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	inv: minetest inventory reference
 | 
			
		||||
	lists: names of inventory lists
 | 
			
		||||
	stack: minetest item stack
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.add_item(inv, lists, stack)
 | 
			
		||||
	local leftover = ItemStack(stack)
 | 
			
		||||
 | 
			
		||||
	for i = 1, #lists do
 | 
			
		||||
		if leftover:is_empty() then
 | 
			
		||||
			break
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		leftover = inv:add_item(lists[i], leftover)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return leftover
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Move items from source list to destination list if possible.
 | 
			
		||||
Skip positions specified in exclude set.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	inv: minetest inventory reference
 | 
			
		||||
	src_list: name of source list
 | 
			
		||||
	dst_list: name of destination list
 | 
			
		||||
	exclude: set of positions to skip
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.swap_items(inv, src_list, dst_list, exclude)
 | 
			
		||||
	local size = inv:get_size(src_list)
 | 
			
		||||
	local empty = ItemStack(nil)
 | 
			
		||||
 | 
			
		||||
	for i = 1, size do
 | 
			
		||||
		if exclude == nil or exclude[i] == nil then
 | 
			
		||||
			local stack = inv:get_stack(src_list, i)
 | 
			
		||||
 | 
			
		||||
			if not stack:is_empty() then
 | 
			
		||||
				inv:set_stack(src_list, i, empty)
 | 
			
		||||
				local leftover = inv:add_item(dst_list, stack)
 | 
			
		||||
 | 
			
		||||
				if not leftover:is_empty() then
 | 
			
		||||
					inv:set_stack(src_list, i, leftover)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Move matched items to the destination list.
 | 
			
		||||
 | 
			
		||||
If destination list position is already occupied with some other item
 | 
			
		||||
then function tries to (in that order):
 | 
			
		||||
1. Move it to the source list
 | 
			
		||||
2. Move it to some other unused position in destination list itself
 | 
			
		||||
3. Drop it to the ground if nothing else is possible.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	player: minetest player object
 | 
			
		||||
	src_list: name of source list
 | 
			
		||||
	dst_list: name of destination list
 | 
			
		||||
	match_table: table of matched items
 | 
			
		||||
	amount: amount of items per every position
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.move_match(player, src_list, dst_list, match_table, amount)
 | 
			
		||||
	local inv = player:get_inventory()
 | 
			
		||||
	local item_drop = minetest.item_drop
 | 
			
		||||
	local src_dst_list = {src_list, dst_list}
 | 
			
		||||
	local dst_src_list = {dst_list, src_list}
 | 
			
		||||
 | 
			
		||||
	local needed = {}
 | 
			
		||||
	local moved = {}
 | 
			
		||||
 | 
			
		||||
	-- Remove stacks needed for craft
 | 
			
		||||
	for item, pos_set in pairs(match_table) do
 | 
			
		||||
		local stack = ItemStack(item)
 | 
			
		||||
		local stack_max = stack:get_stack_max()
 | 
			
		||||
		local bounded_amount = math.min(stack_max, amount)
 | 
			
		||||
		stack:set_count(bounded_amount)
 | 
			
		||||
 | 
			
		||||
		for pos in pairs(pos_set) do
 | 
			
		||||
			needed[pos] = unified_inventory.remove_item(inv, dst_src_list, stack)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Add already removed stacks
 | 
			
		||||
	for pos, stack in pairs(needed) do
 | 
			
		||||
		local occupied = inv:get_stack(dst_list, pos)
 | 
			
		||||
		inv:set_stack(dst_list, pos, stack)
 | 
			
		||||
 | 
			
		||||
		if not occupied:is_empty() then
 | 
			
		||||
			local leftover = unified_inventory.add_item(inv, src_dst_list, occupied)
 | 
			
		||||
 | 
			
		||||
			if not leftover:is_empty() then
 | 
			
		||||
				inv:set_stack(dst_list, pos, leftover)
 | 
			
		||||
				local oversize = unified_inventory.add_item(inv, src_dst_list, stack)
 | 
			
		||||
 | 
			
		||||
				if not oversize:is_empty() then
 | 
			
		||||
					item_drop(oversize, player, player:get_pos())
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		moved[pos] = true
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Swap items from unused positions to src (moved positions excluded)
 | 
			
		||||
	unified_inventory.swap_items(inv, dst_list, src_list, moved)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Find craft match and move matched items to the destination list.
 | 
			
		||||
 | 
			
		||||
If match cannot be found or match count is smaller than the desired
 | 
			
		||||
amount then do nothing.
 | 
			
		||||
 | 
			
		||||
If amount passed is -1 then amount is defined by match count itself.
 | 
			
		||||
This is used to indicate "craft All" case.
 | 
			
		||||
 | 
			
		||||
Arguments:
 | 
			
		||||
	player: minetest player object
 | 
			
		||||
	src_list: name of source list
 | 
			
		||||
	dst_list: name of destination list
 | 
			
		||||
	craft: minetest craft recipe
 | 
			
		||||
	amount: desired amount of output items
 | 
			
		||||
--]]
 | 
			
		||||
function unified_inventory.craftguide_match_craft(player, src_list, dst_list, craft, amount)
 | 
			
		||||
	local inv = player:get_inventory()
 | 
			
		||||
	local src_dst_list = {src_list, dst_list}
 | 
			
		||||
 | 
			
		||||
	local counts = unified_inventory.count_items(inv, src_dst_list)
 | 
			
		||||
	local positions = unified_inventory.count_craft_positions(craft)
 | 
			
		||||
	local match_table, match_count = unified_inventory.match_items(counts, positions)
 | 
			
		||||
 | 
			
		||||
	if match_table == nil or match_count < amount then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if amount == -1 then
 | 
			
		||||
		amount = match_count
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	unified_inventory.move_match(player, src_list, dst_list, match_table, amount)
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										4
									
								
								mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,4 @@
 | 
			
		||||
name = unified_inventory
 | 
			
		||||
depends = default
 | 
			
		||||
optional_depends = creative, sfinv, datastorage, farming
 | 
			
		||||
description = Unified Inventory replaces the default survival and creative inventory. It adds a nicer interface and a number of features, such as a crafting guide.
 | 
			
		||||
							
								
								
									
										499
									
								
								register.lua
									
									
									
									
									
								
							
							
						
						@@ -1,9 +1,18 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local NS = function(s) return s end
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
 | 
			
		||||
minetest.register_privilege("creative", {
 | 
			
		||||
	description = "Can use the creative inventory",
 | 
			
		||||
	description = S("Can use the creative inventory"),
 | 
			
		||||
	give_to_singleplayer = false,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_privilege("ui_full", {
 | 
			
		||||
	description = S("Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally"),
 | 
			
		||||
	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
 | 
			
		||||
@@ -23,43 +32,20 @@ trash:set_size("main", 1)
 | 
			
		||||
unified_inventory.register_button("craft", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_craft_icon.png",
 | 
			
		||||
	tooltip = S("Crafting Grid")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("craftguide", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_craftguide_icon.png",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("home_gui_set", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_sethome_icon.png",
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		unified_inventory.set_home(player, player:getpos())
 | 
			
		||||
		local home = unified_inventory.home_pos[player_name]
 | 
			
		||||
		if home ~= nil then
 | 
			
		||||
			minetest.sound_play("dingdong",
 | 
			
		||||
					{to_player=player_name, gain = 1.0})
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					"Home position set to: "
 | 
			
		||||
					..minetest.pos_to_string(home))
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("home_gui_go", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_gohome_icon.png",
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		minetest.sound_play("teleport",
 | 
			
		||||
				{to_player=player:get_player_name(), gain = 1.0})
 | 
			
		||||
		unified_inventory.go_home(player)
 | 
			
		||||
	end,
 | 
			
		||||
	tooltip = S("Crafting Guide")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("misc_set_day", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_sun_icon.png",
 | 
			
		||||
	tooltip = S("Set time to day"),
 | 
			
		||||
	hide_lite=true,
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {settime=true}) then
 | 
			
		||||
@@ -67,18 +53,23 @@ unified_inventory.register_button("misc_set_day", {
 | 
			
		||||
					{to_player=player_name, gain = 1.0})
 | 
			
		||||
			minetest.set_timeofday((6000 % 24000) / 24000)
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					"Time of day set to 6am")
 | 
			
		||||
				S("Time of day set to 6am"))
 | 
			
		||||
		else
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					"You don't have the"
 | 
			
		||||
					.." settime priviledge!")
 | 
			
		||||
				S("You don't have the settime privilege!"))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
		return minetest.check_player_privs(player:get_player_name(), {settime=true})
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("misc_set_night", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_moon_icon.png",
 | 
			
		||||
	tooltip = S("Set time to night"),
 | 
			
		||||
	hide_lite=true,
 | 
			
		||||
	action = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		if minetest.check_player_privs(player_name, {settime=true}) then
 | 
			
		||||
@@ -86,220 +77,364 @@ unified_inventory.register_button("misc_set_night", {
 | 
			
		||||
					{to_player=player_name, gain = 1.0})
 | 
			
		||||
			minetest.set_timeofday((21000 % 24000) / 24000)
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					"Time of day set to 9pm")
 | 
			
		||||
					S("Time of day set to 9pm"))
 | 
			
		||||
		else
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					"You don't have the"
 | 
			
		||||
					.." settime priviledge!")
 | 
			
		||||
					S("You don't have the settime privilege!"))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
		return minetest.check_player_privs(player:get_player_name(), {settime=true})
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.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
 | 
			
		||||
			minetest.chat_send_player(player_name,
 | 
			
		||||
					"This button has been disabled outside"
 | 
			
		||||
					S("This button has been disabled outside"
 | 
			
		||||
					.." of creative mode to prevent"
 | 
			
		||||
					.." accidental inventory trashing."
 | 
			
		||||
					.." Use the trash slot instead.")
 | 
			
		||||
					.."\nUse the trash slot instead."))
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		player:get_inventory():set_list("main", {})
 | 
			
		||||
		minetest.chat_send_player(player_name, 'Inventory Cleared!')
 | 
			
		||||
		minetest.chat_send_player(player_name, S('Inventory cleared!'))
 | 
			
		||||
		minetest.sound_play("trash_all",
 | 
			
		||||
				{to_player=player_name, gain = 1.0})
 | 
			
		||||
	end,
 | 
			
		||||
	condition = function(player)
 | 
			
		||||
		return unified_inventory.is_creative(player:get_player_name())
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("craft", {
 | 
			
		||||
	get_formspec = function(player, formspec)
 | 
			
		||||
	get_formspec = function(player, perplayer_formspec)
 | 
			
		||||
 | 
			
		||||
		local formspecy = perplayer_formspec.formspec_y
 | 
			
		||||
		local formheadery =  perplayer_formspec.form_header_y
 | 
			
		||||
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
		local formspec = "background[0,1;8,3;ui_crafting_form.png]"
 | 
			
		||||
		formspec = formspec.."background[0,4.5;8,4;ui_main_inventory.png]"
 | 
			
		||||
		formspec = formspec.."label[0,0;Crafting]"
 | 
			
		||||
		local formspec = "background[2,"..formspecy..";6,3;ui_crafting_form.png]"
 | 
			
		||||
		formspec = formspec.."background[0,"..(formspecy + 3.5)..";8,4;ui_main_inventory.png]"
 | 
			
		||||
		formspec = formspec.."label[0,"..formheadery..";" ..F(S("Crafting")).."]"
 | 
			
		||||
		formspec = formspec.."listcolors[#00000000;#00000000]"
 | 
			
		||||
		formspec = formspec.."list[current_player;craftpreview;6,1;1,1;]"
 | 
			
		||||
		formspec = formspec.."list[current_player;craft;2,1;3,3;]"
 | 
			
		||||
		formspec = formspec.."label[7,2.5;Trash:]"
 | 
			
		||||
		formspec = formspec.."list[detached:trash;main;7,3;1,1;]"
 | 
			
		||||
		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;]"
 | 
			
		||||
		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,2.5;Refill:]"
 | 
			
		||||
			formspec = formspec.."list[detached:"..player_name.."refill;main;0,3;1,1;]"
 | 
			
		||||
			formspec = formspec.."label[0,"..(formspecy + 1.5)..";" .. F(S("Refill:")) .. "]"
 | 
			
		||||
			formspec = formspec.."list[detached:"..F(player_name).."refill;main;0,"..(formspecy +2)..";1,1;]"
 | 
			
		||||
		end
 | 
			
		||||
		return {formspec=formspec}
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-- stack_image_button(): generate a form button displaying a stack of items
 | 
			
		||||
--
 | 
			
		||||
-- The specified item may be a group.  In that case, the group will be
 | 
			
		||||
-- represented by some item in the group, along with a flag indicating
 | 
			
		||||
-- that it's a group.  If the group contains only one item, it will be
 | 
			
		||||
-- treated as if that item had been specified directly.
 | 
			
		||||
 | 
			
		||||
local function stack_image_button(x, y, w, h, buttonname_prefix, item)
 | 
			
		||||
	local name = item:get_name()
 | 
			
		||||
	local count = item:get_count()
 | 
			
		||||
	local show_is_group = false
 | 
			
		||||
	local displayitem = name.." "..count
 | 
			
		||||
	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)
 | 
			
		||||
		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 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 grouptip
 | 
			
		||||
		if andcount == 1 then
 | 
			
		||||
			grouptip = S("Any item belonging to the @1 group", groupstring)
 | 
			
		||||
		elseif andcount > 1 then
 | 
			
		||||
			grouptip = S("Any item belonging to the groups @1", groupstring)
 | 
			
		||||
		end
 | 
			
		||||
		grouptip = F(grouptip)
 | 
			
		||||
		if andcount >= 1 then
 | 
			
		||||
			button = button  .. string.format("tooltip[%s;%s]", buttonname, grouptip)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return button
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local recipe_text = {
 | 
			
		||||
	recipe = NS("Recipe @1 of @2"),
 | 
			
		||||
	usage = NS("Usage @1 of @2"),
 | 
			
		||||
}
 | 
			
		||||
local no_recipe_text = {
 | 
			
		||||
	recipe = S("No recipes"),
 | 
			
		||||
	usage = S("No usages"),
 | 
			
		||||
}
 | 
			
		||||
local role_text = {
 | 
			
		||||
	recipe = S("Result"),
 | 
			
		||||
	usage = S("Ingredient"),
 | 
			
		||||
}
 | 
			
		||||
local next_alt_text = {
 | 
			
		||||
	recipe = S("Show next recipe"),
 | 
			
		||||
	usage = S("Show next usage"),
 | 
			
		||||
}
 | 
			
		||||
local prev_alt_text = {
 | 
			
		||||
	recipe = S("Show previous recipe"),
 | 
			
		||||
	usage = S("Show previous usage"),
 | 
			
		||||
}
 | 
			
		||||
local other_dir = {
 | 
			
		||||
	recipe = "usage",
 | 
			
		||||
	usage = "recipe",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("craftguide", {
 | 
			
		||||
	get_formspec = function(player)
 | 
			
		||||
	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 player_name = player:get_player_name()
 | 
			
		||||
		local formspec = "background[0,1;8,3;ui_craftguide_form.png]"
 | 
			
		||||
		formspec = formspec.."background[0,4.5;8,4;ui_main_inventory.png]"
 | 
			
		||||
		formspec = formspec.."label[0,0;Crafting Guide]"
 | 
			
		||||
		formspec = formspec.."listcolors[#00000000;#00000000]"
 | 
			
		||||
		formspec = formspec.."list[detached:"..player_name.."craftrecipe;output;6,1;1,1;]"
 | 
			
		||||
		formspec = formspec.."label[6,3.35;Method:]"
 | 
			
		||||
		local player_privs = minetest.get_player_privs(player_name)
 | 
			
		||||
		local fs = {
 | 
			
		||||
			"background[0,"..(formspecy + 3.5)..";8,4;ui_main_inventory.png]",
 | 
			
		||||
			"label[0,"..formheadery..";" .. F(S("Crafting Guide")) .. "]",
 | 
			
		||||
			"listcolors[#00000000;#00000000]"
 | 
			
		||||
		}
 | 
			
		||||
		local item_name = unified_inventory.current_item[player_name]
 | 
			
		||||
		local craft = nil
 | 
			
		||||
		if item_name then
 | 
			
		||||
			formspec = formspec.."textarea[0.3,0.6;10,1;;Result: "..item_name..";]"
 | 
			
		||||
			local alternates = 0
 | 
			
		||||
			local alternate = unified_inventory.alternate[player_name]
 | 
			
		||||
			local crafts = unified_inventory.crafts_table[item_name]
 | 
			
		||||
			if crafts ~= nil and #crafts > 0 then
 | 
			
		||||
				alternates = #crafts
 | 
			
		||||
				craft = crafts[alternate]
 | 
			
		||||
				local method = craft.type
 | 
			
		||||
				local allow_auto_craft = ((method == "normal") or (method == "shapeless"))
 | 
			
		||||
				if craft.type == "normal" then
 | 
			
		||||
					method = "crafting"
 | 
			
		||||
				elseif craft.type == "shapeless" then
 | 
			
		||||
					method = "shapeless crafting"
 | 
			
		||||
				elseif craft.type == "alloy" then
 | 
			
		||||
					method = "alloy cooking"
 | 
			
		||||
				end
 | 
			
		||||
				formspec = formspec.."label[6,3.75;"..method.."]"
 | 
			
		||||
				if allow_auto_craft then
 | 
			
		||||
					formspec = formspec.."label[6,1.95;Copy to craft grid:]"
 | 
			
		||||
							.."button[6,2.5;0.6,0.5;craftguide_craft_1;1]"
 | 
			
		||||
							.."button[6.6,2.5;0.6,0.5;craftguide_craft_10;10]"
 | 
			
		||||
							.."button[7.2,2.5;0.6,0.5;craftguide_craft_max;All]"
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			if alternates > 1 then
 | 
			
		||||
				formspec = formspec.."label[0,2.6;Recipe "
 | 
			
		||||
						..tostring(alternate).." of "
 | 
			
		||||
						..tostring(alternates).."]"
 | 
			
		||||
						.."button[0,3.15;2,1;alternate;Alternate]"
 | 
			
		||||
			end
 | 
			
		||||
		if not item_name then
 | 
			
		||||
			return { formspec = table.concat(fs) }
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local craftinv = minetest.get_inventory({
 | 
			
		||||
			type = "detached",
 | 
			
		||||
			name = player_name.."craftrecipe"
 | 
			
		||||
		})
 | 
			
		||||
		local item_name_shown
 | 
			
		||||
		if minetest.registered_items[item_name]
 | 
			
		||||
				and minetest.registered_items[item_name].description then
 | 
			
		||||
			item_name_shown = S("@1 (@2)",
 | 
			
		||||
				minetest.registered_items[item_name].description, item_name)
 | 
			
		||||
		else
 | 
			
		||||
			item_name_shown = item_name
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		-- fake buttons just to make 3x3 grid
 | 
			
		||||
		for y = 1, 3 do
 | 
			
		||||
		for x = 1, 3 do
 | 
			
		||||
			formspec = formspec.."image_button["
 | 
			
		||||
				..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;ui_blank_image.png;;]"
 | 
			
		||||
		end
 | 
			
		||||
		local dir = unified_inventory.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 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)
 | 
			
		||||
 | 
			
		||||
		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))
 | 
			
		||||
 | 
			
		||||
		if not craft then
 | 
			
		||||
			craftinv:set_stack("output", 1, nil)
 | 
			
		||||
			return {formspec=formspec}
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		craftinv:set_stack("output", 1, craft.output)
 | 
			
		||||
 | 
			
		||||
		local width = craft.width
 | 
			
		||||
		if width == 0 then
 | 
			
		||||
			-- Shapeless recipe
 | 
			
		||||
			width = 3
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local i = 1
 | 
			
		||||
		for y = 1, 3 do
 | 
			
		||||
		for x = 1, width do
 | 
			
		||||
			local item = craft.items[i]
 | 
			
		||||
			if item then
 | 
			
		||||
				if string.sub(item, 1, 6) == "group:" then
 | 
			
		||||
					local group = string.sub(item, 7)
 | 
			
		||||
					formspec = formspec.."image_button["
 | 
			
		||||
						..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;"
 | 
			
		||||
						.."ui_group.png;"
 | 
			
		||||
						.."item_group_"..minetest.formspec_escape(group)..";"
 | 
			
		||||
						..minetest.formspec_escape(group).."]"
 | 
			
		||||
				else
 | 
			
		||||
					formspec = formspec.."item_image_button["
 | 
			
		||||
						..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;"
 | 
			
		||||
						..minetest.formspec_escape(item)..";"
 | 
			
		||||
						.."item_button_"
 | 
			
		||||
						..minetest.formspec_escape(item)..";]"
 | 
			
		||||
				end
 | 
			
		||||
			-- 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,
 | 
			
		||||
				"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]"
 | 
			
		||||
			end
 | 
			
		||||
			return { formspec = table.concat(fs) }
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local craft_type = unified_inventory.registered_craft_types[craft.type] or
 | 
			
		||||
				unified_inventory.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)
 | 
			
		||||
		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))
 | 
			
		||||
 | 
			
		||||
		local display_size = craft_type.dynamic_display_size
 | 
			
		||||
				and craft_type.dynamic_display_size(craft)
 | 
			
		||||
				or { width = craft_type.width, height = craft_type.height }
 | 
			
		||||
		local craft_width = craft_type.get_shaped_craft_width
 | 
			
		||||
				and craft_type.get_shaped_craft_width(craft)
 | 
			
		||||
				or display_size.width
 | 
			
		||||
 | 
			
		||||
		-- This keeps recipes aligned to the right,
 | 
			
		||||
		-- so that they're close to the arrow.
 | 
			
		||||
		local xoffset = 5.5
 | 
			
		||||
		-- 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
 | 
			
		||||
		local mini_craft_size = 6
 | 
			
		||||
		if display_size.width >= mini_craft_size then
 | 
			
		||||
			od = math.max(1, display_size.width - 2)
 | 
			
		||||
			xoffset = xoffset - 0.1
 | 
			
		||||
		end
 | 
			
		||||
		-- 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
 | 
			
		||||
		end
 | 
			
		||||
		if (bsize_h > 0.35 and display_size.width) then
 | 
			
		||||
		for y = 1, display_size.height do
 | 
			
		||||
		for x = 1, display_size.width do
 | 
			
		||||
			local item
 | 
			
		||||
			if craft and x <= craft_width then
 | 
			
		||||
				item = craft.items[(y-1) * craft_width + x]
 | 
			
		||||
			end
 | 
			
		||||
			-- 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
 | 
			
		||||
			if item then
 | 
			
		||||
				fs[#fs + 1] = stack_image_button(
 | 
			
		||||
						xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h,
 | 
			
		||||
						"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)
 | 
			
		||||
			end
 | 
			
		||||
			i = i + 1
 | 
			
		||||
		end
 | 
			
		||||
		end
 | 
			
		||||
		return {formspec=formspec}
 | 
			
		||||
		else
 | 
			
		||||
			-- Error
 | 
			
		||||
			fs[#fs + 1] = string.format("label[2,%f;%s]",
 | 
			
		||||
				formspecy, F(S("This recipe is too@nlarge to be displayed.")))
 | 
			
		||||
		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")) .. "]"
 | 
			
		||||
		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]"
 | 
			
		||||
		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]) .. "]"
 | 
			
		||||
		end
 | 
			
		||||
		return { formspec = table.concat(fs) }
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
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
 | 
			
		||||
		minetest.log("action", "[unified_inventory] Denied give action to player " ..
 | 
			
		||||
			player_name)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local amount
 | 
			
		||||
	for k, v in pairs(fields) do
 | 
			
		||||
		amount = k:match("craftguide_craft_(.*)")
 | 
			
		||||
		amount = k:match("craftguide_giveme_(.*)")
 | 
			
		||||
		if amount then break end
 | 
			
		||||
	end
 | 
			
		||||
	if not amount then return end
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local recipe_inv = minetest.get_inventory({
 | 
			
		||||
		type="detached",
 | 
			
		||||
		name=player_name.."craftrecipe",
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	amount = tonumber(amount) or 0
 | 
			
		||||
	if amount == 0 then return end
 | 
			
		||||
 | 
			
		||||
	local output = unified_inventory.current_item[player_name]
 | 
			
		||||
	if (not output) or (output == "") then return end
 | 
			
		||||
 | 
			
		||||
	local player_inv = player:get_inventory()
 | 
			
		||||
 | 
			
		||||
	local crafts = unified_inventory.crafts_table[output]
 | 
			
		||||
	if (not crafts) or (#crafts == 0) then return end
 | 
			
		||||
	player_inv:add_item("main", {name = output, count = amount})
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function craftguide_craft(player, formname, fields)
 | 
			
		||||
	local amount
 | 
			
		||||
	for k, v in pairs(fields) do
 | 
			
		||||
		amount = k:match("craftguide_craft_(.*)")
 | 
			
		||||
		if amount then break end
 | 
			
		||||
	end
 | 
			
		||||
	if not amount then return end
 | 
			
		||||
 | 
			
		||||
	amount = tonumber(amount) or -1 -- fallback for "all"
 | 
			
		||||
	if amount == 0 or amount < -1 or amount > 99 then return end
 | 
			
		||||
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
	local output = unified_inventory.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 {}
 | 
			
		||||
	if #crafts == 0 then return end
 | 
			
		||||
 | 
			
		||||
	local alternate = unified_inventory.alternate[player_name]
 | 
			
		||||
 | 
			
		||||
	local craft = crafts[alternate]
 | 
			
		||||
	if craft.width > 3 then return end
 | 
			
		||||
 | 
			
		||||
	local needed = craft.items
 | 
			
		||||
 | 
			
		||||
	local craft_list = player_inv:get_list("craft")
 | 
			
		||||
 | 
			
		||||
	local width = craft.width
 | 
			
		||||
	if width == 0 then
 | 
			
		||||
		-- Shapeless recipe
 | 
			
		||||
		width = 3
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if amount == "max" then
 | 
			
		||||
		amount = 99 -- Arbitrary; need better way to do this.
 | 
			
		||||
	else
 | 
			
		||||
		amount = tonumber(amount)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	for iter = 1, amount do
 | 
			
		||||
		local index = 1
 | 
			
		||||
		for y = 1, 3 do
 | 
			
		||||
			for x = 1, width do
 | 
			
		||||
				local needed_item = needed[index]
 | 
			
		||||
				if needed_item then
 | 
			
		||||
					local craft_index = ((y - 1) * 3) + x
 | 
			
		||||
					local craft_item = craft_list[craft_index]
 | 
			
		||||
					if (not craft_item) or (craft_item:is_empty()) or (craft_item:get_name() == needed_item) then
 | 
			
		||||
						itemname = craft_item and craft_item:get_name() or needed_item
 | 
			
		||||
						local needed_stack = ItemStack(needed_item)
 | 
			
		||||
						if player_inv:contains_item("main", needed_stack) then
 | 
			
		||||
							local count = (craft_item and craft_item:get_count() or 0) + 1
 | 
			
		||||
							if count <= needed_stack:get_definition().stack_max then
 | 
			
		||||
								local stack = ItemStack({name=needed_item, count=count})
 | 
			
		||||
								craft_list[craft_index] = stack
 | 
			
		||||
								player_inv:remove_item("main", needed_stack)
 | 
			
		||||
							end
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				index = index + 1
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	player_inv:set_list("craft", craft_list)
 | 
			
		||||
	unified_inventory.craftguide_match_craft(player, "main", "craft", craft, amount)
 | 
			
		||||
 | 
			
		||||
	unified_inventory.set_inventory_formspec(player, "craft")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
	if formname ~= "" then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	for k, v in pairs(fields) do
 | 
			
		||||
		if k:match("craftguide_craft_") then
 | 
			
		||||
			craftguide_craft(player, formname, fields)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if k:match("craftguide_giveme_") then
 | 
			
		||||
			craftguide_giveme(player, formname, fields)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								screenshot.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 134 KiB  | 
							
								
								
									
										11
									
								
								settingtypes.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,11 @@
 | 
			
		||||
#Enabling lite mode enables a smaller and simpler version of the Unified
 | 
			
		||||
#Inventory, optimized for small displays.
 | 
			
		||||
unified_inventory_lite (Lite mode) bool false
 | 
			
		||||
 | 
			
		||||
#If enabled, bags will be made available which can be used to extend
 | 
			
		||||
#inventory storage size.
 | 
			
		||||
unified_inventory_bags (Enable bags) bool true
 | 
			
		||||
 | 
			
		||||
#If enabled, the trash slot can be used by those without both creative
 | 
			
		||||
#and the give privilege.
 | 
			
		||||
unified_inventory_trash (Enable trash) bool true
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 12 KiB  | 
| 
		 Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 11 KiB  | 
| 
		 Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 9.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_1_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 456 B  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_2_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 961 B  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_3_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_4_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 658 B  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_5_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 928 B  | 
| 
		 Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 12 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 7.9 KiB  | 
| 
		 Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 5.9 KiB  | 
| 
		 Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 7.0 KiB  | 
| 
		 Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_bags_trash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 71 B  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_blue_icon_background.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_circular_arrows_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.6 KiB  | 
| 
		 Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 15 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_craftgrid_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 483 B  | 
| 
		 Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 962 B  | 
| 
		 Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 15 KiB  | 
| 
		 Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 2.3 KiB  | 
| 
		 Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 9.0 KiB  | 
| 
		 Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 9.1 KiB  | 
| 
		 Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 1.6 KiB  | 
| 
		 Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 15 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_green_icon_background.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.6 KiB  | 
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 22 KiB  | 
| 
		 Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 6.3 KiB  | 
| 
		 Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 4.0 KiB  | 
| 
		 Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 5.2 KiB  | 
| 
		 Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_no.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.2 KiB  | 
| 
		 Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_ok_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.6 KiB  | 
| 
		 Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_pencil_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_red_icon_background.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_reset_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 10 KiB  | 
| 
		 Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 6.3 KiB  | 
| 
		 Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 10 KiB  | 
| 
		 Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_single_slot.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 629 B  | 
| 
		 Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 8.1 KiB  | 
| 
		 Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 8.0 KiB  | 
| 
		 Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 18 KiB  | 
| 
		 Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_waypoint_set_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.7 KiB  | 
| 
		 Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 15 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_xyz_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_xyz_off_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/ui_xyz_on_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.1 KiB  | 
							
								
								
									
										247
									
								
								waypoints.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,247 @@
 | 
			
		||||
local S = minetest.get_translator("unified_inventory")
 | 
			
		||||
local F = minetest.formspec_escape
 | 
			
		||||
 | 
			
		||||
local hud_colors = {
 | 
			
		||||
	{"#FFFFFF", 0xFFFFFF, S("White")},
 | 
			
		||||
	{"#DBBB00", 0xf1d32c, S("Yellow")},
 | 
			
		||||
	{"#DD0000", 0xDD0000, S("Red")},
 | 
			
		||||
	{"#2cf136", 0x2cf136, S("Green")},
 | 
			
		||||
	{"#2c4df1", 0x2c4df1, S("Blue")},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local hud_colors_max = #hud_colors
 | 
			
		||||
 | 
			
		||||
-- Stores temporary player data (persists until player leaves)
 | 
			
		||||
local waypoints_temp = {}
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_page("waypoints", {
 | 
			
		||||
	get_formspec = function(player)
 | 
			
		||||
		local player_name = player:get_player_name()
 | 
			
		||||
 | 
			
		||||
		-- 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 = "background[0,4.5;8,4;ui_main_inventory.png]" ..
 | 
			
		||||
			"image[0,0;1,1;ui_waypoints_icon.png]" ..
 | 
			
		||||
			"label[1,0;" .. F(S("Waypoints")) .. "]"
 | 
			
		||||
 | 
			
		||||
		-- 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).."]"
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local i = waypoints.selected or 1
 | 
			
		||||
		local waypoint = waypoints[i] or {}
 | 
			
		||||
		local temp = waypoints_temp[player_name][i] or {}
 | 
			
		||||
		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")).."]"
 | 
			
		||||
 | 
			
		||||
		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")).."]"
 | 
			
		||||
 | 
			
		||||
		-- Waypoint's info:
 | 
			
		||||
		if waypoint.active then
 | 
			
		||||
			formspec = formspec .. 	"label[1,0.8;"..F(S("Waypoint active")).."]"
 | 
			
		||||
		else
 | 
			
		||||
			formspec = formspec .. 	"label[1,0.8;"..F(S("Waypoint inactive")).."]"
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		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")).."]"
 | 
			
		||||
		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] .. "]"
 | 
			
		||||
 | 
			
		||||
		return {formspec=formspec}
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
unified_inventory.register_button("waypoints", {
 | 
			
		||||
	type = "image",
 | 
			
		||||
	image = "ui_waypoints_icon.png",
 | 
			
		||||
	tooltip = S("Waypoints"),
 | 
			
		||||
	hide_lite=true
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
local function update_hud(player, waypoints, temp, i)
 | 
			
		||||
	local waypoint = waypoints[i]
 | 
			
		||||
	if not waypoint then return end
 | 
			
		||||
	temp[i] = temp[i] or {}
 | 
			
		||||
	temp = temp[i]
 | 
			
		||||
	local pos = waypoint.world_pos or vector.new()
 | 
			
		||||
	local name
 | 
			
		||||
	if waypoint.display_pos then
 | 
			
		||||
		name = minetest.pos_to_string(pos)
 | 
			
		||||
		if waypoint.name then
 | 
			
		||||
			name = name..", "..waypoint.name
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		name = waypoint.name or "Waypoint "..i
 | 
			
		||||
	end
 | 
			
		||||
	if temp.hud then
 | 
			
		||||
		player:hud_remove(temp.hud)
 | 
			
		||||
	end
 | 
			
		||||
	if waypoint.active then
 | 
			
		||||
		temp.hud = player:hud_add({
 | 
			
		||||
			hud_elem_type = "waypoint",
 | 
			
		||||
			number = hud_colors[waypoint.color or 1][2] ,
 | 
			
		||||
			name = name,
 | 
			
		||||
			text = "m",
 | 
			
		||||
			world_pos = pos
 | 
			
		||||
		})
 | 
			
		||||
	else
 | 
			
		||||
		temp.hud = nil
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
	if formname ~= "" then return end
 | 
			
		||||
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local update_formspec = false
 | 
			
		||||
	local need_update_hud = false
 | 
			
		||||
	local hit = false
 | 
			
		||||
 | 
			
		||||
	local waypoints = datastorage.get(player_name, "waypoints")
 | 
			
		||||
	local temp = waypoints_temp[player_name]
 | 
			
		||||
	for i = 1, 5, 1 do
 | 
			
		||||
		if fields["select_waypoint"..i] then
 | 
			
		||||
			hit = true
 | 
			
		||||
			waypoints.selected = i
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if fields["toggle_waypoint"..i] then
 | 
			
		||||
			hit = true
 | 
			
		||||
			waypoints[i] = waypoints[i] or {}
 | 
			
		||||
			waypoints[i].active = not (waypoints[i].active)
 | 
			
		||||
			need_update_hud = true
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if fields["set_waypoint"..i] then
 | 
			
		||||
			hit = true
 | 
			
		||||
			local pos = player:get_pos()
 | 
			
		||||
			pos.x = math.floor(pos.x)
 | 
			
		||||
			pos.y = math.floor(pos.y)
 | 
			
		||||
			pos.z = math.floor(pos.z)
 | 
			
		||||
			waypoints[i] = waypoints[i] or {}
 | 
			
		||||
			waypoints[i].world_pos = pos
 | 
			
		||||
			need_update_hud = true
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if fields["rename_waypoint"..i] then
 | 
			
		||||
			hit = true
 | 
			
		||||
			temp[i] = temp[i] or {}
 | 
			
		||||
			temp[i].edit = true
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if fields["toggle_display_pos"..i] then
 | 
			
		||||
			hit = true
 | 
			
		||||
			waypoints[i] = waypoints[i] or {}
 | 
			
		||||
			waypoints[i].display_pos = not waypoints[i].display_pos
 | 
			
		||||
			need_update_hud = true
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if fields["toggle_color"..i] then
 | 
			
		||||
			hit = true
 | 
			
		||||
			waypoints[i] = waypoints[i] or {}
 | 
			
		||||
			local color = waypoints[i].color or 1
 | 
			
		||||
			color = color + 1
 | 
			
		||||
			if color > hud_colors_max then
 | 
			
		||||
				color = 1
 | 
			
		||||
			end
 | 
			
		||||
			waypoints[i].color = color
 | 
			
		||||
			need_update_hud = true
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if fields["confirm_rename"..i] then
 | 
			
		||||
			hit = true
 | 
			
		||||
			waypoints[i] = waypoints[i] or {}
 | 
			
		||||
			temp[i].edit = false
 | 
			
		||||
			waypoints[i].name = fields["rename_box"..i]
 | 
			
		||||
			need_update_hud = true
 | 
			
		||||
			update_formspec = true
 | 
			
		||||
		end
 | 
			
		||||
		if need_update_hud then
 | 
			
		||||
			update_hud(player, waypoints, temp, i)
 | 
			
		||||
		end
 | 
			
		||||
		if update_formspec then
 | 
			
		||||
			unified_inventory.set_inventory_formspec(player, "waypoints")
 | 
			
		||||
		end
 | 
			
		||||
		if hit then return end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	local waypoints = datastorage.get(player_name, "waypoints")
 | 
			
		||||
	local temp = {}
 | 
			
		||||
	waypoints_temp[player_name] = temp
 | 
			
		||||
	for i = 1, 5 do
 | 
			
		||||
		update_hud(player, waypoints, temp, i)
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
	waypoints_temp[player:get_player_name()] = nil
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||