1 Commits

Author SHA1 Message Date
c884727ff3 Version MFF. 2018-09-08 23:00:32 +02:00
130 changed files with 1840 additions and 4951 deletions

View File

@ -1,11 +0,0 @@
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

0
.gitignore vendored Normal file → Executable file
View File

View File

@ -1,21 +0,0 @@
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",
"doors",
}
files["callbacks.lua"].ignore = { "player", "draw_lite_mode" }
files["bags.lua"].ignore = { "player" }

View File

@ -1,19 +0,0 @@
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.

135
README.md Normal file → Executable file
View File

@ -1,120 +1,31 @@
# Unified Inventory
[![](https://github.com/minetest-mods/unified_inventory/workflows/Check%20&%20Release/badge.svg)](https://github.com/minetest-mods/unified_inventory/actions)
![Screenshot](screenshot.png)
Unified inventory
=================
Unified Inventory replaces the default survival and creative inventory.
It adds a nicer interface and a number of features, such as a crafting guide.
## 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 and refill slot for creative
* Waypoints to keep track of important locations
* 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.4.0+
* Mod `default` for category filters (contained in Minetest Game)
* Mod `farming` for craftable bags (contained in Minetest Game)
* For waypoint migration: `datastorage`
# Licenses
License
=======
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
Copyright (C) 2012-? Various minetest-mods contributors
Unified inventory code is licensed under the GNU LGPLv2+.
Licenses for textures:
VanessaE: (WTFPL)
* ui\_group.png
* ui_form_bg : credits to moretrees mod.
© 2013, Vanessa Ezekowitz <vanessaezekowitz@gmail.com>
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
RealBadAngel: (WTFPL)
* Bags icons
* ui_numbers
* waypoints icons, ui_group, ui_ok, circular_arrows, xyz_icons
Obani : (CC-BY)
* Ui formspecs textures
* Every other icon
## 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)
From https://www.svgrepo.com (CC-BY)
* [`ui_teleport.png`](https://www.svgrepo.com/svg/321565/teleport)
Everaldo Coelho (YellowIcon) (LGPL v2.1+):
* [`ui_craftguide_icon.png` / `ui_craft_icon.png`](http://commons.wikimedia.org/wiki/File:Advancedsettings.png)
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.
## Sounds
* [`bell.ogg`](https://freesound.org/people/bennstir/sounds/81072/) by bennstir, CC 4.0
* [`electricity.ogg`](https://freesound.org/people/Halleck/sounds/19486/) by Halleck, CC 4.0 (cut)
* [`pageflip1.ogg`](https://freesound.org/people/themfish/sounds/45823/) by themfish, CC 4.0 (cut, slowed down)
* `pageflip2.ogg` (derived from `pageflip1.ogg`)
* [`trash.ogg`](https://freesound.org/people/OwlStorm/sounds/151231/) by OwlStorm, CC 0 (speed up)
* [`trash_all.ogg`](https://freesound.org/people/abel_K/sounds/68280/) by abel_K, Sampling Plus 1.0 (speed up)
* [`ui_click.ogg`](https://freesound.org/people/lartti/sounds/527569/) by lartti, CC 0 (cut)
* [`ui_morning.ogg`](https://freesound.org/people/InspectorJ/sounds/439472/) by InspectorJ, CC 4.0
* [`ui_owl.ogg`](https://freesound.org/people/manda_g/sounds/54987/) by manda_g, Sampling Plus 1.0 (cut)

338
api.lua Normal file → Executable file
View File

@ -1,69 +1,67 @@
local S = minetest.get_translator("unified_inventory")
local F = minetest.formspec_escape
local ui = unified_inventory
local function is_recipe_craftable(recipe)
-- Ensure the ingedients exist
for _, itemname in pairs(recipe.items) do
local groups = string.find(itemname, "group:")
if groups then
if not ui.get_group_item(string.sub(groups, 8)).item then
return false
end
else
-- Possibly an item
local itemname_cleaned = ItemStack(itemname):get_name()
if not minetest.registered_items[itemname_cleaned]
or minetest.get_item_group(itemname_cleaned, "not_in_craft_guide") ~= 0 then
return false
end
end
end
return true
end
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
-- Create detached creative inventory after loading all mods
minetest.after(0.01, function()
local rev_aliases = {}
for original, newname in pairs(minetest.registered_aliases) do
if not rev_aliases[newname] then
rev_aliases[newname] = {}
end
table.insert(rev_aliases[newname], original)
for source, target in pairs(minetest.registered_aliases) do
if not rev_aliases[target] then rev_aliases[target] = {} end
table.insert(rev_aliases[target], source)
end
-- Filtered item list
ui.items_list = {}
unified_inventory.items_list = {}
for name, def in pairs(minetest.registered_items) do
if ui.is_itemdef_listable(def) then
table.insert(ui.items_list, name)
-- Alias processing: Find recipes that belong to the current item name
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 all_names = rev_aliases[name] or {}
table.insert(all_names, name)
for _, itemname in ipairs(all_names) do
local recipes = minetest.get_all_craft_recipes(itemname)
for _, recipe in ipairs(recipes or {}) do
if is_recipe_craftable(recipe) then
ui.register_craft(recipe)
for _, name in ipairs(all_names) do
local recipes = minetest.get_all_craft_recipes(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 groupchk then
for _,groupname in pairs(string.gsub(chk, "group:", ""):split(",")) do
if not unified_inventory.get_group_item(groupname).item then
unknowns = true
if minetest.setting_getbool("show_unknown_craftrecipes") then
minetest.log("error", "Recipe for item " .. recipe.output .. " contains unknown group " .. groupname)
end
break
end
end
elseif not minetest.registered_items[chk] then
unknowns = true
if minetest.setting_getbool("show_unknown_craftrecipes") then
minetest.log("error", "Recipe for item " .. recipe.output .. " contains unknown item " .. chk)
end
break
end
end
if not unknowns then
unified_inventory.register_craft(recipe)
end
end
end
end
end
end
table.sort(ui.items_list)
ui.items_list_size = #ui.items_list
print("Unified Inventory. Inventory size: "..ui.items_list_size)
-- Analyse dropped items -> custom "digging" recipes
for _, name in ipairs(ui.items_list) do
table.sort(unified_inventory.items_list)
unified_inventory.items_list_size = #unified_inventory.items_list
minetest.log("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
ui.register_craft({
unified_inventory.register_craft({
type = "digging",
items = {name},
output = def.drop,
@ -96,40 +94,40 @@ minetest.after(0.01, function()
-- 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 def.drop.items then
for i=1,#def.drop.items do
if max_items_left ~= nil and max_items_left <= 0 then break end
local itit = def.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
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
-- 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
ui.register_craft({
unified_inventory.register_craft({
type = "digging",
items = {name},
output = itemstring .. " " .. count,
@ -137,7 +135,7 @@ minetest.after(0.01, function()
})
end
for itemstring, count in pairs(drop_maybe) do
ui.register_craft({
unified_inventory.register_craft({
type = "digging_chance",
items = {name},
output = itemstring .. " " .. count,
@ -146,55 +144,33 @@ minetest.after(0.01, function()
end
end
end
-- Step 1: Initialize cache for looking up groups
unified_inventory.init_matching_cache()
-- Step 2: Find all matching items for the given spec (groups)
local get_matching_spec_items = unified_inventory.get_matching_items
for outputitemname, recipes in pairs(ui.crafts_for.recipe) do
-- List of crafts that return this item string (variable "_")
-- Problem: The group cache must be initialized after all mods finished loading
-- thus, invalid recipes might be indexed. Hence perform filtering with `new_recipe_list`
local new_recipe_list = {}
for _, recipes in pairs(unified_inventory.crafts_for.recipe) do
for _, recipe in ipairs(recipes) do
local ingredient_items = {}
for _, spec in pairs(recipe.items) do
-- Get items that fit into this spec (group or item name)
local specname = ItemStack(spec):get_name()
for item_name, _ in pairs(get_matching_spec_items(specname)) do
ingredient_items[item_name] = true
for _, spec in ipairs(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 not ui.crafts_for.usage[name] then
ui.crafts_for.usage[name] = {}
if unified_inventory.crafts_for.usage[name] == nil then
unified_inventory.crafts_for.usage[name] = {}
end
table.insert(ui.crafts_for.usage[name], recipe)
end
if next(ingredient_items) then
-- There's at least one known ingredient: mark as good recipe
-- PS: What whatll be done about partially incomplete recipes?
table.insert(new_recipe_list, recipe)
table.insert(unified_inventory.crafts_for.usage[name], recipe)
end
end
ui.crafts_for.recipe[outputitemname] = new_recipe_list
end
for _, callback in ipairs(ui.initialized_callbacks) do
callback()
end
end)
---------------- Home API ----------------
-- load_home
local function load_home()
local input = io.open(ui.home_filename, "r")
local input = io.open(unified_inventory.home_filename, "r")
if not input then
ui.home_pos = {}
unified_inventory.home_pos = {}
return
end
while true do
@ -203,42 +179,32 @@ local function load_home()
local y = input:read("*n")
local z = input:read("*n")
local name = input:read("*l")
ui.home_pos[name:sub(2)] = {x = x, y = y, z = z}
unified_inventory.home_pos[name:sub(2)] = {x = x, y = y, z = z}
end
io.close(input)
end
load_home()
function ui.set_home(player, pos)
function unified_inventory.set_home(player, pos)
local player_name = player:get_player_name()
ui.home_pos[player_name] = vector.round(pos)
unified_inventory.home_pos[player_name] = vector.round(pos)
-- save the home data from the table to the file
local output = io.open(ui.home_filename, "w")
if not output then
minetest.log("warning", "[unified_inventory] Failed to save file: "
.. ui.home_filename)
return
end
for k, v in pairs(ui.home_pos) do
local output = io.open(unified_inventory.home_filename, "w")
for k, v in pairs(unified_inventory.home_pos) do
output:write(v.x.." "..v.y.." "..v.z.." "..k.."\n")
end
io.close(output)
end
function ui.go_home(player)
local pos = ui.home_pos[player:get_player_name()]
function unified_inventory.go_home(player)
local pos = unified_inventory.home_pos[player:get_player_name()]
if pos then
player:set_pos(pos)
return true
player:setpos(pos)
end
return false
end
---------------- Crafting API ----------------
function ui.register_craft(options)
-- register_craft
function unified_inventory.register_craft(options)
if not options.output then
return
end
@ -249,24 +215,21 @@ function ui.register_craft(options)
if options.type == "normal" and options.width == 0 then
options = { type = "shapeless", items = options.items, output = options.output, width = 0 }
end
local item_name = itemstack:get_name()
if not ui.crafts_for.recipe[item_name] then
ui.crafts_for.recipe[item_name] = {}
end
table.insert(ui.crafts_for.recipe[item_name],options)
for _, callback in ipairs(ui.craft_registered_callbacks) do
callback(item_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 ui.craft_type_defaults(name, options)
function unified_inventory.craft_type_defaults(name, options)
if not options.description then
options.description = name
end
@ -275,13 +238,14 @@ function ui.craft_type_defaults(name, options)
end
function ui.register_craft_type(name, options)
ui.registered_craft_types[name] = ui.craft_type_defaults(name, options)
function unified_inventory.register_craft_type(name, options)
unified_inventory.registered_craft_types[name] =
unified_inventory.craft_type_defaults(name, options)
end
ui.register_craft_type("normal", {
description = F(S("Crafting")),
unified_inventory.register_craft_type("normal", {
description = F("Crafting"),
icon = "ui_craftgrid_icon.png",
width = 3,
height = 3,
@ -296,8 +260,8 @@ ui.register_craft_type("normal", {
})
ui.register_craft_type("shapeless", {
description = F(S("Mixing")),
unified_inventory.register_craft_type("shapeless", {
description = F("Mixing"),
icon = "ui_craftgrid_icon.png",
width = 3,
height = 3,
@ -311,104 +275,46 @@ ui.register_craft_type("shapeless", {
})
ui.register_craft_type("cooking", {
description = F(S("Cooking")),
unified_inventory.register_craft_type("cooking", {
description = F("Cooking"),
icon = "default_furnace_front.png",
width = 1,
height = 1,
})
ui.register_craft_type("digging", {
description = F(S("Digging")),
unified_inventory.register_craft_type("digging", {
description = F("Digging"),
icon = "default_tool_steelpick.png",
width = 1,
height = 1,
})
ui.register_craft_type("digging_chance", {
unified_inventory.register_craft_type("digging_chance", {
description = "Digging (by chance)",
icon = "default_tool_steelpick.png^[transformFY.png",
width = 1,
height = 1,
})
---------------- GUI registrations ----------------
function ui.register_page(name, def)
ui.pages[name] = def
function unified_inventory.register_page(name, def)
unified_inventory.pages[name] = def
end
function ui.register_button(name, def)
function unified_inventory.register_button(name, def)
if not def.action then
def.action = function(player)
ui.set_inventory_formspec(player, name)
unified_inventory.set_inventory_formspec(player, name)
end
end
def.name = name
table.insert(ui.buttons, def)
table.insert(unified_inventory.buttons, def)
end
---------------- Callback registrations ----------------
function ui.register_on_initialized(callback)
if type(callback) ~= "function" then
error(("Initialized callback must be a function, %s given."):format(type(callback)))
end
table.insert(ui.initialized_callbacks, callback)
end
function ui.register_on_craft_registered(callback)
if type(callback) ~= "function" then
error(("Craft registered callback must be a function, %s given."):format(type(callback)))
end
table.insert(ui.craft_registered_callbacks, callback)
end
---------------- List getters ----------------
function ui.get_recipe_list(output)
return ui.crafts_for.recipe[output]
end
function ui.get_registered_outputs()
local outputs = {}
for item_name, _ in pairs(ui.crafts_for.recipe) do
table.insert(outputs, item_name)
end
return outputs
end
---------------- Player utilities ----------------
function ui.is_creative(playername)
function unified_inventory.is_creative(playername)
return minetest.check_player_privs(playername, {creative=true})
or minetest.settings:get_bool("creative_mode")
or minetest.setting_getbool("creative_mode")
end
---------------- Formspec helpers ----------------
function ui.single_slot(xpos, ypos, bright)
return string.format("background9[%f,%f;%f,%f;ui_single_slot%s.png;false;16]",
xpos, ypos, ui.imgscale, ui.imgscale, (bright and "_bright" or "") )
end
function ui.make_trash_slot(xpos, ypos)
return
ui.single_slot(xpos, ypos)..
"image["..xpos..","..ypos..";1.25,1.25;ui_trash_slot_icon.png]"..
"list[detached:trash;main;"..(xpos + ui.list_img_offset)..","..(ypos + ui.list_img_offset)..";1,1;]"
end
function ui.make_inv_img_grid(xpos, ypos, width, height, bright)
local tiled = {}
local n=1
for y = 0, (height - 1) do
for x = 0, (width -1) do
tiled[n] = ui.single_slot(xpos + (ui.imgscale * x), ypos + (ui.imgscale * y), bright)
n = n + 1
end
end
return table.concat(tiled)
end

470
bags.lua Normal file → Executable file
View File

@ -1,251 +1,188 @@
--[[
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
local ui = unified_inventory
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
ui.register_page("bags", {
get_formspec = function(player, perplayer_formspec)
unified_inventory.register_page("bags", {
get_formspec = function(player)
local player_name = player:get_player_name()
local std_inv_x = perplayer_formspec.std_inv_x
local formspec = {
perplayer_formspec.standard_inv_bg,
"label[", perplayer_formspec.form_header_x, ",",
perplayer_formspec.form_header_y, ";", F(S("Bags")), "]",
"listcolors[#00000000;#00000000]",
}
for i = 1, 4 do
local x = std_inv_x + i * 2.5
formspec[#formspec + 1] = ui.single_slot(x - 1.875, 1.5)
formspec[#formspec + 1] = string.format("list[detached:%s_bags;bag%i;%.3f,1.65;1,1;]",
F(player_name), i, x - 1.725)
formspec[#formspec + 1] = string.format("button[%.4f,2.75;1.875,0.75;bag%i;%s]",
x - 2.1875, i, F(S("Bag @1", i)))
end
return { formspec = table.concat(formspec) }
local formspec = "background[0.06,0.99;7.92,7.52;ui_bags_main_form.png]"
formspec = formspec.."label[0,0;"..F("Bags").."]"
formspec = formspec.."button[0,2;2,0.5;bag1;"..F("Bag 1").."]" .. "button[0,3;2,0.5;unequip_bag1;Unequip]"
formspec = formspec.."button[2,2;2,0.5;bag2;"..F("Bag 2").."]" .. "button[2,3;2,0.5;unequip_bag2;Unequip]"
formspec = formspec.."button[4,2;2,0.5;bag3;"..F("Bag 3").."]" .. "button[4,3;2,0.5;unequip_bag3;Unequip]"
formspec = formspec.."button[6,2;2,0.5;bag4;"..F("Bag 4").."]" .. "button[6,3;2,0.5;unequip_bag4;Unequip]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag1;0.5,1;1,1;]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag2;2.5,1;1,1;]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag3;4.5,1;1,1;]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag4;6.5,1;1,1;]"
return {formspec=formspec}
end,
})
ui.register_button("bags", {
unified_inventory.register_button("bags", {
type = "image",
image = "ui_bags_icon.png",
tooltip = S("Bags"),
hide_lite=true,
show_with = false, --Modif MFF (Crabman 30/06/2015)
})
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
ui.register_page("bag" .. bag_i, {
get_formspec = function(player, perplayer_formspec)
local stack = get_player_bag_stack(player, bag_i)
unified_inventory.register_page("bag1", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag1", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 1").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag1contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag1contents]"
formspec = formspec.."listring[current_player;main]"
local slots = stack:get_definition().groups.bagslots
local std_inv_x = perplayer_formspec.std_inv_x
local lite_mode = perplayer_formspec.is_lite_mode
local bag_inv_y, header_x, header_y = 1.5, 0.3, 0.65
if lite_mode then
bag_inv_y = 0.5
header_x = perplayer_formspec.form_header_x
header_y = perplayer_formspec.form_header_y
if slots == 8 then
formspec = formspec.."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]"
elseif slots == 24 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_lg_form.png]"
end
local formspec = {
perplayer_formspec.standard_inv_bg,
ui.make_inv_img_grid(std_inv_x, bag_inv_y, 8, slots/8),
"label[", header_x, ",", header_y, ";", F(S("Bag @1", bag_i)), "]",
"listcolors[#00000000;#00000000]",
"listring[current_player;main]",
string.format("list[current_player;bag%icontents;%f,%f;8,3;]",
bag_i, std_inv_x + ui.list_img_offset, bag_inv_y + ui.list_img_offset),
"listring[current_name;bag", bag_i, "contents]",
}
if lite_mode then
return { formspec = table.concat(formspec) }
end
local n = #formspec + 1
formspec[n] = "image[" .. std_inv_x + 8.9 .. ",0.4;1,1;" .. image .. "]"
n = n + 1
local player_name = player:get_player_name() -- For if statement.
if ui.trash_enabled
or ui.is_creative(player_name)
or minetest.get_player_privs(player_name).give then
formspec[n] = ui.make_trash_slot(7.8, 0.25)
n = n + 1
end
local inv = player:get_inventory()
for i = 1, 4 do
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
formspec[n] = string.format("image_button[%f,0.4;1,1;%s;bag%i;%s]",
(i + 1.35)*1.25, img, i, label)
n = n + 1
end
end
return { formspec = table.concat(formspec) }
return {formspec=formspec}
end,
})
unified_inventory.register_page("bag2", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag2", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 2").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag2contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag2contents]"
formspec = formspec.."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]"
elseif slots == 16 then
formspec = formspec.."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]"
end
return {formspec=formspec}
end,
})
unified_inventory.register_page("bag3", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag3", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 3").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag3contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag3contents]"
formspec = formspec.."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]"
elseif slots == 16 then
formspec = formspec.."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]"
end
return {formspec=formspec}
end,
})
unified_inventory.register_page("bag4", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag4", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 4").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag4contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag4contents]"
formspec = formspec.."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]"
elseif slots == 16 then
formspec = formspec.."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]"
end
return {formspec=formspec}
end,
})
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "" then
return
end
for i = 1, 4 do
if fields["bag" .. i] then
local stack = get_player_bag_stack(player, i)
if fields["bag"..i] then
local stack = player:get_inventory():get_stack("bag"..i, 1)
if not stack:get_definition().groups.bagslots then
return
end
ui.set_inventory_formspec(player, "bag" .. i)
unified_inventory.set_inventory_formspec(player, "bag"..i)
return
elseif fields["unequip_bag" .. i] then
local stack = unified_inventory.extract_bag(player, i)
if not stack then
return
elseif stack == "overflow" then
minetest.chat_send_player(player:get_player_name(), "You bag is too heavy to be unequipped... Remove some items and retry")
return
elseif not player:get_inventory():room_for_item("main", stack) then
local pos = player:getpos()
pos.y = pos.y + 2
minetest.add_item(pos, stack)
return
end
player:get_inventory():add_item("main", stack)
end
end
end)
-- Player slots are preserved when unified_inventory is disabled. Do not allow modification.
-- Fix: use a detached inventory and store the data separately.
local function save_bags_metadata(player, bags_inv)
local is_empty = true
local bags = {}
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 meta = player:get_meta()
local bags_meta = meta:get("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
-- Legacy: Clean up old player lists
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", {
allow_put = function(inv, listname, index, stack, player)
local new_slots = stack:get_definition().groups.bagslots
if not new_slots then
return 0 -- ItemStack is not a bag.
local player_inv = player:get_inventory()
local bags_inv = minetest.create_detached_inventory(player:get_player_name().."_bags",{
on_put = function(inv, listname, index, stack, player)
local pinv = player:get_inventory()
pinv:set_stack(listname, index, stack)
pinv:set_size(listname.."contents",
stack:get_definition().groups.bagslots)
-- Retrieve the serialized inventory if any
if stack:get_metadata() ~= "" then
for i, item in pairs(minetest.deserialize(stack:get_metadata())) do
pinv:set_stack(listname .. "contents", i, ItemStack(item))
end
end
-- The execution order of `allow_put`/`allow_take` is not defined.
-- We do not know the replacement ItemStack if the items are swapped.
-- Hence, bag slot upgrades and downgrades are not possible with the
-- current API.
if not player:get_inventory():is_empty(listname .. "contents") then
-- Legacy: in case `allow_take` is not executed on old Minetest versions.
end,
allow_take = function()
return 0
end,
allow_put = function(inv, listname, index, stack, player)
if stack:get_definition().groups.bagslots then
return 1
else
return 0
end
return 1
end,
on_put = function(inv, listname, index, stack, player)
player:get_inventory():set_size(listname .. "contents",
stack:get_definition().groups.bagslots)
save_bags_metadata(player, inv)
end,
allow_take = function(inv, listname, index, stack, player)
if player:get_inventory():is_empty(listname .. "contents") then
return stack:get_count()
end
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return 0
end,
on_take = function(inv, listname, index, stack, player)
player:get_inventory():set_size(listname .. "contents", 0)
save_bags_metadata(player, inv)
if listname == ui.current_page[player:get_player_name()] then
-- Bag is currently open: avoid follow-up issues by navigating back
-- Trick: the list name is the same as the registered page name
ui.set_inventory_formspec(player, "bags")
end
end,
allow_move = function()
return 0
end,
}, player_name)
load_bags_metadata(player, bags_inv)
end)
minetest.register_allow_player_inventory_action(function(player, action, inventory, info)
-- From detached inventory -> player inventory: put & take callbacks
if action ~= "put" or not info.listname:find("bag%dcontents") then
return
end
if info.stack:get_definition().groups.bagslots then
-- Problem 1: empty bags could be moved into their own slots
-- Problem 2: cannot reliably keep track of ItemStack ownership due to
--> Disallow all external bag movements into this list
return 0
})
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
end)
@ -268,32 +205,119 @@ minetest.register_tool("unified_inventory:bag_large", {
groups = {bagslots=24},
})
-- register bag crafts
if minetest.get_modpath("farming") ~= nil then
local colours = {"orange", "blue", "green", "violet"}
for _, colour in pairs(colours) do
minetest.register_tool("unified_inventory:bag_small_" .. colour, {
description = S("Small Bag"),
inventory_image = "bags_small_" .. colour .. ".png",
groups = {bagslots=8},
})
minetest.register_tool("unified_inventory:bag_medium_" .. colour, {
description = S("Medium Bag"),
inventory_image = "bags_medium_" .. colour .. ".png",
groups = {bagslots=16},
})
minetest.register_tool("unified_inventory:bag_large_" .. colour, {
description = S("Large Bag"),
inventory_image = "bags_large_" .. colour .. ".png",
groups = {bagslots=24},
})
-- register bag crafts
minetest.register_craft({
output = "unified_inventory:bag_small",
output = "unified_inventory:bag_small_" .. colour,
recipe = {
{"", "farming:string", ""},
{"group:wool", "group:wool", "group:wool"},
{"group:wool", "group:wool", "group:wool"},
{"dye:"..colour, "unified_inventory:bag_small"},
},
})
minetest.register_craft({
output = "unified_inventory:bag_medium",
output = "unified_inventory:bag_medium_" .. colour,
recipe = {
{"", "", ""},
{"farming:string", "unified_inventory:bag_small", "farming:string"},
{"farming:string", "unified_inventory:bag_small", "farming:string"},
{"", "", ""},
{"farming:cotton", "unified_inventory:bag_small_" .. colour, "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_small_" .. colour, "farming:cotton"},
},
})
minetest.register_craft({
output = "unified_inventory:bag_large",
output = "unified_inventory:bag_large_" .. colour,
recipe = {
{"", "", ""},
{"farming:string", "unified_inventory:bag_medium", "farming:string"},
{"farming:string", "unified_inventory:bag_medium", "farming:string"},
{"", "", ""},
{"farming:cotton", "unified_inventory:bag_medium_" .. colour, "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_medium_" .. colour, "farming:cotton"},
},
})
end
--minetest.register_alias("unified_inventory:bag_small", "unified_inventory:bad_small_red")
--minetest.register_alias("unified_inventory:bag_medium", "unified_inventory:bad_medium_red")
--minetest.register_alias("unified_inventory:bag_large", "unified_inventory:bad_large_red")
-- register bag crafts
minetest.register_craft({
output = "unified_inventory:bag_small",
recipe = {
{"", "farming:cotton", ""},
{"group:wool", "group:wool", "group:wool"},
{"group:wool", "group:wool", "group:wool"},
},
})
minetest.register_craft({
output = "unified_inventory:bag_medium",
recipe = {
{"", "", ""},
{"farming:cotton", "unified_inventory:bag_small", "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_small", "farming:cotton"},
},
})
minetest.register_craft({
output = "unified_inventory:bag_large",
recipe = {
{"", "", ""},
{"farming:cotton", "unified_inventory:bag_medium", "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_medium", "farming:cotton"},
},
})
function unified_inventory.extract_bag(player, id)
if not player then
minetest.log("error", "[u_inv] Invalid player for bag extraction : nil")
return
end
if tonumber(id) == nil or id > 4 or id < 0 then
minetest.log("error", "Invalid id: " .. (id or 'nil'))
return
end
local stack = player:get_inventory():get_stack("bag"..id, 1)
if not stack:get_definition().groups.bagslots then
return
end
local pinv = player:get_inventory()
local inv = pinv:get_list("bag" .. id .. "contents")
local list = {}
for i, item in pairs(inv) do
list[i] = item:to_table()
end
if minetest.serialize(list):len() >= 4096 then
minetest.log("warning", "[U_Inv] Preventing metadata overflow with bag metadata")
return "overflow"
end
pinv:remove_item("bag" .. id, stack)
local dinv = minetest.get_inventory({type = "detached", name = minetest.formspec_escape(player:get_player_name()) .. "_bags"})
if dinv then
dinv:set_stack("bag" .. id, 1, nil)
end
pinv:set_list("bag" .. id .. "contents", {})
stack:set_metadata(minetest.serialize(list))
return stack
end

152
callbacks.lua Normal file → Executable file
View File

@ -1,5 +1,3 @@
local ui = unified_inventory
local function default_refill(stack)
stack:set_count(stack:get_stack_max())
local itemdef = minetest.registered_items[stack:get_name()]
@ -14,21 +12,23 @@ end
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
unified_inventory.players[player_name] = {}
unified_inventory.current_index[player_name] = 1 -- Item (~page) index
unified_inventory.current_index[player_name] = 1
unified_inventory.filtered_items_list[player_name] =
unified_inventory.items_list
unified_inventory.items_list
unified_inventory.activefilter[player_name] = ""
unified_inventory.active_search_direction[player_name] = "nochange"
unified_inventory.apply_filter(player, "", "nochange")
unified_inventory.current_searchbox[player_name] = ""
unified_inventory.current_category[player_name] = "all"
unified_inventory.current_category_scroll[player_name] = 0
unified_inventory.alternate[player_name] = 1
unified_inventory.current_item[player_name] = nil
unified_inventory.current_craft_direction[player_name] = "recipe"
unified_inventory.set_inventory_formspec(player,
unified_inventory.default)
-- Refill slot
local refill = minetest.create_detached_inventory(player_name.."refill", {
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
@ -36,102 +36,47 @@ minetest.register_on_joinplayer(function(player)
end
end,
on_put = function(inv, listname, index, stack, player)
local player_name = player:get_player_name()
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)
minetest.register_on_mods_loaded(function()
minetest.register_on_joinplayer(function(player)
-- After everything is initialized, set up the formspec
ui.apply_filter(player, "", "nochange")
ui.set_inventory_formspec(player, unified_inventory.default)
end)
end)
local function apply_new_filter(player, search_text, new_dir)
local player_name = player:get_player_name()
minetest.sound_play("ui_click", {to_player=player_name, gain = 0.1})
ui.apply_filter(player, search_text, new_dir)
ui.current_searchbox[player_name] = search_text
ui.set_inventory_formspec(player, ui.current_page[player_name])
end
-- Search box handling
local function receive_fields_searchbox(player, formname, fields)
local player_name = player:get_player_name()
-- always take new search text, even if not searching on it yet
if fields.searchbox and fields.searchbox ~= ui.current_searchbox[player_name] then
ui.current_searchbox[player_name] = fields.searchbox
end
if fields.searchbutton
or fields.key_enter_field == "searchbox" then
if ui.current_searchbox[player_name] ~= ui.activefilter[player_name] then
ui.apply_filter(player, ui.current_searchbox[player_name], "nochange")
ui.set_inventory_formspec(player, ui.current_page[player_name])
minetest.sound_play("paperflip2",
{to_player=player_name, gain = 1.0})
end
elseif fields.searchresetbutton then
if ui.activefilter[player_name] ~= "" then
apply_new_filter(player, "", "nochange")
end
end
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "" then
return
end
receive_fields_searchbox(player, formname, fields)
local player_name = player:get_player_name()
local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
local clicked_category
for name, value in pairs(fields) do
local category_name = string.match(name, "^category_(.+)$")
if category_name then
clicked_category = category_name
break
end
if formname ~= "" then
return
end
if clicked_category
and clicked_category ~= unified_inventory.current_category[player_name] then
unified_inventory.current_category[player_name] = clicked_category
unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange")
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
if fields.hidebutton then --MFF crabman(29/11/2015) hide guide, textfield bug
if not unified_inventory.hidden_guide[player_name] then
unified_inventory.hidden_guide[player_name] = true
else
unified_inventory.hidden_guide[player_name] = false
end
unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
return
end
if fields.next_category or fields.prev_category then
local step = fields.next_category and 1 or -1
local scroll_old = ui.current_category_scroll[player_name]
local scroll_new = math.max(0, math.min(#ui.category_list - ui_peruser.pagecols, scroll_old + step))
if scroll_old ~= scroll_new then
ui.current_category_scroll[player_name] = scroll_new
ui.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
end
-- 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
unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
end
for i, def in pairs(unified_inventory.buttons) do
if fields[def.name] then
def.action(player)
minetest.sound_play("ui_click",
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
return
end
@ -177,26 +122,28 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
unified_inventory.current_page[player_name])
end
-- Check clicked item image button
local clicked_item
for name, value in pairs(fields) do
local new_dir, mangled_item = string.match(name, "^[0-9]*_?item_button_([a-z]+)_(.*)$")
if new_dir and mangled_item then
if string.sub(name, 1, 12) == "item_button_" then
local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$")
clicked_item = unified_inventory.demangle_for_formspec(mangled_item)
if string.sub(clicked_item, 1, 6) == "group:" then
-- Change search filter to this group
unified_inventory.current_category[player_name] = "all"
apply_new_filter(player, clicked_item, new_dir)
minetest.sound_play("click", {to_player=player_name, gain = 0.1})
unified_inventory.apply_filter(player, clicked_item, new_dir)
unified_inventory.current_searchbox[player_name] = clicked_item
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
return
end
if new_dir == "recipe" or new_dir == "usage" then
if new_dir == "recipe"
or new_dir == "usage" then
unified_inventory.current_craft_direction[player_name] = new_dir
end
break
end
end
if clicked_item then
minetest.sound_play("ui_click",
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
local page = unified_inventory.current_page[player_name]
local player_creative = unified_inventory.is_creative(player_name)
@ -208,7 +155,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
unified_inventory.alternate[player_name] = 1
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())
@ -218,11 +164,26 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end
if fields.searchbutton or fields.key_enter_field == "searchbox" then
unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange")
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
minetest.sound_play("paperflip2",
{to_player=player_name, gain = 1.0})
elseif fields.searchresetbutton then
unified_inventory.apply_filter(player, "", "nochange")
unified_inventory.current_searchbox[player_name] = ""
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
end
-- alternate buttons
if not (fields.alternate or fields.alternate_prev) then
return
end
minetest.sound_play("ui_click",
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
local item_name = unified_inventory.current_item[player_name]
if not item_name then
@ -253,8 +214,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
unified_inventory.current_page[player_name])
end)
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
minetest.remove_detached_inventory(player_name.."_bags")
minetest.remove_detached_inventory(player_name.."refill")
end)
if minetest.delete_detached_inventory then
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
minetest.delete_detached_inventory(player_name.."_bags")
minetest.delete_detached_inventory(player_name.."craftrecipe")
minetest.delete_detached_inventory(player_name.."refill")
end)
end

View File

@ -1,153 +0,0 @@
local S = minetest.get_translator("unified_inventory")
unified_inventory.registered_categories = {}
unified_inventory.registered_category_items = {}
unified_inventory.category_list = {}
local function char_to_sort_index(char_code)
if char_code <= 32 then
-- Command codes, no thanks
return 0
end
if char_code <= 64 then
-- Sorts numbers, and some punctuation, after letters
return char_code
end
if char_code >= 158 then
-- Out of sortable range
return 0
end
if char_code > 122 then
-- Avoids overlap with {, |, } and ~
return char_code - 58
end
if char_code > 96 then
-- Normalises lowercase with uppercase
return char_code - 96
end
return char_code - 64
end
local function string_to_sort_index(str)
local max_chars = 5
local power = 100
local index = 0
for i=1,math.min(#str, max_chars) do
index = index + (char_to_sort_index(string.byte(str, i))/(power^i))
end
return index
end
function update_category_list()
local category_list = {}
table.insert(category_list, {
name = "all",
label = S("All Items"),
symbol = "ui_category_all.png",
index = -2,
})
table.insert(category_list, {
name = "uncategorized",
label = S("Misc. Items"),
symbol = "ui_category_none.png",
index = -1,
})
for category, def in pairs(unified_inventory.registered_categories) do
table.insert(category_list, {
name = category,
label = def.label or category,
symbol = def.symbol,
index = def.index or -- sortby defined order
string_to_sort_index(category) -- or do a rudimentary alphabetical sort
})
end
table.sort(category_list, function (a,b)
return a.index < b.index
end)
unified_inventory.category_list = category_list
end
local function ensure_category_exists(category_name)
if not unified_inventory.registered_categories[category_name] then
unified_inventory.registered_categories[category_name] = {
symbol = "unknown_item.png",
label = category_name
}
end
if not unified_inventory.registered_category_items[category_name] then
unified_inventory.registered_category_items[category_name] = {}
end
end
function unified_inventory.register_category(category_name, config)
ensure_category_exists(category_name)
config = config or {}
if config.symbol then
unified_inventory.set_category_symbol(category_name, config.symbol)
end
if config.label then
unified_inventory.set_category_label(category_name, config.label)
end
if config.index then
unified_inventory.set_category_index(category_name, config.index)
end
if config.items then
unified_inventory.add_category_items(category_name, config.items)
end
update_category_list()
end
-- TODO: Mark these for removal. They are pretty much useless
function unified_inventory.set_category_symbol(category_name, symbol)
ensure_category_exists(category_name)
unified_inventory.registered_categories[category_name].symbol = symbol
update_category_list()
end
function unified_inventory.set_category_label(category_name, label)
ensure_category_exists(category_name)
unified_inventory.registered_categories[category_name].label = label
update_category_list()
end
function unified_inventory.set_category_index(category_name, index)
ensure_category_exists(category_name)
unified_inventory.registered_categories[category_name].index = index
update_category_list()
end
function unified_inventory.add_category_item(category_name, item)
ensure_category_exists(category_name)
unified_inventory.registered_category_items[category_name][item] = true
end
function unified_inventory.add_category_items(category_name, items)
for _,item in ipairs(items) do
unified_inventory.add_category_item(category_name, item)
end
end
function unified_inventory.remove_category_item(category_name, item)
unified_inventory.registered_category_items[category_name][item] = nil
end
function unified_inventory.remove_category(category_name)
unified_inventory.registered_categories[category_name] = nil
unified_inventory.registered_category_items[category_name] = nil
update_category_list()
end
function unified_inventory.find_category(item)
-- Returns the first category the item exists in
-- Best for checking if an item has any category at all
for category, items in pairs(unified_inventory.registered_category_items) do
if items[item] then return category end
end
end
function unified_inventory.find_categories(item)
-- Returns all the categories the item exists in
-- Best for listing all categories
local categories = {}
for category, items in pairs(unified_inventory.registered_category_items) do
if items[item] then
table.insert(categories, category)
end
end
return categories
end

View File

@ -1,704 +0,0 @@
local S = minetest.get_translator("unified_inventory")
unified_inventory.register_category('plants', {
symbol = "flowers:tulip",
label = S("Plant Life")
})
unified_inventory.register_category('building', {
symbol = "default:brick",
label = S("Building Materials")
})
unified_inventory.register_category('tools', {
symbol = "default:pick_diamond",
label = S("Tools")
})
unified_inventory.register_category('minerals', {
symbol = "default:iron_lump",
label = S("Minerals and Metals")
})
unified_inventory.register_category('environment', {
symbol = "default:dirt_with_grass",
label = S("Environment and Worldgen")
})
unified_inventory.register_category('lighting', {
symbol = "default:torch",
label = S("Lighting")
})
if unified_inventory.automatic_categorization then
minetest.register_on_mods_loaded(function()
-- Add biome nodes to environment category
for _,def in pairs(minetest.registered_biomes) do
local env_nodes = {
def.node_riverbed, def.node_top, def.node_filler, def.node_dust,
}
for i,node in pairs(env_nodes) do
if node then
unified_inventory.add_category_item('environment', node)
end
end
end
-- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment
for _,item in pairs(minetest.registered_ores) do
if item.ore_type == "scatter" then
local drop = minetest.registered_nodes[item.ore].drop
if drop and drop ~= "" then
unified_inventory.add_category_item('minerals', item.ore)
unified_inventory.add_category_item('minerals', drop)
else
unified_inventory.add_category_item('environment', item.ore)
end
else
unified_inventory.add_category_item('environment', item.ore)
end
end
-- Add items by item definition
for name, def in pairs(minetest.registered_items) do
local group = def.groups or {}
if not group.not_in_creative_inventory then
if group.stair or
group.slab or
group.wall or
group.fence then
unified_inventory.add_category_item('building', name)
elseif group.flora or
group.flower or
group.seed or
group.leaves or
group.sapling or
group.tree then
unified_inventory.add_category_item('plants', name)
elseif def.type == 'tool' then
unified_inventory.add_category_item('tools', name)
elseif def.liquidtype == 'source' then
unified_inventory.add_category_item('environment', name)
elseif def.light_source and def.light_source > 0 then
unified_inventory.add_category_item('lighting', name)
elseif group.door or
minetest.global_exists("doors") and (
doors.registered_doors and doors.registered_doors[name..'_a'] or
doors.registered_trapdoors and doors.registered_trapdoors[name]
) then
unified_inventory.add_category_item('building', name)
end
end
end
end)
end
-- [[
unified_inventory.add_category_items('plants', {
"default:dry_grass_5",
"default:acacia_sapling",
"default:blueberry_bush_sapling",
"default:grass_2",
"default:pine_bush_stem",
"default:leaves",
"default:pine_needles",
"default:cactus",
"default:junglegrass",
"default:pine_sapling",
"default:sapling",
"default:bush_stem",
"default:dry_grass_2",
"default:fern_1",
"default:grass_3",
"default:marram_grass_1",
"default:pine_tree",
"default:dry_grass_3",
"default:dry_shrub",
"default:grass_4",
"default:marram_grass_2",
"default:jungleleaves",
"default:apple",
"default:tree",
"default:aspen_tree",
"default:bush_sapling",
"default:grass_5",
"default:blueberry_bush_leaves_with_berries",
"default:acacia_bush_sapling",
"default:grass_1",
"default:aspen_leaves",
"default:marram_grass_3",
"default:large_cactus_seedling",
"default:junglesapling",
"default:dry_grass_4",
"default:acacia_bush_stem",
"default:papyrus",
"default:pine_bush_needles",
"default:bush_leaves",
"default:fern_3",
"default:aspen_sapling",
"default:acacia_tree",
"default:apple_mark",
"default:acacia_leaves",
"default:jungletree",
"default:dry_grass_1",
"default:acacia_bush_leaves",
"default:emergent_jungle_sapling",
"default:fern_2",
"default:blueberries",
"default:sand_with_kelp",
"default:blueberry_bush_leaves",
"default:pine_bush_sapling",
"farming:cotton",
"farming:cotton_1",
"farming:cotton_2",
"farming:cotton_3",
"farming:cotton_4",
"farming:cotton_5",
"farming:cotton_6",
"farming:cotton_7",
"farming:cotton_8",
"farming:cotton_wild",
"farming:seed_cotton",
"farming:seed_wheat",
"farming:straw",
"farming:wheat",
"farming:wheat_1",
"farming:wheat_2",
"farming:wheat_3",
"farming:wheat_4",
"farming:wheat_5",
"farming:wheat_6",
"farming:wheat_7",
"farming:wheat_8",
"flowers:chrysanthemum_green",
"flowers:dandelion_white",
"flowers:dandelion_yellow",
"flowers:geranium",
"flowers:mushroom_brown",
"flowers:mushroom_red",
"flowers:rose",
"flowers:tulip",
"flowers:tulip_black",
"flowers:viola",
"flowers:waterlily",
"flowers:waterlily_waving",
})
unified_inventory.add_category_items('tools', {
"default:sword_diamond",
"default:axe_diamond",
"default:shovel_diamond",
"default:axe_steel",
"default:shovel_mese",
"default:sword_wood",
"default:pick_bronze",
"default:axe_stone",
"default:sword_stone",
"default:pick_stone",
"default:shovel_stone",
"default:sword_mese",
"default:shovel_bronze",
"default:sword_bronze",
"default:axe_bronze",
"default:shovel_steel",
"default:sword_steel",
"default:axe_mese",
"default:shovel_wood",
"default:pick_mese",
"default:axe_wood",
"default:pick_diamond",
"default:pick_wood",
"default:pick_steel",
"farming:hoe_bronze",
"farming:hoe_diamond",
"farming:hoe_mese",
"farming:hoe_steel",
"farming:hoe_stone",
"farming:hoe_wood",
"fire:flint_and_steel",
"map:mapping_kit",
"screwdriver:screwdriver",
"fireflies:bug_net",
"bucket:bucket_empty",
"binoculars:binoculars",
"default:skeleton_key",
})
unified_inventory.add_category_items('minerals', {
"default:stone_with_copper",
"default:stone_with_gold",
"default:stone_with_iron",
"default:copper_ingot",
"default:copper_lump",
"default:gold_lump",
"default:diamondblock",
"default:stone_with_diamond",
"default:stone_with_mese",
"default:steel_ingot",
"default:gold_ingot",
"default:iron_lump",
"default:tinblock",
"default:tin_lump",
"default:stone_with_tin",
"default:mese_crystal",
"default:diamond",
"default:bronze_ingot",
"default:mese",
"default:mese_crystal_fragment",
"default:copperblock",
"default:stone_with_coal",
"default:steelblock",
"default:tin_ingot",
"default:coalblock",
"default:coal_lump",
"default:bronzeblock",
"default:goldblock",
"stairs:slab_bronzeblock",
"stairs:slab_copperblock",
"stairs:slab_steelblock",
"stairs:slab_tinblock",
"stairs:stair_bronzeblock",
"stairs:stair_copperblock",
"stairs:stair_inner_bronzeblock",
"stairs:stair_inner_copperblock",
"stairs:stair_inner_steelblock",
"stairs:stair_inner_tinblock",
"stairs:stair_outer_bronzeblock",
"stairs:stair_outer_copperblock",
"stairs:stair_outer_steelblock",
"stairs:stair_outer_tinblock",
"stairs:stair_steelblock",
"stairs:stair_tinblock",
})
unified_inventory.add_category_items('building', {
"default:fence_rail_aspen_wood",
"default:fence_rail_acacia_wood",
"default:fence_junglewood",
"default:fence_rail_junglewood",
"default:fence_aspen_wood",
"default:fence_pine_wood",
"default:fence_rail_wood",
"default:fence_rail_pine_wood",
"default:fence_acacia_wood",
"default:junglewood",
"default:acacia_wood",
"default:aspen_wood",
"default:fence_wood",
"default:pine_wood",
"default:silver_sandstone",
"default:desert_sandstone",
"default:sandstone_block",
"default:desert_sandstone_brick",
"default:stone_block",
"default:stonebrick",
"default:obsidian_glass",
"default:desert_sandstone_block",
"default:silver_sandstone_brick",
"default:brick",
"default:obsidianbrick",
"default:sandstonebrick",
"default:sandstone",
"default:desert_stone_block",
"default:silver_sandstone_block",
"default:wood",
"default:obsidian_block",
"default:glass",
"default:clay_brick",
"default:desert_stonebrick",
"default:desert_cobble",
"default:cobble",
"default:mossycobble",
"doors:door_glass",
"doors:door_glass_a",
"doors:door_glass_b",
"doors:door_glass_c",
"doors:door_glass_d",
"doors:door_obsidian_glass",
"doors:door_obsidian_glass_a",
"doors:door_obsidian_glass_b",
"doors:door_obsidian_glass_c",
"doors:door_obsidian_glass_d",
"doors:door_steel",
"doors:door_steel_a",
"doors:door_steel_b",
"doors:door_steel_c",
"doors:door_steel_d",
"doors:door_wood",
"doors:door_wood_a",
"doors:door_wood_b",
"doors:door_wood_c",
"doors:door_wood_d",
"doors:gate_acacia_wood_closed",
"doors:gate_acacia_wood_open",
"doors:gate_aspen_wood_closed",
"doors:gate_aspen_wood_open",
"doors:gate_junglewood_closed",
"doors:gate_junglewood_open",
"doors:gate_pine_wood_closed",
"doors:gate_pine_wood_open",
"doors:gate_wood_closed",
"doors:gate_wood_open",
"doors:hidden",
"doors:trapdoor",
"doors:trapdoor_open",
"doors:trapdoor_steel",
"doors:trapdoor_steel_open",
"stairs:slab_bronzeblock",
"stairs:slab_copperblock",
"stairs:slab_steelblock",
"stairs:slab_tinblock",
"stairs:stair_bronzeblock",
"stairs:stair_copperblock",
"stairs:stair_inner_bronzeblock",
"stairs:stair_inner_copperblock",
"stairs:stair_inner_steelblock",
"stairs:stair_inner_tinblock",
"stairs:stair_outer_bronzeblock",
"stairs:stair_outer_copperblock",
"stairs:stair_outer_steelblock",
"stairs:stair_outer_tinblock",
"stairs:stair_steelblock",
"stairs:stair_tinblock",
"stairs:slab_acacia_wood",
"stairs:slab_aspen_wood",
"stairs:slab_brick",
"stairs:slab_cobble",
"stairs:slab_desert_cobble",
"stairs:slab_desert_sandstone",
"stairs:slab_desert_sandstone_block",
"stairs:slab_desert_sandstone_brick",
"stairs:slab_desert_stone",
"stairs:slab_desert_stone_block",
"stairs:slab_desert_stonebrick",
"stairs:slab_glass",
"stairs:slab_goldblock",
"stairs:slab_ice",
"stairs:slab_junglewood",
"stairs:slab_mossycobble",
"stairs:slab_obsidian",
"stairs:slab_obsidian_block",
"stairs:slab_obsidian_glass",
"stairs:slab_obsidianbrick",
"stairs:slab_pine_wood",
"stairs:slab_sandstone",
"stairs:slab_sandstone_block",
"stairs:slab_sandstonebrick",
"stairs:slab_silver_sandstone",
"stairs:slab_silver_sandstone_block",
"stairs:slab_silver_sandstone_brick",
"stairs:slab_snowblock",
"stairs:slab_stone",
"stairs:slab_stone_block",
"stairs:slab_stonebrick",
"stairs:slab_straw",
"stairs:slab_wood",
"stairs:stair_acacia_wood",
"stairs:stair_aspen_wood",
"stairs:stair_brick",
"stairs:stair_cobble",
"stairs:stair_desert_cobble",
"stairs:stair_desert_sandstone",
"stairs:stair_desert_sandstone_block",
"stairs:stair_desert_sandstone_brick",
"stairs:stair_desert_stone",
"stairs:stair_desert_stone_block",
"stairs:stair_desert_stonebrick",
"stairs:stair_glass",
"stairs:stair_goldblock",
"stairs:stair_ice",
"stairs:stair_inner_acacia_wood",
"stairs:stair_inner_aspen_wood",
"stairs:stair_inner_brick",
"stairs:stair_inner_cobble",
"stairs:stair_inner_desert_cobble",
"stairs:stair_inner_desert_sandstone",
"stairs:stair_inner_desert_sandstone_block",
"stairs:stair_inner_desert_sandstone_brick",
"stairs:stair_inner_desert_stone",
"stairs:stair_inner_desert_stone_block",
"stairs:stair_inner_desert_stonebrick",
"stairs:stair_inner_glass",
"stairs:stair_inner_goldblock",
"stairs:stair_inner_ice",
"stairs:stair_inner_junglewood",
"stairs:stair_inner_mossycobble",
"stairs:stair_inner_obsidian",
"stairs:stair_inner_obsidian_block",
"stairs:stair_inner_obsidian_glass",
"stairs:stair_inner_obsidianbrick",
"stairs:stair_inner_pine_wood",
"stairs:stair_inner_sandstone",
"stairs:stair_inner_sandstone_block",
"stairs:stair_inner_sandstonebrick",
"stairs:stair_inner_silver_sandstone",
"stairs:stair_inner_silver_sandstone_block",
"stairs:stair_inner_silver_sandstone_brick",
"stairs:stair_inner_snowblock",
"stairs:stair_inner_stone",
"stairs:stair_inner_stone_block",
"stairs:stair_inner_stonebrick",
"stairs:stair_inner_straw",
"stairs:stair_inner_wood",
"stairs:stair_junglewood",
"stairs:stair_mossycobble",
"stairs:stair_obsidian",
"stairs:stair_obsidian_block",
"stairs:stair_obsidian_glass",
"stairs:stair_obsidianbrick",
"stairs:stair_outer_acacia_wood",
"stairs:stair_outer_aspen_wood",
"stairs:stair_outer_brick",
"stairs:stair_outer_cobble",
"stairs:stair_outer_desert_cobble",
"stairs:stair_outer_desert_sandstone",
"stairs:stair_outer_desert_sandstone_block",
"stairs:stair_outer_desert_sandstone_brick",
"stairs:stair_outer_desert_stone",
"stairs:stair_outer_desert_stone_block",
"stairs:stair_outer_desert_stonebrick",
"stairs:stair_outer_glass",
"stairs:stair_outer_goldblock",
"stairs:stair_outer_ice",
"stairs:stair_outer_junglewood",
"stairs:stair_outer_mossycobble",
"stairs:stair_outer_obsidian",
"stairs:stair_outer_obsidian_block",
"stairs:stair_outer_obsidian_glass",
"stairs:stair_outer_obsidianbrick",
"stairs:stair_outer_pine_wood",
"stairs:stair_outer_sandstone",
"stairs:stair_outer_sandstone_block",
"stairs:stair_outer_sandstonebrick",
"stairs:stair_outer_silver_sandstone",
"stairs:stair_outer_silver_sandstone_block",
"stairs:stair_outer_silver_sandstone_brick",
"stairs:stair_outer_snowblock",
"stairs:stair_outer_stone",
"stairs:stair_outer_stone_block",
"stairs:stair_outer_stonebrick",
"stairs:stair_outer_straw",
"stairs:stair_outer_wood",
"stairs:stair_pine_wood",
"stairs:stair_sandstone",
"stairs:stair_sandstone_block",
"stairs:stair_sandstonebrick",
"stairs:stair_silver_sandstone",
"stairs:stair_silver_sandstone_block",
"stairs:stair_silver_sandstone_brick",
"stairs:stair_snowblock",
"stairs:stair_stone",
"stairs:stair_stone_block",
"stairs:stair_stonebrick",
"stairs:stair_straw",
"stairs:stair_wood",
"xpanes:bar",
"xpanes:bar_flat",
"xpanes:door_steel_bar",
"xpanes:door_steel_bar_a",
"xpanes:door_steel_bar_b",
"xpanes:door_steel_bar_c",
"xpanes:door_steel_bar_d",
"xpanes:obsidian_pane",
"xpanes:obsidian_pane_flat",
"xpanes:pane",
"xpanes:pane_flat",
"xpanes:trapdoor_steel_bar",
"xpanes:trapdoor_steel_bar_open",
"walls:cobble",
"walls:desertcobble",
"walls:mossycobble",
})
unified_inventory.add_category_items('environment', {
"air",
"default:cave_ice",
"default:dirt_with_rainforest_litter",
"default:gravel",
"default:dry_dirt_with_dry_grass",
"default:permafrost",
"default:desert_stone",
"default:ice",
"default:dry_dirt",
"default:obsidian",
"default:sand",
"default:river_water_source",
"default:dirt_with_snow",
"default:dirt_with_grass",
"default:water_flowing",
"default:dirt",
"default:desert_sand",
"default:permafrost_with_moss",
"default:dirt_with_coniferous_litter",
"default:water_source",
"default:dirt_with_dry_grass",
"default:river_water_flowing",
"default:stone",
"default:snow",
"default:lava_flowing",
"default:lava_source",
"default:permafrost_with_stones",
"default:dirt_with_grass_footsteps",
"default:silver_sand",
"default:snowblock",
"default:clay",
"farming:desert_sand_soil",
"farming:desert_sand_soil_wet",
"farming:dry_soil",
"farming:dry_soil_wet",
"farming:soil",
"farming:soil_wet",
})
unified_inventory.add_category_items('lighting', {
"default:mese_post_light_junglewood",
"default:torch_ceiling",
"default:meselamp",
"default:torch",
"default:mese_post_light_acacia_wood",
"default:mese_post_light",
"default:torch_wall",
"default:mese_post_light_pine_wood",
"default:mese_post_light_aspen_wood"
})
--]]
--[[ UNCATEGORISED
"farming:string",
"beds:bed_bottom",
"beds:bed_top",
"beds:fancy_bed_bottom",
"beds:fancy_bed_top",
"boats:boat",
"bones:bones",
"bucket:bucket_lava",
"bucket:bucket_river_water",
"bucket:bucket_water",
"butterflies:butterfly_red",
"butterflies:butterfly_violet",
"butterflies:butterfly_white",
"butterflies:hidden_butterfly_red",
"butterflies:hidden_butterfly_violet",
"butterflies:hidden_butterfly_white",
"carts:brakerail",
"carts:cart",
"carts:powerrail",
"carts:rail",
"default:book",
"default:book_written",
"default:bookshelf",
"default:chest",
"default:chest_locked",
"default:chest_locked_open",
"default:chest_open",
"default:clay_lump",
"default:cloud",
"default:coral_brown",
"default:coral_cyan",
"default:coral_green",
"default:coral_orange",
"default:coral_pink",
"default:coral_skeleton",
"default:flint",
"default:furnace",
"default:furnace_active",
"default:key",
"default:ladder_steel",
"default:ladder_wood",
"default:obsidian_shard",
"default:paper",
"default:sign_wall_steel",
"default:sign_wall_wood",
"default:stick",
"fire:basic_flame",
"fire:permanent_flame",
"fireflies:firefly",
"fireflies:firefly_bottle",
"fireflies:hidden_firefly",
"ignore",
"unknown",
"tnt:boom",
"tnt:gunpowder",
"tnt:gunpowder_burning",
"tnt:tnt",
"tnt:tnt_burning",
"tnt:tnt_stick",
"vessels:drinking_glass",
"vessels:glass_bottle",
"vessels:glass_fragments",
"vessels:shelf",
"vessels:steel_bottle",
"dye:black",
"dye:blue",
"dye:brown",
"dye:cyan",
"dye:dark_green",
"dye:dark_grey",
"dye:green",
"dye:grey",
"dye:magenta",
"dye:orange",
"dye:pink",
"dye:red",
"dye:violet",
"dye:white",
"dye:yellow",
"wool:black",
"wool:blue",
"wool:brown",
"wool:cyan",
"wool:dark_green",
"wool:dark_grey",
"wool:green",
"wool:grey",
"wool:magenta",
"wool:orange",
"wool:pink",
"wool:red",
"wool:violet",
"wool:white",
"wool:yellow",
"unified_inventory:bag_large",
"unified_inventory:bag_medium",
"unified_inventory:bag_small",
--]]
--[[ LIST UNCATEGORIZED AFTER LOAD
minetest.register_on_mods_loaded(function()
minetest.after(1, function ( )
local l = {}
for name,_ in pairs(minetest.registered_items) do
if not unified_inventory.find_category(name) then
-- minetest.log("error", minetest.serialize(minetest.registered_items[name]))
table.insert(l, name)
end
end
table.sort(l)
minetest.log(table.concat(l, '",'.."\n"..'"'))
end)
end)
--]]

5
depends.txt Executable file
View File

@ -0,0 +1,5 @@
h2omes
creative?
intllib?
datastorage?
farming?

1
description.txt Normal file
View 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.

View File

@ -1,222 +0,0 @@
unified_inventory API
=====================
This file provides information about the API of unified_inventory
and can be viewed in Markdown readers.
API revisions within unified_inventory can be checked using:
(unified_inventory.version or 1)
**Revision history**
* Version `1`: Classic formspec layout (no real_coordinates)
* Version `2`: Force formspec version 4 (includes real_coordinates)
Misc functions
--------------
Grouped by use-case, afterwards sorted alphabetically.
* `unified_inventory.is_creative(name)`
* Checks whether creative is enabled or the player has `creative`
Callbacks
---------
Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft.
This callback is run before any recipe ingredients checks, hence it is also executed on recipes that are
purged after all mods finished loading.
unified_inventory.register_on_craft_registered(
function (item_name, options)
-- item_name (string): name of the output item, equivalent to `ItemStack:get_name()`
-- options (table): definition table of crafts registered by `unified_inventory.register_craft`
end
)
Register a callback that will be run after all mods have loaded and after the unified_inventory mod has initialised all its internal structures:
unified_inventory.register_on_initialized(callback)
-- The callback is passed no arguments
Accessing Data
--------------
These methods should be used instead of accessing the unified_inventory data structures directly - this will ensure your code survives any potential restructuring of the mod.
Get a list of recipes for a particular output item:
unified_inventory.get_recipe_list(output_item)
Returns a list of tables, each holding a recipe definition, like:
{
{
type = "normal",
items = { "default:stick", "default:stick", "default:stick", "default:stick" },
output = "default:wood",
width = 2
},
{
type = "shapeless",
items = { "default:tree" },
output = "default:wood 4",
width = 0
},
...
}
Get a list of all the output items crafts have been registered for:
unified_inventory.get_registered_outputs()
Returns a list of item names, like:
{
"default:stone",
"default:chest",
"default:brick",
"doors:door_wood",
...
}
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`
})
Categories
----------
* `unified_inventory.register_category(name, def)`
* Registers a new category
* `name` (string): internal category name
* `def` (optional, table): also its fields are optional
unified_inventory.register_category("category_name", {
symbol = source,
-- ^ Can be in the format "mod_name:item_name" or "texture.png",
label = "Human Readable Label",
index = 5,
-- ^ Categories are sorted by index. Lower numbers appear before higher ones.
-- By default, the name is translated to a number: AA -> 0.0101, ZZ -> 0.2626
--- Predefined category indices: "all" = -2, "uncategorized" = -1
items = {
"mod_name:item_name",
"another_mod:different_item"
}
-- ^ List of items within this category
})
* `unified_inventory.remove_category(name)`
* Removes an entire category
Modifier functions (to be removed)
* `unified_inventory.set_category_symbol(name, source)`
* Changes the symbol of the category. The category does not need to exist yet.
* `name` (string): internal category name
* `source` (string, optional): `"mod_name:item_name"` or `"texture.png"`.
Defaults to `"default:stick"` if not specified.
* `unified_inventory.set_category_label(name, label)`
* Changes the human readable label of the category.
* `name` (string): internal category name
* `label` (string): human readable label. Defaults to the category name.
* `unified_inventory.set_category_index(name, index)`
* Changes the sorting index of the category.
* `name` (string): internal category name
* `index` (numeric): any real number
Item management
* ` unified_inventory.add_category_item(name, itemname)`
* Adds a single item to the category
* `itemname` (string): self-explanatory
* `unified_inventory.add_category_items(name, { itemname1, itemname2, ... }`
* Same as above but with multiple items
* `unified_inventory.remove_category_item(name, itemname)`
* Removes an item from the category
* `unified_inventory.find_category(itemname)`
* Looks up the first category containing this item
* Returns: category name (string) or nil
* `unified_inventory.find_categories(itemname)`
* Looks up the item name within all registered categories
* Returns: array of category names (table)

120
group.lua Normal file → Executable file
View File

@ -1,13 +1,64 @@
local S = minetest.get_translator("unified_inventory")
local ui = unified_inventory
local S = unified_inventory.gettext
function unified_inventory.canonical_item_spec_matcher(spec)
local specname = ItemStack(spec):get_name()
if specname:sub(1, 6) == "group:" then
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
else
return function (itemname) return itemname == specname end
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
if specname:sub(1, 6) == "group:" then
local group_names = specname:sub(7):split(",")
if #group_names == 1 then
return group_names[1], 1
end
local s = ""
for g=1,#group_names do
if g > 1 then
-- List connector
s = s .. S(" and ")
end
s = s .. group_names[g]
end
return s, #group_names
else
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",
ingot = "default:steel_ingot",
}
function unified_inventory.register_group_item(groupname, itemname)
unified_inventory.registered_group_items[groupname] = itemname
end
@ -27,7 +78,6 @@ end
-- It may be a comma-separated list of group names. This is really a
-- "group:..." ingredient specification, minus the "group:" prefix.
-- TODO Replace this with the more efficient spec matcher (below)
local function compute_group_item(group_name_list)
local group_names = group_name_list:split(",")
local candidate_items = {}
@ -86,61 +136,3 @@ function unified_inventory.get_group_item(group_name)
return group_item_cache[group_name]
end
--[[
This is for filtering known items by groups
e.g. find all items that match "group:flower,yellow" (flower AND yellow groups)
]]
local spec_matcher = {}
function unified_inventory.init_matching_cache()
for _, name in ipairs(ui.items_list) do
-- we only need to care about groups, exact items are handled separately
for group, value in pairs(minetest.registered_items[name].groups) do
if value and value ~= 0 then
if not spec_matcher[group] then
spec_matcher[group] = {}
end
spec_matcher[group][name] = true
end
end
end
end
--[[
Retrieves all matching items
Arguments:
specname (string): Item name or group(s) to filter
Output:
{
matchingitem1 = true,
...
}
]]
function unified_inventory.get_matching_items(specname)
if specname:sub(1,6) ~= "group:" then
return { [specname] = true }
end
local accepted = {}
for i, group in ipairs(specname:sub(7):split(",")) do
if i == 1 then
-- First step: Copy all possible item names in this group
for name, _ in pairs(spec_matcher[group] or {}) do
accepted[name] = true
end
else
-- Perform filtering
if spec_matcher[group] then
for name, _ in pairs(accepted) do
accepted[name] = spec_matcher[group][name]
end
else
-- No matching items
return {}
end
end
end
return accepted
end

3
image_credits.txt Normal file → Executable file
View File

@ -25,9 +25,6 @@ ui_skip_backward_icon.png
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

172
init.lua Normal file → Executable file
View File

@ -1,13 +1,8 @@
-- Unified Inventory
if not minetest.features.formspec_version_element then
-- At least formspec_version[] is the minimal feature requirement
error("Unified Inventory requires Minetest version 5.4.0 or newer.\n" ..
" Please update Minetest or use an older version of Unified Inventory.")
end
-- Unified Inventory for Minetest 0.4.8+
local modpath = minetest.get_modpath(minetest.get_current_modname())
local worldpath = minetest.get_worldpath()
local mygettext = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
-- Data tables definitions
unified_inventory = {
@ -16,8 +11,6 @@ unified_inventory = {
alternate = {},
current_page = {},
current_searchbox = {},
current_category = {},
current_category_scroll = {},
current_index = {},
current_item = {},
current_craft_direction = {},
@ -30,8 +23,7 @@ unified_inventory = {
filtered_items_list = {},
pages = {},
buttons = {},
initialized_callbacks = {},
craft_registered_callbacks = {},
hidden_guide = {}, --MFF crabman(29/11/2015) hide guide, textfield bug
-- Homepos stuff
home_pos = {},
@ -40,133 +32,24 @@ unified_inventory = {
-- Default inventory page
default = "craft",
-- intllib
gettext = mygettext,
fgettext = function(s) return minetest.formspec_escape(mygettext(s)) end,
-- "Lite" mode
lite_mode = minetest.settings:get_bool("unified_inventory_lite"),
lite_mode = minetest.setting_getbool("unified_inventory_lite"),
-- Items automatically added to categories based on item definitions
automatic_categorization = (minetest.settings:get_bool("unified_inventory_automatic_categorization") ~= false),
-- Trash enabled
trash_enabled = (minetest.settings:get_bool("unified_inventory_trash") ~= false),
imgscale = 1.25,
list_img_offset = 0.13,
standard_background = "bgcolor[#0000]background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]",
hide_disabled_buttons = minetest.settings:get_bool("unified_inventory_hide_disabled_buttons", false),
hide_uncraftable_items = minetest.settings:get_bool("unified_inventory_hide_uncraftable_items", false),
version = 5
}
local ui = unified_inventory
-- These tables establish position and layout for the two UI styles.
-- UI doesn't use formspec_[xy] anymore, but other mods may need them.
ui.style_full = {
formspec_x = 1,
formspec_y = 1,
formw = 17.75,
formh = 12.25,
-- Item browser size, pos
pagecols = 8,
pagerows = 9,
page_x = 10.75,
page_y = 2.30,
-- Item browser controls
page_buttons_x = 11.60,
page_buttons_y = 10.15,
searchwidth = 3.4,
-- Crafting grid positions
craft_x = 2.8,
craft_y = 1.15,
craftresult_x = 7.8,
craft_arrow_x = 6.55,
craft_guide_x = 3.3,
craft_guide_y = 1.15,
craft_guide_arrow_x = 7.05,
craft_guide_result_x = 8.3,
craft_guide_resultstr_x = 0.3,
craft_guide_resultstr_y = 0.6,
give_btn_x = 0.25,
-- Tab switching buttons
main_button_x = 0.4,
main_button_y = 11.0,
main_button_cols = 12,
main_button_rows = 1,
-- Tab title position
form_header_x = 0.4,
form_header_y = 0.4,
-- Generic sizes
btn_spc = 0.85,
btn_size = 0.75,
std_inv_x = 0.3,
std_inv_y = 5.75,
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
}
ui.style_lite = {
formspec_x = 0.6,
formspec_y = 0.6,
formw = 14,
formh = 9.75,
-- Item browser size, pos
pagecols = 4,
pagerows = 5,
page_x = 10.5,
page_y = 2.15,
-- Item browser controls
page_buttons_x = 10.5,
page_buttons_y = 6.15,
searchwidth = 1.6,
-- Crafting grid positions
craft_x = 2.6,
craft_y = 0.75,
craftresult_x = 5.75,
craft_arrow_x = 6.35,
craft_guide_x = 3.1,
craft_guide_y = 0.75,
craft_guide_arrow_x = 7.05,
craft_guide_result_x = 8.3,
craft_guide_resultstr_x = 0.15,
craft_guide_resultstr_y = 0.35,
give_btn_x = 0.15,
-- Tab switching buttons
main_button_x = 10.5,
main_button_y = 8.15,
main_button_cols = 4,
main_button_rows = 2,
-- Tab title position
form_header_x = 0.2,
form_header_y = 0.2,
-- Generic sizes
btn_spc = 0.8,
btn_size = 0.7,
std_inv_x = 0.1,
std_inv_y = 4.6,
}
dofile(modpath.."/api.lua")
for _, style in ipairs({ui.style_full, ui.style_lite}) do
style.items_per_page = style.pagecols * style.pagerows
style.standard_inv = string.format("list[current_player;main;%f,%f;8,4;]",
style.std_inv_x + ui.list_img_offset, style.std_inv_y + ui.list_img_offset)
style.standard_inv_bg = ui.make_inv_img_grid(style.std_inv_x, style.std_inv_y, 8, 1, true)..
ui.make_inv_img_grid(style.std_inv_x, style.std_inv_y + ui.imgscale, 8, 3)
style.craft_grid = table.concat({
ui.make_inv_img_grid(style.craft_x, style.craft_y, 3, 3),
ui.single_slot(style.craft_x + ui.imgscale*4, style.craft_y), -- the craft result slot
string.format("image[%f,%f;%f,%f;ui_crafting_arrow.png]",
style.craft_arrow_x, style.craft_y, ui.imgscale, ui.imgscale),
string.format("list[current_player;craft;%f,%f;3,3;]",
style.craft_x + ui.list_img_offset, style.craft_y + ui.list_img_offset),
string.format("list[current_player;craftpreview;%f,%f;1,1;]",
style.craftresult_x + ui.list_img_offset, style.craft_y + ui.list_img_offset)
})
end
-- Disable default creative inventory
local creative = rawget(_G, "creative") or rawget(_G, "creative_inventory")
if creative then
@ -175,27 +58,16 @@ if creative then
end
end
-- Disable sfinv inventory
local sfinv = rawget(_G, "sfinv")
if sfinv then
sfinv.enabled = false
end
dofile(modpath.."/group.lua")
dofile(modpath.."/category.lua")
dofile(modpath.."/default-categories.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
if minetest.settings:get_bool("unified_inventory_item_names") ~= false then
dofile(modpath.."/item_names.lua")
end
if minetest.settings:get_bool("unified_inventory_waypoints") ~= false then
dofile(modpath.."/item_names.lua")
if minetest.get_modpath("datastorage") then
dofile(modpath.."/waypoints.lua")
end
dofile(modpath.."/legacy.lua") -- mod compatibility

668
internal.lua Normal file → Executable file
View File

@ -1,6 +1,5 @@
local S = minetest.get_translator("unified_inventory")
local F = minetest.formspec_escape
local ui = unified_inventory
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
-- This pair of encoding functions is used where variable text must go in
-- button names, where the text might contain formspec metacharacters.
@ -10,364 +9,279 @@ local ui = unified_inventory
-- 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 ui.mangle_for_formspec(str)
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 ui.demangle_for_formspec(str)
function unified_inventory.demangle_for_formspec(str)
return string.gsub(str, "_([0-9]+)_", function (v) return string.char(v) end)
end
-- Get the player-specific unified_inventory style
function ui.get_per_player_formspec(player_name)
local draw_lite_mode = ui.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true})
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 style = table.copy(draw_lite_mode and ui.style_lite or ui.style_full)
style.is_lite_mode = draw_lite_mode
return style
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
-- Creates an item image or regular image button with a tooltip
local function formspec_button(ui_peruser, name, image, offset, pos, scale, label)
local element = 'image_button'
if minetest.registered_items[image] then
element = 'item_image_button'
elseif image:find(":", 1, true) then
image = "unknown_item.png"
end
local spc = (1-scale)*ui_peruser.btn_size/2
local size = ui_peruser.btn_size*scale
return string.format("%s[%f,%f;%f,%f;%s;%s;]", element,
(offset.x or offset[1]) + ( ui_peruser.btn_spc * (pos.x or pos[1]) ) + spc,
(offset.y or offset[2]) + ( ui_peruser.btn_spc * (pos.y or pos[2]) ) + spc,
size, size, image, name) ..
string.format("tooltip[%s;%s]", name, F(label or name))
end
-- Add registered buttons (tabs)
local function formspec_tab_buttons(player, formspec, style)
local n = #formspec + 1
-- Main buttons
local filtered_inv_buttons = {}
for _, def in pairs(ui.buttons) do
if not (style.is_lite_mode and def.hide_lite) then
if def.condition == nil or def.condition(player) or not ui.hide_disabled_buttons then
table.insert(filtered_inv_buttons, def)
end
end
end
local needs_scrollbar = #filtered_inv_buttons > style.main_button_cols * style.main_button_rows
formspec[n] = ("scroll_container[%g,%g;%g,%g;tabbtnscroll;vertical]"):format(
style.main_button_x, style.main_button_y, -- position
style.main_button_cols * style.btn_spc, style.main_button_rows -- size
)
n = n + 1
for i, def in pairs(filtered_inv_buttons) do
local pos_x = ((i - 1) % style.main_button_cols) * style.btn_spc
local pos_y = math.floor((i - 1) / style.main_button_cols) * style.btn_spc
if def.type == "image" then
if (def.condition == nil or def.condition(player)) then
formspec[n] = string.format("image_button[%g,%g;%g,%g;%s;%s;]",
pos_x, pos_y, style.btn_size, style.btn_size,
F(def.image),
F(def.name))
formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]"
n = n+2
else
formspec[n] = string.format("image[%g,%g;%g,%g;%s^[colorize:#808080:alpha]",
pos_x, pos_y, style.btn_size, style.btn_size,
def.image)
n = n+1
end
end
end
formspec[n] = "scroll_container_end[]"
if needs_scrollbar then
local total_rows = math.ceil(#filtered_inv_buttons / style.main_button_cols)
formspec[n+1] = ("scrollbaroptions[max=%i;arrows=hide]"):format(
-- This calculation is not 100% accurate but "good enough"
(total_rows - style.main_button_rows) * style.btn_spc * 10
)
formspec[n+2] = ("scrollbar[%g,%g;0.4,%g;vertical;tabbtnscroll;0]"):format(
style.main_button_x + style.main_button_cols * style.btn_spc - 0.1, -- x pos
style.main_button_y, -- y pos
style.main_button_rows * style.btn_spc -- height
)
formspec[n+3] = "scrollbaroptions[max=1000;arrows=default]"
end
end
-- Add category GUI elements (top right)
local function formspec_add_categories(player, formspec, ui_peruser)
local player_name = player:get_player_name()
local n = #formspec + 1
local categories_pos = {
ui_peruser.page_x,
ui_peruser.page_y-ui_peruser.btn_spc-0.5
}
local categories_scroll_pos = {
ui_peruser.page_x,
ui_peruser.form_header_y - (ui_peruser.is_lite_mode and 0 or 0.2)
}
formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;16]",
ui_peruser.page_x-0.15, categories_scroll_pos[2],
(ui_peruser.btn_spc * ui_peruser.pagecols) + 0.2, 1.4 + (ui_peruser.is_lite_mode and 0 or 0.2),
"ui_smallbg_9_sliced.png")
n = n + 1
formspec[n] = string.format("label[%f,%f;%s]",
ui_peruser.page_x,
ui_peruser.form_header_y + (ui_peruser.is_lite_mode and 0.3 or 0.2), F(S("Category:")))
n = n + 1
local scroll_offset = 0
local category_count = #ui.category_list
if category_count > ui_peruser.pagecols then
scroll_offset = ui.current_category_scroll[player_name]
end
for index, category in ipairs(ui.category_list) do
local column = index - scroll_offset
if column > 0 and column <= ui_peruser.pagecols then
local scale = 0.8
if ui.current_category[player_name] == category.name then
scale = 1
end
formspec[n] = formspec_button(ui_peruser, "category_"..category.name, category.symbol, categories_pos, {column-1, 0}, scale, category.label)
n = n + 1
end
end
if category_count > ui_peruser.pagecols and scroll_offset > 0 then
-- prev
formspec[n] = formspec_button(ui_peruser, "prev_category", "ui_left_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 2, 0}, 0.8, S("Scroll categories left"))
n = n + 1
end
if category_count > ui_peruser.pagecols and category_count - scroll_offset > ui_peruser.pagecols then
-- next
formspec[n] = formspec_button(ui_peruser, "next_category", "ui_right_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 1, 0}, 0.8, S("Scroll categories right"))
end
end
local function formspec_add_search_box(player, formspec, ui_peruser)
local player_name = player:get_player_name()
local n = #formspec + 1
formspec[n] = "field_close_on_enter[searchbox;false]"
formspec[n+1] = string.format("field[%f,%f;%f,%f;searchbox;;%s]",
ui_peruser.page_buttons_x, ui_peruser.page_buttons_y,
ui_peruser.searchwidth - 0.1, ui_peruser.btn_size,
F(ui.current_searchbox[player_name]))
formspec[n+2] = string.format("image_button[%f,%f;%f,%f;ui_search_icon.png;searchbutton;]",
ui_peruser.page_buttons_x + ui_peruser.searchwidth, ui_peruser.page_buttons_y,
ui_peruser.btn_size,ui_peruser.btn_size)
formspec[n+3] = "tooltip[searchbutton;" ..F(S("Search")) .. "]"
formspec[n+4] = string.format("image_button[%f,%f;%f,%f;ui_reset_icon.png;searchresetbutton;]",
ui_peruser.page_buttons_x + ui_peruser.searchwidth + ui_peruser.btn_spc,
ui_peruser.page_buttons_y,
ui_peruser.btn_size, ui_peruser.btn_size)
formspec[n+5] = "tooltip[searchresetbutton;"..F(S("Reset search and display everything")).."]"
if ui.activefilter[player_name] ~= "" then
formspec[n+6] = string.format("label[%f,%f;%s: %s]",
ui_peruser.page_x, ui_peruser.page_y - 0.25,
F(S("Filter")), F(ui.activefilter[player_name]))
end
end
local function formspec_add_item_browser(player, formspec, ui_peruser)
local player_name = player:get_player_name()
local n = #formspec + 1
-- Controls to flip items pages
local btnlist = {
{ "ui_skip_backward_icon.png", "start_list", S("First page") },
{ "ui_doubleleft_icon.png", "rewind3", S("Back three pages") },
{ "ui_left_icon.png", "rewind1", S("Back one page") },
{ "ui_right_icon.png", "forward1", S("Forward one page") },
{ "ui_doubleright_icon.png", "forward3", S("Forward three pages") },
{ "ui_skip_forward_icon.png", "end_list", S("Last page") },
}
if ui_peruser.is_lite_mode then
btnlist[2] = nil
btnlist[5] = nil
end
local bn = 0
for _, b in pairs(btnlist) do
formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]",
ui_peruser.page_buttons_x + ui_peruser.btn_spc*bn,
ui_peruser.page_buttons_y + ui_peruser.btn_spc,
ui_peruser.btn_size, ui_peruser.btn_size,
b[1],b[2])
formspec[n+1] = "tooltip["..b[2]..";"..F(b[3]).."]"
bn = bn + 1
n = n + 2
end
-- Items list
if #ui.filtered_items_list[player_name] == 0 then
local no_matches = S("No matching items")
if ui_peruser.is_lite_mode then
no_matches = S("No matches.")
end
formspec[n] = "label["..ui_peruser.page_x..","..(ui_peruser.page_y+0.15)..";" .. F(no_matches) .. "]"
return
end
local dir = ui.active_search_direction[player_name]
local list_index = ui.current_index[player_name]
local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1)
local pagemax = math.floor(
(#ui.filtered_items_list[player_name] - 1)
/ (ui_peruser.items_per_page) + 1)
for y = 0, ui_peruser.pagerows - 1 do
for x = 0, ui_peruser.pagecols - 1 do
local name = ui.filtered_items_list[player_name][list_index]
local item = minetest.registered_items[name]
if item then
-- Clicked on current item: Flip crafting direction
if name == ui.current_item[player_name] then
local cdir = ui.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 = ui.active_search_direction[player_name]
end
local button_name = "item_button_" .. dir .. "_"
.. ui.mangle_for_formspec(name)
formspec[n] = ("item_image_button[%f,%f;%f,%f;%s;%s;]"):format(
ui_peruser.page_x + x * ui_peruser.btn_spc,
ui_peruser.page_y + y * ui_peruser.btn_spc,
ui_peruser.btn_size, ui_peruser.btn_size,
name, button_name
)
local tooltip = item.description
if item.mod_origin then
-- "mod_origin" may not be specified for items that were
-- registered in a callback (during or before ServerEnv init)
tooltip = tooltip .. " [" .. item.mod_origin .. "]"
end
formspec[n + 1] = ("tooltip[%s;%s]"):format(
button_name, minetest.formspec_escape(tooltip)
)
n = n + 2
end
list_index = list_index + 1
end
end
formspec[n] = "style[page_number;content_offset=0]"
formspec[n + 1] = string.format("image_button[%f,%f;%f,0.4;;page_number;%s: %s;false;false;]",
ui_peruser.page_buttons_x,
ui_peruser.page_buttons_y + ui_peruser.btn_spc * 2 - 0.1,
ui_peruser.btn_spc * (bn - 1) + ui_peruser.btn_size,
F(S("Page")), S("@1 of @2",page2,pagemax))
end
function ui.get_formspec(player, page)
function unified_inventory.get_formspec(player, page)
if not player then
return ""
end
local player_name = player:get_player_name()
local ui_peruser = ui.get_per_player_formspec(player_name)
local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
ui.current_page[player_name] = page
local pagedef = ui.pages[page]
unified_inventory.current_page[player_name] = page
local pagedef = unified_inventory.pages[page]
if not pagedef then
local formspec = {
"size[14,10]",
"background[-0.19,-0.25;14.4,10.75;ui_form_bg.png]" -- Background
}
local n = 3
if draw_lite_mode then
formspec[1] = "size[11,7.7]"
formspec[2] = "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
-- Current page
if not unified_inventory.pages[page] then
return "" -- Invalid page name
end
local fs = {
"formspec_version[4]",
"size["..ui_peruser.formw..","..ui_peruser.formh.."]",
pagedef.formspec_prepend and "" or "no_prepend[]",
ui.standard_background
}
local perplayer_formspec = ui.get_per_player_formspec(player_name)
local perplayer_formspec = unified_inventory.get_per_player_formspec(player_name)
local fsdata = pagedef.get_formspec(player, perplayer_formspec)
fs[#fs + 1] = fsdata.formspec
formspec[n] = fsdata.formspec
n = n+1
formspec_tab_buttons(player, fs, ui_peruser)
local privs = minetest.get_player_privs(player_name) --Modif MFF (Crabman 13/10/2015) not show if player has not privs requiered
local button_row = 0
local button_col = 0
-- Main buttons
local filtered_inv_buttons = {}
for i, def in pairs(unified_inventory.buttons) do
if not (draw_lite_mode and def.hide_lite) and (not def.show_with or (privs[def.show_with] and privs[def.show_with] == true)) then --Modif MFF (Crabman 13/10/2015) not show if player has not privs requiered
table.insert(filtered_inv_buttons, def)
end
end
local i = 1 --Modif MFF (Crabman 13/10/2015) 12 buttons max by row
for _, def in pairs(filtered_inv_buttons) do --Modif MFF (Crabman 13/10/2015)
if draw_lite_mode and i > 4 then
button_row = 1
button_col = 1
elseif not draw_lite_mode and i > 12 then --Modif MFF (Crabman 13/10/2015)
button_row = 1
i = 1
end
if def.type == "image" then
formspec[n] = "image_button["
formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4)
formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;"
formspec[n+3] = minetest.formspec_escape(def.image)..";"
formspec[n+4] = minetest.formspec_escape(def.name)..";]"
formspec[n+5] = "tooltip["..minetest.formspec_escape(def.name)
formspec[n+6] = ";"..(def.tooltip or "").."]"
n = n+7
end
i = i + 1 --Modif MFF (Crabman 13/10/2015)
end
if fsdata.draw_inventory ~= false then
-- Player inventory
fs[#fs + 1] = "listcolors[#00000000;#00000000]"
fs[#fs + 1] = ui_peruser.standard_inv
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 table.concat(fs, "")
return table.concat(formspec, "")
end
formspec_add_categories(player, fs, ui_peruser)
formspec_add_search_box(player, fs, ui_peruser)
formspec_add_item_browser(player, fs, ui_peruser)
if not unified_inventory.hidden_guide[player_name] then --MFF crabman(29/11/2015) hide guide, textfield bug
formspec[n] = "image_button[13.2,0.1;.8,.8;ui_on_icon.png;hidebutton;]"
.. "tooltip[hidebutton;" ..F("Hide guide") .. "]"
n = n+1
else
formspec[n] = "image_button[13.2,0.1;.8,.8;ui_off_icon.png;hidebutton;]"
.. "tooltip[hidebutton;" ..F("Show guide") .. "]"
return table.concat(formspec, "")
end
return table.concat(fs)
-- Controls to flip items pages
local start_x = 9.2
if not draw_lite_mode then
formspec[n] =
"image_button[" .. (start_x + 0.6 * 0)
.. ",9;.8,.8;ui_skip_backward_icon.png;start_list;]"
.. "tooltip[start_list;" .. F("First page") .. "]"
.. "image_button[" .. (start_x + 0.6 * 1)
.. ",9;.8,.8;ui_doubleleft_icon.png;rewind3;]"
.. "tooltip[rewind3;" .. F("Back three pages") .. "]"
.. "image_button[" .. (start_x + 0.6 * 2)
.. ",9;.8,.8;ui_left_icon.png;rewind1;]"
.. "tooltip[rewind1;" .. F("Back one page") .. "]"
.. "image_button[" .. (start_x + 0.6 * 3)
.. ",9;.8,.8;ui_right_icon.png;forward1;]"
.. "tooltip[forward1;" .. F("Forward one page") .. "]"
.. "image_button[" .. (start_x + 0.6 * 4)
.. ",9;.8,.8;ui_doubleright_icon.png;forward3;]"
.. "tooltip[forward3;" .. F("Forward three pages") .. "]"
.. "image_button[" .. (start_x + 0.6 * 5)
.. ",9;.8,.8;ui_skip_forward_icon.png;end_list;]"
.. "tooltip[end_list;" .. F("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("First page") .. "]"
.. "image_button[" .. (8.2 + 0.65 * 1)
.. ",5.8;.8,.8;ui_left_icon.png;rewind1;]"
.. "tooltip[rewind1;" .. F("Back one page") .. "]"
.. "image_button[" .. (8.2 + 0.65 * 2)
.. ",5.8;.8,.8;ui_right_icon.png;forward1;]"
.. "tooltip[forward1;" .. F("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("Last page") .. "]"
end
n = n+1
-- Search box
formspec[n] = "field_close_on_enter[searchbox;false]"
n = n+1
if not draw_lite_mode then
formspec[n] = "field[9.5,8.325;3,1;searchbox;;"
.. minetest.formspec_escape(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("Search") .. "]"
formspec[n+2] = "image_button[12.9,8.1;.8,.8;ui_reset_icon.png;searchresetbutton;]"
.. "tooltip[searchbutton;" ..F("Search") .. "]"
.. "tooltip[searchresetbutton;" ..F("Reset search and display everything") .. "]"
else
formspec[n] = "field[8.5,5.225;2.2,1;searchbox;;"
.. minetest.formspec_escape(unified_inventory.current_searchbox[player_name]) .. "]"
formspec[n+1] = "image_button[10.3,5;.8,.8;ui_search_icon.png;searchbutton;]"
.. "tooltip[searchbutton;" ..F("Search") .. "]"
formspec[n+2] = "image_button[11,5;.8,.8;ui_reset_icon.png;searchresetbutton;]"
.. "tooltip[searchbutton;" ..F("Search") .. "]"
.. "tooltip[searchresetbutton;" ..F("Reset search and display everything") .. "]"
end
n = n+3
local no_matches = "No matching items"
if draw_lite_mode then
no_matches = "No matches."
end
-- Items list
if #unified_inventory.filtered_items_list[player_name] == 0 then
formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";" .. F(no_matches) .. "]"
else
local dir = unified_inventory.active_search_direction[player_name]
local list_index = unified_inventory.current_index[player_name]
local page = 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)
local item = {}
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]
if minetest.registered_items[name] 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
formspec[n] = "item_image_button["
..(8.2 + x * 0.7)..","
..(ui_peruser.formspec_y + ui_peruser.page_y + y * 0.7)..";.81,.81;"
..name..";item_button_"..dir.."_"
..unified_inventory.mangle_for_formspec(name)..";]"
n = n+1
list_index = list_index + 1
end
end
end
formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";"..F("Page") .. ": "
.. S("%s of %s"):format(page,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("Filter") .. ":]"
formspec[n+1] = "label[9.1,"..(ui_peruser.form_header_y + 0.4)..";"..minetest.formspec_escape(unified_inventory.activefilter[player_name]).."]"
end
return table.concat(formspec, "")
end
function ui.set_inventory_formspec(player, page)
function unified_inventory.set_inventory_formspec(player, page)
if player then
player:set_inventory_formspec(ui.get_formspec(player, page))
player:set_inventory_formspec(unified_inventory.get_formspec(player, page))
end
end
function ui.is_itemdef_listable(def)
return (not def.groups.not_in_creative_inventory
or def.groups.not_in_creative_inventory == 0)
and def.description
and def.description ~= ""
end
--apply filter to the inventory list (create filtered copy of full one)
function ui.apply_filter(player, filter, search_dir)
function unified_inventory.apply_filter(player, filter, search_dir)
if not player then
return false
end
local player_name = player:get_player_name()
-- Whether to show uncraftable items
local fprefilter = function(_)
return true
end
if ui.hide_uncraftable_items and not ui.is_creative(player_name) then
fprefilter = function(name)
return ui.get_recipe_list(name)
end
end
local registered_items = minetest.registered_items
local lfilter = string.lower(filter)
local ffilter
if lfilter:sub(1, 6) == "group:" then
-- Group filter: all groups of the item must match
local groups = lfilter:sub(7):split(",")
ffilter = function(name)
local def = registered_items[name]
ffilter = function(name, def)
for _, group in ipairs(groups) do
if not def.groups[group]
or def.groups[group] <= 0 then
@ -377,64 +291,86 @@ function ui.apply_filter(player, filter, search_dir)
return true
end
else
-- Name filter: fuzzy match item names and descriptions
local player_info = minetest.get_player_information(player_name)
local lang = player_info and player_info.lang_code or ""
ffilter = function(name)
local def = registered_items[name]
ffilter = function(name, def)
local lname = string.lower(name)
local ldesc = string.lower(def.description)
local llocaldesc = minetest.get_translated_string
and string.lower(minetest.get_translated_string(lang, def.description))
return string.find(lname, lfilter, 1, true) or string.find(ldesc, lfilter, 1, true)
or llocaldesc and string.find(llocaldesc, lfilter, 1, true)
end
end
local filtered_items = {}
local category = ui.current_category[player_name] or 'all'
if category == 'all' then
for _, name in ipairs(ui.items_list) do
if fprefilter(name) and ffilter(name) then
table.insert(filtered_items, name)
end
end
elseif category == 'uncategorized' then
for _, name in ipairs(ui.items_list) do
if not ui.find_category(name)
and fprefilter(name)
and ffilter(name) then
table.insert(filtered_items, name)
end
end
else
-- Any other category is selected
for name, exists in pairs(ui.registered_category_items[category]) do
if exists
and fprefilter(name)
and ffilter(name) then
table.insert(filtered_items, name)
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)
and (unified_inventory.is_creative(player_name)
or unified_inventory.crafts_for.recipe[def.name]) then
table.insert(unified_inventory.filtered_items_list[player_name], name)
end
end
table.sort(filtered_items)
ui.filtered_items_list_size[player_name] = #filtered_items
ui.filtered_items_list[player_name] = filtered_items
ui.current_index[player_name] = 1
ui.activefilter[player_name] = filter
ui.active_search_direction[player_name] = search_dir
ui.set_inventory_formspec(player, ui.current_page[player_name])
table.sort(unified_inventory.filtered_items_list[player_name])
unified_inventory.filtered_items_list_size[player_name] = #unified_inventory.filtered_items_list[player_name]
unified_inventory.current_index[player_name] = 1
unified_inventory.activefilter[player_name] = filter
unified_inventory.active_search_direction[player_name] = search_dir
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
end
-- Inform players about potential visual issues
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
local info = minetest.get_player_information(player_name)
if info and (info.formspec_version or 0) < 4 then
minetest.chat_send_player(player_name, S("Unified Inventory: Your game version is too old"
.. " and does not support the GUI requirements. You might experience visual issues."))
function unified_inventory.items_in_group(groups)
local items = {}
for name, item in pairs(minetest.registered_items) do
for _, group in pairs(groups:split(',')) do
if item.groups[group] then
table.insert(items, name)
end
end
end
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

93
item_names.lua Normal file → Executable file
View File

@ -1,86 +1,55 @@
-- Based on 4itemnames mod by 4aiman
local item_names = {} -- [player_name] = { hud, dtime, itemname }
local wield = {}
local huds = {}
local dtimes = {}
local dlimit = 3 -- HUD element will be hidden after this many seconds
local air_hud_mod = minetest.get_modpath("4air")
local hud_mod = minetest.get_modpath("hud")
local hudbars_mod = minetest.get_modpath("hudbars")
local only_names = minetest.settings:get_bool("unified_inventory_only_names", true)
local max_length = tonumber(minetest.settings:get("unified_inventory_max_item_name_length")) or 80
local function set_hud(player)
local player_name = player:get_player_name()
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
local off = {x=0, y=-70}
if air_hud_mod or hud_mod then
off.y = off.y - 20
elseif hudbars_mod then
off.y = off.y + 5
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 = ""
}
huds[player_name] = player:hud_add({
hud_elem_type = "text",
position = {x=0.5, y=1},
offset = off,
alignment = {x=0, y=0},
number = 0xFFFFFF ,
text = "",
})
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 player_name = player:get_player_name()
local wstack = player:get_wielded_item():get_name()
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', "")
if dtimes[player_name] and dtimes[player_name] < dlimit then
dtimes[player_name] = dtimes[player_name] + dtime
if dtimes[player_name] > dlimit and huds[player_name] then
player:hud_change(huds[player_name], '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 lang_code = minetest.get_player_information(player:get_player_name()).lang_code
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 ""
if wstack ~= wield[player_name] then
wield[player_name] = wstack
dtimes[player_name] = 0
if huds[player_name] then
local def = minetest.registered_items[wstack]
local desc = def and def.description or ""
player:hud_change(huds[player_name], 'text', desc)
end
if only_names and desc and string.find(desc, "\n") then
desc = string.match(desc, "([^\n]*)")
end
desc = minetest.get_translated_string(lang_code, desc)
desc = minetest.strip_colors(desc)
if string.len(desc) > max_length and max_length > 0 then
desc = string.sub(desc, 1, max_length) .. " [...]"
end
player:hud_change(data.hud, 'text', desc)
end
end
end)

View File

@ -1,55 +0,0 @@
-- Inefficient pattern matching
local warned_funcs = {}
local function LOG_ONCE(funcname)
if warned_funcs[funcname] then return end
warned_funcs[funcname] = true
minetest.log("error", "Call to undocumented, deprecated API '" .. funcname .. "'."
.. " In a future version of Unified Inventory this will result in a real error.")
end
function unified_inventory.canonical_item_spec_matcher(spec)
LOG_ONCE("canonical_item_spec_matcher")
local specname = ItemStack(spec):get_name()
if specname:sub(1, 6) ~= "group:" then
return function (itemname)
return itemname == specname
end
end
local group_names = specname:sub(7):split(",")
return function (itemname)
local itemdef = minetest.registered_items[itemname]
for _, group_name in ipairs(group_names) do
if (itemdef.groups[group_name] or 0) == 0 then
return false
end
end
return true
end
end
function unified_inventory.item_matches_spec(item, spec)
LOG_ONCE("item_matches_spec")
local itemname = ItemStack(item):get_name()
return unified_inventory.canonical_item_spec_matcher(spec)(itemname)
end
unified_inventory.registered_group_items = {
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
stone = "default:cobble",
wood = "default:wood",
book = "default:book",
sand = "default:sand",
leaves = "default:leaves",
tree = "default:tree",
vessel = "vessels:glass_bottle",
wool = "wool:white",
}
function unified_inventory.register_group_item(groupname, itemname)
LOG_ONCE("register_group_item")
unified_inventory.registered_group_items[groupname] = itemname
end

101
locale/de.txt Executable file
View File

@ -0,0 +1,101 @@
# Translation mostly by Xanthin
### api.lua ###
Digging (by chance) = Graben (durch Zufall)
### bags.lua ###
Bags = Taschen
Bag 1 = Tasche 1
Bag 2 = Tasche 2
Bag 3 = Tasche 3
Bag 4 = Tasche 4
Small Bag = Kleine Tasche
Medium Bag = Mittelgroße Tasche
Large Bag = Große Tasche
### inernal.lua ###
First page = Erste Seite
Back three pages = Drei Seiten zurueckblättern
Back one page = Eine Seite zurueckblättern
Forward one page = Eine Seite vorblättern
Forward three pages = Drei Seiten vorblättern
Last page = Letzte Seite
No matching items = Keine passenden Gegenstände
Page = Seite
%s of %s = %s von %s
Filter = Filter
Search = Suchen
Reset search and display everything = Suche zurücksetzen und alles anzeigen
### register.lua ###
Can use the creative inventory = Kann das Kreativinventar nutzen
Home position set to: %s = Heimatposition nach: %s gesetzt
Time of day set to 6am = Tageszeit auf 6 Uhr geändert
You don't have the settime privilege! = Du hast nicht das „settime“-Privileg!
Time of day set to 9pm = Tageszeit auf 21 Uhr geändert
This button has been disabled outside of creative mode to prevent accidental inventory trashing. Use the trash slot instead. = Diese Funktion ist außerhalb des Kreativmodus deaktiviert, um ein versehentliches Löschen des ganzen Inventars zu verhindern.\nNutze stattdessen das Müllfeld.
Inventory cleared! = Inventar geleert!
Crafting = Fertigung
Digging = Graben
Cooking = Kochen
Mixing = Mischen
Trash: = Müll:
Refill: = Nachfüllen:
Crafting Guide = Fertigungsführer
Method: = Methode:
Result: %s = Ergebnis: %s
crafting = Bauen
shapeless crafting = Formlose Fertigung
cooking = Kochen
alloy cooking = Legierung Kochen
Copy to craft grid: = Ins Fertigungsraster kopieren:
All = Alles
Alternate = Alternative
Crafting Grid = Fertigungsraster
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
This recipe is too\nlarge to be displayed. = Dieses Rezept ist zu\ngroß, um angezeigt\nzu werden.
Any item belonging to the %s group = Irgendein Gegenstand, der zur Gruppe %s gehört
Any item belonging to the groups %s = Irgendein Gegenstand, der zu den Gruppen %s gehört
Recipe %d of %d = Rezept %d von %d
Usage %d of %d = Verwendung %d von %d
No recipes = Keine Rezepte
No usages = Keine Verwendungen
Result = Ergebnis
Ingredient = Zutat
Set time to day = Zur Tageszeit wechseln
Set time to night = Zur Nachtzeit wechseln
Set home position = Heimatposition setzen
Go home = Nach Hause gehen
Clear inventory = Inventar leeren
Give me: = Gib mir:
To craft grid: = Ins Fertigungsraster:
### group.lua ###
\sand\s=\sund\s
### waypoints.lua ###
White = Weiß
Yellow = Gelb
Red = Rot
Green = Grün
Blue = Blau
Waypoints = Wegpunkte
Waypoint %d = Wegpunkt Nr. %d
Waypoint active = Wegpunkt aktiv
Waypoint inactive = Wegpunkt inaktiv
World position = Weltposition
Name = Name
HUD text color = HUD-Textfarbe
Edit waypoint name = Name des Wegpunkts ändern
Rename waypoint = Wegpunkt umbenennen
Change color of waypoint display = Farbe der Darstellung der Wegpunkte ändern
Set waypoint to current location = Setze Wegpunkt zur derzeitigen Position
Make waypoint visible = Wegpunkt sichtbar machen
Make waypoint invisible = Wegpunkt verstecken
Disable display of waypoint coordinates = Anzeige der Wegpunktkoordinaten deaktivieren
Enable display of waypoint coordinates = Anzeige der Wegpunktkoordinaten aktivieren
Finish editing = Bearbeitung abschließen
Select Waypoint #%d = Wegpunkt Nr. %d auswählen

72
locale/es.txt Executable file
View File

@ -0,0 +1,72 @@
# Translation by Diego Martínez <kaeza>
# Template
### bags.lua ###
Bags = Bolsas
Bag 1 = Bolsa 1
Bag 2 = Bolsa 2
Bag 3 = Bolsa 3
Bag 4 = Bolsa 4
Small Bag = Bolsa Pequeña
Medium Bag = Bolsa Mediana
Large Bag = Bolsa Grande
### inernal.lua ###
First page =
Back three pages =
Back one page =
Forward one page =
Forward three pages =
Last page =
No matching items =
Page = Página
%s of %s = %s de %s
Filter = Filtro
Search =
### register.lua ###
Can use the creative inventory = Puede usar el inventario creativo
Home position set to: %s = Posición de hogar cambiada a: %s
Time of day set to 6am = Hora del día cambiada a 6AM
You don't have the settime priviledge! = ¡No tienes el privilegio `settime'!
Time of day set to 9pm = Hora del día cambiada a 9PM
This button has been disabled outside of creative mode to prevent accidental inventory trashing. Use the trash slot instead. = Éste botón ha sido deshabilitado para prevenir la destrucción accidental del inventario.\nUsa la ranura para basura en su lugar.
Inventory cleared! = ¡Inventario limpio!
Crafting = Elaboración
Trash: = Basura:
Refill: = Rellenar:
Crafting Guide = Guía de Elaboración
Method: = Método:
Result: %s = Resultado: %s
crafting = elaboración
shapeless crafting = elaboración sin forma
cooking = hornear
alloy cooking = horneado de aleación
Copy to craft grid: = Copiar al cuadro de elaboración
All = Todos
Recipe %s of %s = Receta %s de %s
Alternate = Alternar
Crafting Grid =
### waypoints.lua ###
White = Blanco
Yellow = Amarillo
Red = Rojo
Green = Verde
Blue = Azul
Waypoints = Puntos de paso
Waypoint active = Punto de paso activo
Waypoint inactive = Punto de paso inactivo
World position = Posición en el mundo
Name = Nombre
HUD text color = Color del HUD
Edit waypoint name =
Rename waypoint =
Change color of waypoint display =
Set waypoint to current location =
Make waypoint visible =
Make waypoint invisible =
Disable display of waypoint coordinates =
Enable display of waypoint coordinates =
Finish editing =
Select Waypoint #%d =

72
locale/fr.txt Executable file
View File

@ -0,0 +1,72 @@
# Translation by kilbith
# Template
### bags.lua ###
Bags = Sacs
Bag 1 = Sac 1
Bag 2 = Sac 2
Bag 3 = Sac 3
Bag 4 = Sac 4
Small Bag = Petit sac
Medium Bag = Sac moyen
Large Bag = Grand sac
### inernal.lua ###
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
No matching items = Aucun élément correspondant
Page = Page
%s of %s = %s de %s
Filter = Filtre
Search = Rechercher
### register.lua ###
Can use the creative inventory = Vous pouvez utiliser l'inventaire créatif
Home position set to: %s = Position de votre base fixée à : %s
Time of day set to 6am = Heure fixée à 6h
You don't have the settime priviledge! = Vous n'avez pas le privilège 'settime' !
Time of day set to 9pm = Heure fixée à 21h
This button has been disabled outside of creative mode to prevent accidental inventory trashing.\nUse the trash slot instead. = Ce bouton a été désactivé en dehors du mode créatif pour éviter des saccages dans l'inventaire.\nUtilisez plutôt la case poubelle.
Inventory cleared! = Inventaire vidé !
Crafting = Création
Trash: = Poubelle :
Refill: = Remplir :
Crafting Guide = Guide de création
Method: = Méthode :
Result: %s = Résultat : %s
crafting = fabrication
shapeless crafting = fabrication sans forme
cooking = cuisson
alloy cooking = cuisson des métaux
Copy to craft grid: = Copier sur la grille de création
All = Tout
Recipe %s of %s = Recette %s de %d
Alternate = Alternative
Crafting Grid = Grille de création
### waypoints.lua ###
White = Blanc
Yellow = Jaune
Red = Rouge
Green = Vert
Blue = Bleu
Waypoints = Point de passage
Waypoint active = Point de passage actif
Waypoint inactive = Point de passage inactif
World position = Position dans le monde
Name = Nom
HUD text color = Couleur de texte du HUD
Edit waypoint name = Editer le nom du point de passage
Rename waypoint = Renommer le point de passage
Change color of waypoint display = Changer la couleur du point de passage
Set waypoint to current location = Marquer un point de passage à la position actuelle
Make waypoint visible = Rendre visible le point de passage
Make waypoint invisible = Rendre invisible le point de passage
Disable display of waypoint coordinates = Masquer les coordonnées des points de passages
Enable display of waypoint coordinates = Montrer les coordonnées des points de passages
Finish editing = Terminer l'édition
Select Waypoint #%d = Choisir un point de passage #%d

71
locale/pl.txt Executable file
View File

@ -0,0 +1,71 @@
# Translation by RealBadAngel
### bags.lua ###
Bags = Plecaki
Bag 1 = Plecak 1
Bag 2 = Plecak 2
Bag 3 = Plecak 3
Bag 4 = Plecak 4
Small Bag = Maly plecak
Medium Bag = Sredni plecak
Large Bag = Duzy plecak
### inernal.lua ###
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
No matching items = Brak pasujacych przedmiotow
Page = Strona
%s of %s = %s z %s
Filter = Filtr
Search = Szukaj
### register.lua ###
Can use the creative inventory =
Home position set to: %s = Pozycja domowa ustawiona na: %s
Time of day set to 6am = Czas ustawiony na 6:00
You don't have the settime priviledge! = Nie masz uprawnien do zmiany czasu (settime)!
Time of day set to 9pm = Czas ustawiony na 21:00
This button has been disabled outside of creative mode to prevent accidental inventory trashing.\nUse the trash slot instead. =
Inventory cleared! =
Crafting =
Trash: = Smietnik:
Refill: = Uzupelnianie:
Crafting Guide =
Method: = Metoda:
Result: %s = Wynik: %s
crafting =
shapeless crafting =
cooking =
alloy cooking =
Copy to craft grid: =
All = Wszystko
Recipe %s of %s = Recepta %s z %s
Alternate = Alternatywa
Crafting Grid =
### waypoints.lua ###
White = Bialy
Yellow = Zolty
Red = Czerwony
Green = Zielony
Blue = Niebieski
Waypoints = Punkty orientacyjne
Waypoint active = Punkt wlaczony
Waypoint inactive = Punkt wylaczony
World position = Pozycja
Name = Nazwa
HUD text color = Kolor tekstu HUD
Edit waypoint name = Edytuj nazwe punktu
Rename waypoint = Zmien nazwe punktu
Change color of waypoint display = Zmien kolor punktu
Set waypoint to current location = Ustaw punkt orientacyjny na biezacej pozycji
Make waypoint visible = Pokaz punkt
Make waypoint invisible = Nie pokazuj punktu
Disable display of waypoint coordinates = Pokazuj koordynaty punktu
Enable display of waypoint coordinates = Nie pokazuj koordynatow punktu
Finish editing = Zakoncz edycje
Select Waypoint #%d = Wybierz punkt #%d

76
locale/ru.txt Executable file
View File

@ -0,0 +1,76 @@
# Translation by eternal_sorrow
# Template
### bags.lua ###
Bags = Сумки
Bag 1 = Сумка 1
Bag 2 = Сумка 2
Bag 3 = Сумка 3
Bag 4 = Сумка 4
Small Bag = Малая сумка
Medium Bag = Средняя сумка
Large Bag = Большая сумка
### inernal.lua ###
First page = Первая страница
Back three pages = Назад на три страницы
Back one page = Назад на одну страницу
Forward one page = Вперед на одну страницу
Forward three pages = Вперед на три страницы
Last page = Последняя страница
No matching items = Совпадений нет
Page = Страница
%s of %s = %s из %s
Filter = Фильтр
Search = Поиск
### register.lua ###
Can use the creative inventory = Можно использовать инвентарь творческого режима
Home position set to: %s = Дом теперь расположен по коодинатам: %s
Time of day set to 6am = Установлено время 6 утра
You don't have the settime priviledge! = Вам не разрешено устанавливать время!
Time of day set to 9pm = Установлено время 9 вечера
This button has been disabled outside of creative mode to prevent accidental inventory trashing.\nUse the trash slot instead. = Эта кнопка отключена вне творческого режима, чтобы предотвратить случайное уничтожение предметов.\nИспользуйте слот корзины вместо нее.
Inventory cleared! = Инвентарь очищен!
Crafting = Крафт
Trash: = Корзина:
Refill: = Размножить:
Crafting Guide = Книга рецептов
Method: = Способ:
Result: %s = Результат: %s
crafting = крафт
shapeless crafting = бесформенный крафт
cooking = жарка
alloy cooking = приготовление сплавов
Copy to craft grid: = В решетку крафта:
All = Все
Recipe %s of %s = Рецепт %s из %s
Alternate = Следующий
Crafting Grid = Решетка крафта
Go home = Отправиться домой
Set time to day = День
Set time to night = Ночь
Clear inventory = Очистить инвентарь
### waypoints.lua ###
White = Белый
Yellow = Желтый
Red = Красный
Green = Зелёный
Blue = Синий
Waypoints = Путевые точки
Waypoint active = Путевая точка активна
Waypoint inactive = Путевая точка неактивна
World position = Позиция
Name = Имя
HUD text color = Цвет текста
Edit waypoint name = Редактировать имя путевой точки
Rename waypoint = Переименовать путевую точку
Change color of waypoint display = Изменить цвет путевой точки
Set waypoint to current location = Установить путевую точку в текущем местоположении
Make waypoint visible = Сделать путевую точку видимой
Make waypoint invisible = Сделать путевую точку невидимой
Disable display of waypoint coordinates = Отключить отображение координат путевой точки
Enable display of waypoint coordinates = Включить отображение координат путевой точки
Finish editing = Завершить редактирование
Select Waypoint #%d = Выбрать путевую точку №%d

View File

@ -1,358 +0,0 @@
# LANGUAGE translation for the unified_inventory mod.
# Copyright (C) 2018 Maciej Kasatkin (RealBadAngel)
# This file is distributed under the same license as the unified_inventory package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: unified_inventory\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-02 03:34+0200\n"
"PO-Revision-Date: 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 ""

197
locale/template.txt Normal file → Executable file
View File

@ -1,90 +1,107 @@
# textdomain: unified_inventory
Mixing=
Cooking=
Digging=
Bags=
Bag @1=
Small Bag=
Medium Bag=
Large Bag=
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and =
Scroll categories left=
Scroll categories right=
Search=
Reset search and display everything=
First page=
Back three pages=
Back one page=
Forward one page=
Forward three pages=
Last page=
No matching items=
No matches.=
Page=
@1 of @2=
Filter=
Can use the creative inventory=
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
Crafting Grid=
Crafting Guide=
Set home position=
Home position set to: @1=
You don't have the "home" privilege!=
Go home=
Set time to day=
Time of day set to 6am=
You don't have the settime privilege!=
Set time to night=
Time of day set to 9pm=
Clear inventory=
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
Inventory cleared!=
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@@large to be displayed.=
To craft grid:=
All=
Crafting=
White=
Yellow=
Red=
Green=
Blue=
Waypoints=
Select Waypoint #@1=
Waypoint @1=
Set waypoint to current location=
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
Change color of waypoint display=
Edit waypoint name=
Waypoint active=
Waypoint inactive=
Finish editing=
World position=
Name=
HUD text color=
# Translation by
### api.lua ###
Digging (by chance) =
# Template
### bags.lua ###
Bags =
Bag 1 =
Bag 2 =
Bag 3 =
Bag 4 =
Small Bag =
Medium Bag =
Large Bag =
### inernal.lua ###
First page =
Back three pages =
Back one page =
Forward one page =
Forward three pages =
Last page =
No matching items =
Page =
%s of %s =
Filter =
Search =
Reset search and display everything =
### register.lua ###
Can use the creative inventory =
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally =
Home position set to: %s =
Time of day set to 6am =
You don't have the settime priviledge! =
Time of day set to 9pm =
This button has been disabled outside of creative mode to prevent accidental inventory trashing.\nUse the trash slot instead. =
Inventory cleared! =
Crafting =
Digging =
Cooking =
Mixing =
Trash: =
Refill: =
Crafting Guide =
Method: =
Result: %s =
crafting =
shapeless crafting =
cooking =
alloy cooking =
Copy to craft grid: =
All =
Alternate =
Crafting Grid =
Show next recipe =
Show next usage =
Show previous recipe =
Show previous usage =
# Shown for huge crafting recipes; try to keep the line length short and use multiple line breaks as needed
This recipe is too\nlarge to be displayed. =
# %s = group name (e.g. wool)
Any item belonging to the %s group =
# %s = List of “and”-concatenated group names
Any item belonging to the groups %s =
Recipe %d of %d =
Usage %d of %d =
No recipes =
No usages =
Result =
Ingredient =
Set time to day =
Set time to night =
Set home position =
Go home =
Clear inventory =
Give me: =
To craft grid: =
### group.lua ###
# Logical connective, example: “Any item belonging to the groups foo and bar”
\sand\s =
### waypoints.lua ###
White =
Yellow =
Red =
Green =
Blue =
Waypoints =
Waypoint %d =
Waypoint active =
Waypoint inactive =
World position =
Name =
HUD text color =
Edit waypoint name =
Rename waypoint =
Change color of waypoint display =
Set waypoint to current location =
Make waypoint visible =
Make waypoint invisible =
Disable display of waypoint coordinates =
Enable display of waypoint coordinates =
Finish editing =
Select Waypoint #%d =

72
locale/tr.txt Executable file
View File

@ -0,0 +1,72 @@
# Translation by Mahmutelmas06@hotmail.com
# Template
### bags.lua ###
Bags = Çantalarım
Bag 1 = 1. Çanta
Bag 2 = 2. Çanta
Bag 3 = 3. Çanta
Bag 4 = 4. Çanta
Small Bag = Küçük Çanta
Medium Bag = Çanta
Large Bag = Büyük Çanta
### inernal.lua ###
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
No matching items = Eşleşme yok
Page = Sayfa
%s of %s = %s dan %s
Filter = Süzgeç
Search = Ara
### register.lua ###
Can use the creative inventory = Yaratıcı envanteri kullanabilir
Home position set to: %s = Yeni eviniz: %s
Time of day set to 6am = Saat 06:00 olarak ayarlandı
You don't have the settime priviledge = Saati düzenleme yetkiniz yok!
Time of day set to 9pm = Saat 19:00 olarak ayarlandı
This button has been disabled outside of creative mode to prevent accidental inventory trashing.\nUse the trash slot instead. = Yaratıcı modu dışında iken bu tuş kullanılamaz.
Inventory cleared! = Envanter temizlendi!
Crafting = Üretim
Trash: = Çöp
Refill: = Doldur
Crafting Guide = Kılavuz
Method: = Yöntem
Result: %s = Çıktı: %s
crafting = üretim
shapeless crafting = şekilsiz üretim
cooking = pişirme
alloy cooking = karıştırma
Copy to craft grid: = Üretim tablosuna kopyala
All = Tümü
Recipe %s of %s = %s dan %s tarifi
Alternate = Altarnatif
Crafting Grid = Üretim tablosu
### waypoints.lua ###
White = Beyaz
Yellow = Sarı
Red = Kırmızı
Green = Yeşil
Blue = Mavi
Waypoints = Konum Noktaları
Waypoint active = Konum Etkin
Waypoint inactive = Konum Devredışı
World position = Dünya konumu
Name = İsim
HUD text color = Metin rengi
Edit waypoint name = Konum Noktasını Düzenle
Rename waypoint = Konum Noktasını Adlandır
Change color of waypoint display = Konum Gösterge Rengi
Set waypoint to current location = Bulunduğun noktayı işaretle
Make waypoint visible = Konumlar görünür
Make waypoint invisible = Konumlar gözükmez
Disable display of waypoint coordinates = Koordinatları gizle
Enable display of waypoint coordinates = Koordinatları göster
Finish editing = Düzenleme bitti
Select Waypoint #%d = #%d konum noktası seç

View File

@ -1,100 +0,0 @@
# textdomain: unified_inventory
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
All Items=Alle Gegenstände
Misc. Items=Sonstige Gegenstände
Plant Life=Pfanzenwelt
Building Materials=Baumaterialien
Tools=Werkzeuge
Minerals and Metals=Minerale und Metalle
Environment and Worldgen=Umwelt und Welterstellung
Lighting=Beleuchtung
and = und
Scroll categories left=Kategorien nach links blättern
Scroll categories right=Kategorien nach rechts blättern
Search=Suchen
Reset search and display everything=Suche zurücksetzen und alles anzeigen
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
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
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
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
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
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
@1 (@2)=
Give me:=Gib mir:
This recipe is too@@large to be displayed.=
To craft grid:=Ins Fertigungsraster:
All=Alles
Crafting=Fertigung
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
Hide waypoint=Wegpunkt verstecken
Show waypoint=Wegpunkt zeigen
Hide coordinates=Koordinaten verstecken
Show coordinates=Koordinaten zeigen
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
##### not used anymore #####
invisible=unsichtbar
visible=sichtbar
Make waypoint @1=Wegpunkt @1 machen
Disable=ausschalten
Enable=einschalten
@1 display of waypoint coordinates=Anzeige der Wegpunktkoordinaten @1

View File

@ -1,108 +0,0 @@
# textdomain: unified_inventory
# api.lua
Mixing=Mezclar
Cooking=Hornear
Digging=Recoger
# bags.lua
Bags=Bolsos
Bag @1=Bolso @1
Small Bag=Bolso Pequeño
Medium Bag=Bolso Mediano
Large Bag=Bolso Grande
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
# group.lua
and = y
Scroll categories left=
Scroll categories right=
Search=Buscar
Reset search and display everything=Limpiar la busqueda y mostrar todo
# 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
No matching items=No se encontraron elementos
No matches.=No hay resultados.
Page=Página
@1 of @2=@1 de @2
Filter=Filtro
# 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!=
Go home=Ir a casa
Set time to day=Cambiar a dia
Time of day set to 6am=Hora del día cambiada a 6 AM
You don't have the settime privilege!=¡No tienes el privilegio "settime"!
Set time to night=Cambiar a noche
Time of day set to 9pm=Hora del día cambiada a 9 PM
Clear inventory=Limpiar inventario
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
Inventory cleared!=¡Inventario limpio!
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@@large to be displayed.=
To craft grid:=Construir:
All=Todos
Crafting=Elaboración
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
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
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
##### not used anymore #####
Make waypoint @1=Hacer punto @1
invisible=invisible
visible=visible
@1 display of waypoint coordinates=Visualizar coordenadas del punto @1
Disable=Deshabilitado
Enable=Habilitado
You don't have the \"home\" privilege!=¡No tienes el privilegio \"home\"!
This button has been disabled outside=Este botón ha sido deshabilitado
This recipe is too@nlarge to be displayed.=Esta receta es demasiado@ngrande para ser mostrada.

View File

@ -1,96 +0,0 @@
# textdomain: unified_inventory
Mixing=
Cooking=Cuisson
Digging=Creuser
Bags=Sacs
Bag @1=Sac @1
Small Bag=Petit sac
Medium Bag=Sac moyen
Large Bag=Grand sac
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = et
Scroll categories left=
Scroll categories right=
Search=Rechercher
Reset search and display everything=
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
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
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
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"!
Go home=
Set time to day=
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"!
Set time to night=
Time of day set to 9pm=Heure fixée à 21h
Clear inventory=
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
Inventory cleared!=Inventaire vidé !
Trash:=Poubelle :
Refill:=Remplir :
Any item belonging to the @1 group=
Any item belonging to the groups @1=
Recipe @1 of @2=Recette @1 de @2
Usage @1 of @2=
No recipes=
No usages=
Result=Résultat
Ingredient=
Show next recipe=
Show next usage=
Show previous recipe=
Show previous usage=
@1 (@2)=
Give me:=
This recipe is too@@large to be displayed.=
To craft grid:=Sur de création:
All=Tout
Crafting=Création
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
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
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
##### not used anymore #####
Make waypoint @1=Rendre @1 le point de passage
@1 display of waypoint coordinates=@1 montrer les coordonnées des points de passages

View File

@ -1,100 +0,0 @@
# textdomain: unified_inventory
Mixing=Unione
Cooking=Cottura
Digging=Scavo
Bags=Borse
Bag @1=Borsa @1
Small Bag=Borsa piccola
Medium Bag=Borsa media
Large Bag=Borsa grande
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = e
Scroll categories left=
Scroll categories right=
Search=Cerca
Reset search and display everything=Azzera la ricerca e mostra tutto
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
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
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
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
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
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
@1 (@2)=
Give me:=Dammi:
This recipe is too@@large to be displayed.=
To craft grid:=Alla griglia di assemblaggio:
All=Tutto
Crafting=Assemblaggio
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
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
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
##### not used anymore #####
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

View File

@ -1,100 +0,0 @@
# textdomain: unified_inventory
Mixing=Pencampuran
Cooking=Pemasakan
Digging=Penggalian
Bags=Beg
Bag @1=Beg @1
Small Bag=Beg Kecil
Medium Bag=Beg Sederhana
Large Bag=Beg Besar
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = dan
Scroll categories left=
Scroll categories right=
Search=Cari
Reset search and display everything=Set semula carian dan tunjukkan semua benda
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
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
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
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
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
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:
This recipe is too@@large to be displayed.=
To craft grid:=Ke grid pertukangan:
All=
Crafting=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
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
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
##### not used anymore #####
invisible=Sembunyikan
visible=Paparkan
Make waypoint @1=@1 titik arah
Disable=Sembunyikan
Enable=Paparkan
@1 display of waypoint coordinates=@1 koordinat untuk titik arah

View File

@ -1,91 +0,0 @@
# textdomain: unified_inventory
Category:=Kategorie:
Mixing=Miksowanie
Cooking=Gotowanie
Digging=Kopanie
Bags=Plecaki
Bag @1=Plecak @1
Small Bag=Mały plecak
Medium Bag=Średni plecak
Large Bag=Duży plecak
All Items=Wszystkie przedmioty
Misc. Items=Różne przedmioty
Plant Life=Życie roślin
Building Materials=Materiały budowlane
Tools=Narzędzia
Minerals and Metals=Minerały i metale
Environment and Worldgen=Otoczenie i generowanie świata
Lighting=Oświetlenie
and = i
Scroll categories left=Przewiń kategorię w lewo
Scroll categories right=Przewiń kategorię w prawo
Search=Szukaj
Reset search and display everything=Zresetuj wyszukiwanie i pokaż wszystko
First page=Pierwsza strona
Back three pages=Trzy strony do tyłu
Back one page=Stronę do tyłu
Forward one page=Stronę do przodu
Forward three pages=Trzy strony do przodu
Last page=Ostatnia strona
No matching items=Brak pasujących przedmiotów
No matches.=Brak wyników
Page=Strona
@1 of @2=@1 z @2
Filter=Filtr
Can use the creative inventory=Może używać kreatywnego ekwipunku
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Wymusza wyświetlanie Unified Inventory w trybie Full jeżeli tryb Lite jest skonfigurowany globalnie
Crafting Grid=Siatka craftingu
Crafting Guide=Przewodnik craftingu
Set home position=Ustaw pozycję domu
Home position set to: @1=Pozycja domu ustawiona na: @1
You don't have the "home" privilege!=Brak uprawnień "home"!
Go home=Idź do domu
Set time to day=Ustaw czas na dzień
Time of day set to 6am=Czas ustawiony na 6:00
You don't have the settime privilege!=Brak uprawnień "settime"!
Set time to night=Ustaw czas na noc
Time of day set to 9pm=Czas ustawiony na 21:00
Clear inventory=Wyczyść ekwipunek
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=Aby zapobiec przypadkowemu skasowaniu ekwipunku, ten przycisk został wyłączony poza trybem kreatywnym.@nUżyj zamiast tego ikony śmietnika.
Inventory cleared!=Ekwipunek został wyczyszczony!
Trash:=Śmietnik:
Refill:=Uzupełnianie:
Any item belonging to the @1 group=Każdy przedmiot należący do @1 grupy
Any item belonging to the groups @1=Każdy przedmiot należacy do grup @1
Recipe @1 of @2=Recepta @1 z @2
Usage @1 of @2=Użycie @1 z @2
No recipes=Brak recepty
No usages=Bez użycia
Result=Wynik
Ingredient=Składnik
Show next recipe=Pokaż nastepną recepturę
Show next usage=Pokaż następne użycie
Show previous recipe=Pokaż poprzednią recepturę
Show previous usage=Pokaż poprzednie użycie
@1 (@2)=@1 (@2)
Give me:=Daj mi:
This recipe is too@@large to be displayed.=Receptura jest zbyt@@duża aby ją wyświetlić.
To craft grid:=Do siatki craftingu.
All=Wszystko
Crafting=Crafting
White=Biały
Yellow=Zółty
Red=Czerwony
Green=Zielony
Blue=Niebieski
Waypoints=Punkty orientacyjne
Select Waypoint #@1=Wybierz punkt #@1
Waypoint @1=Punkty orientacyjne @1
Set waypoint to current location=Ustaw punkt orientacyjny na bieżacej pozycji
Hide waypoint=Ukryj punkt orientacyjny
Show waypoint=Pokaż punkt orientacyjny
Hide coordinates=Ukryj koordynaty
Show coordinates=Pokaż koordynaty
Change color of waypoint display=Zmień kolor punktu
Edit waypoint name=Edytuj nazwę punktu
Waypoint active=Punkt włączony
Waypoint inactive=Punkt wyłączony
Finish editing=Zakończ edycję
World position=Pozycja
Name=Nazwa
HUD text color=Kolor tekstu HUD

View File

@ -1,98 +0,0 @@
# textdomain: unified_inventory
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
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = e
Scroll categories left=
Scroll categories right=
Search=Pesquisar
Reset search and display everything=Redefinir pesquisa e exibir tudo
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
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
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
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
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
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
@1 (@2)=
Give me:=Gerado:
This recipe is too@@large to be displayed.=
To craft grid:=Para Grade de Artesanato
All=MAX
Crafting=Artesanato
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
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
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
##### not used anymore #####
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

View File

@ -1,100 +0,0 @@
# textdomain: unified_inventory
Mixing=Мешать
Cooking=Варить
Digging=Копать
Bags=Сумки
Bag @1=Сумка @1
Small Bag=Малая сумка
Medium Bag=Средняя сумка
Large Bag=Большая сумка
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = и
Scroll categories left=
Scroll categories right=
Search=Поиск
Reset search and display everything=Сброс поиска, показать всё
First page=Первая страница
Back three pages=3 страницы назад
Back one page=1 страницу назад
Forward one page=1 страницу вперёд
Forward three pages=3 страницы вперёд
Last page=Последняя страница
No matching items=Нет подходящих элементов
No matches.=Ничего не найдено
Page=Страница
@1 of @2=@1 из @2
Filter=Фильтр
Can use the creative inventory=Можно использовать инвентарь творческого режима
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
Crafting Grid=Решетка крафта
Crafting Guide=Книга рецептов
Set home position=Установить позицию дома
Home position set to: @1=Дом теперь расположен по коодинатам: @1
You don't have the "home" privilege!=У вас нет привилегии "home"!
Go home=Отправиться домой
Set time to day=День
Time of day set to 6am=Установлено время 6 утра
You don't have the settime privilege!=Вам не разрешено устанавливать время! (нет привилегии "settime")
Set time to night=Ночь
Time of day set to 9pm=Установлено время 9 вечера
Clear inventory=Очистить инвентарь
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
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=Прошлая страница
@1 (@2)=
Give me:=Дай мне:
This recipe is too@@large to be displayed.=
To craft grid:=На решeтку крафта:
All=Все
Crafting=Крафт
White=Белый
Yellow=Желтый
Red=Красный
Green=Зелёный
Blue=Синий
Waypoints=Путевые точки
Select Waypoint #@1=Выбрать путевую точку №@1
Waypoint @1=Путевая точка @1
Set waypoint to current location=Установить путевую точку по текущей позиции
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
Change color of waypoint display=Поменять цвет путевой точки
Edit waypoint name=Переименовать путевую точку
Waypoint active=Путевая точка включена
Waypoint inactive=Путевая точка выключена
Finish editing=Закончить редакцию
World position=Позиция мира
Name=Имя
HUD text color=Цвет текста HUDа
##### not used anymore #####
invisible=невидимой
visible=видимой
Make waypoint @1=Сделать путевую точку @1
Disable=Выключить
Enable=Включить
@1 display of waypoint coordinates=@1 показ координат путевых точек

View File

@ -1,99 +0,0 @@
# textdomain: unified_inventory
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
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = ve
Scroll categories left=
Scroll categories right=
Search=Ara
Reset search and display everything=
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
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
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
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ı
Clear inventory=
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
Inventory cleared!=Envanter temizlendi!
Trash:=Çöp
Refill:=Doldur
Any item belonging to the @1 group=
Any item belonging to the groups @1=
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
Show next recipe=
Show next usage=
Show previous recipe=
Show previous usage=
@1 (@2)=
Give me:=Ver bana:
This recipe is too@@large to be displayed.=
To craft grid:=Üretim tablosuna kopyala
All=Tümü
Crafting=Üretim
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
Hide waypoint=
Show waypoint=
Hide coordinates=
Show coordinates=
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
##### not used anymore #####
msgid ""=Yaratıcı modu dışında iken bu tuş kullanılamaz.
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

View File

@ -1,98 +0,0 @@
# textdomain: unified_inventory
Mixing=混合
Cooking=烹饪
Digging=挖出
Bags=背包
Bag @1=背包@1
Small Bag=小背包
Medium Bag=中背包
Large Bag=大背包
All Items=所有物品
Misc. Items=杂项
Plant Life=植物
Building Materials=建材
Tools=工具
Minerals and Metals=矿物与金属
Environment and Worldgen=自然环境
Lighting=光源
and = 和
Scroll categories left=向左滚动分类栏
Scroll categories right=向右滚动分类栏
Search=搜索
Reset search and display everything=重置搜索并显示所有物品
First page=第一页
Back three pages=后退三页
Back one page=后退一页
Forward one page=前进一页
Forward three pages=前进三页
Last page=最后一页
No matching items=没有匹配物品
No matches.=没有匹配
Page=页面
@1 of @2=第@1页共@2页
Filter=过滤器
Can use the creative inventory=可以使用创造背包
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=如果轻量模式被全局配置强迫Unified 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=清空背包
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=此按钮已在非创造模式中禁用以防止意外的背包清空。@n请使用垃圾桶栏。
Inventory cleared!=清空背包
Trash:=丢弃:
Refill:=填满:
Any item belonging to the @1 group=属于@1组的任何项目
Any item belonging to the groups @1=属于组@1的任何项目
Recipe @1 of @2=第@1配方共@2个
Usage @1 of @2=第@1用法共@2个
No recipes=没有配方
No usages=没有用法
Result=结果
Ingredient=原料
Show next recipe=显示下一个配方
Show next usage=显示下一个用法
Show previous recipe=显示前一个配方
Show previous usage=显示前一个用法
@1 (@2)=@1 (@2)
Give me:=给予:
This recipe is too@@large to be displayed.=该配方太@@大,不能显示。
To craft grid:=填充物品到合成表
All=全部
Crafting=合成
White=白
Yellow=黄
Red=红
Green=绿
Blue=蓝
Waypoints=航路点
Select Waypoint #@1=查询航路点 #@1
Waypoint @1=航路点 @1
Set waypoint to current location=将航路点设置到当前位置
Hide waypoint=隐藏航路点
Show waypoint=显示航路点
Hide coordinates=隐藏坐标
Show coordinates=显示坐标
Change color of waypoint display=改变航路点显示的颜色
Edit waypoint name=编辑航路点名称
Waypoint active=航路点已激活
Waypoint inactive=航路点未激活
Finish editing=完成编辑
World position=世界位置
Name=名称
HUD text color=HUD文本颜色
##### not used anymore #####
invisible=不可见的
visible=可见的
Make waypoint @1=设置航路点 @1
@1 display of waypoint coordinates=显示航路点@1坐标

View File

@ -1,98 +0,0 @@
# textdomain: unified_inventory
Mixing=混合
Cooking=烹飪
Digging=挖出
Bags=揹包
Bag @1=揹包@1
Small Bag=小揹包
Medium Bag=中揹包
Large Bag=大揹包
All Items=所有物品
Misc. Items=雜項
Plant Life=植物
Building Materials=建材
Tools=工具
Minerals and Metals=礦物與金屬
Environment and Worldgen=自然環境
Lighting=光源
and = 和
Scroll categories left=向左滾動分類欄
Scroll categories right=向右滾動分類欄
Search=搜索
Reset search and display everything=重置搜索並顯示所有物品
First page=第一頁
Back three pages=後退三頁
Back one page=後退一頁
Forward one page=前進一頁
Forward three pages=前進三頁
Last page=最後一頁
No matching items=沒有匹配物品
No matches.=沒有匹配
Page=頁面
@1 of @2=第@1頁共@2頁
Filter=過濾器
Can use the creative inventory=可以使用創造揹包
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=如果輕量模式被全局配置強迫Unified 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=清空揹包
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=此按鈕已在非創造模式中禁用以防止意外的背包清空。@n請使用垃圾桶欄。
Inventory cleared!=清空揹包
Trash:=丟棄:
Refill:=填滿:
Any item belonging to the @1 group=屬於@1組的任何項目
Any item belonging to the groups @1=屬於組@1的任何項目
Recipe @1 of @2=第@1配方共@2個
Usage @1 of @2=第@1用法共@2個
No recipes=沒有配方
No usages=沒有用法
Result=結果
Ingredient=原料
Show next recipe=顯示下一個配方
Show next usage=顯示下一個用法
Show previous recipe=顯示上一個配方
Show previous usage=顯示上一個用法
@1 (@2)=@1 (@2)
Give me:=給予:
This recipe is too@@large to be displayed.=該配方太@@大,不能顯示。
To craft grid:=填充物品到合成表
All=全部
Crafting=合成
White=白
Yellow=黃
Red=紅
Green=綠
Blue=藍
Waypoints=航路點
Select Waypoint #@1=查詢航路點 #@1
Waypoint @1=航路點 @1
Set waypoint to current location=將航路點設置到當前位置
Hide waypoint=隱藏航路點
Show waypoint=顯示航路點
Hide coordinates=隱藏坐標
Show coordinates=顯示坐標
Change color of waypoint display=改變航路點顯示的顏色
Edit waypoint name=編輯航路點名稱
Waypoint active=航路點已激活
Waypoint inactive=航路點未激活
Finish editing=完成編輯
World position=世界位置
Name=名稱
HUD text color=HUD文本顏色
##### not used anymore #####
invisible=不可見的
visible=可見的
Make waypoint @1=設置航路點 @1
@1 display of waypoint coordinates=顯示航路點@1座標

View File

@ -1,402 +0,0 @@
-- 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 result = {}
for craft_item in pairs(craft_items) do
-- may specify group:type1,type2
local items = unified_inventory.get_matching_items(craft_item)
local found = {}
for itemname, _ in pairs(items) do
if inv_items[itemname] then
found[itemname] = 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

View File

@ -1,8 +1 @@
name = unified_inventory
optional_depends = default, creative, sfinv, datastorage
description = """
Unified Inventory replaces the default survival and creative inventory.
It adds a nicer interface and a number of features, such as a crafting guide.
"""
min_minetest_version = 5.4.0

550
register.lua Normal file → Executable file
View File

@ -1,7 +1,5 @@
local S = minetest.get_translator("unified_inventory")
local NS = function(s) return s end
local F = minetest.formspec_escape
local ui = unified_inventory
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
minetest.register_privilege("creative", {
description = S("Can use the creative inventory"),
@ -13,9 +11,10 @@ minetest.register_privilege("ui_full", {
give_to_singleplayer = false,
})
local trash = minetest.create_detached_inventory("trash", {
--allow_put = function(inv, listname, index, stack, player)
-- if ui.is_creative(player:get_player_name()) then
-- if unified_inventory.is_creative(player:get_player_name()) then
-- return stack:get_count()
-- else
-- return 0
@ -29,76 +28,83 @@ local trash = minetest.create_detached_inventory("trash", {
})
trash:set_size("main", 1)
ui.register_button("craft", {
unified_inventory.register_button("craft", {
type = "image",
image = "ui_craft_icon.png",
tooltip = S("Crafting Grid")
tooltip = S("Crafting Grid"),
show_with = false, --Modif MFF (Crabman 30/06/2015)
})
ui.register_button("craftguide", {
unified_inventory.register_button("craftguide", {
type = "image",
image = "ui_craftguide_icon.png",
tooltip = S("Crafting Guide")
tooltip = S("Crafting Guide"),
show_with = false, --Modif MFF (Crabman 30/06/2015)
})
ui.register_button("home_gui_set", {
--[[
unified_inventory.register_button("home_gui_set", {
type = "image",
image = "ui_sethome_icon.png",
tooltip = S("Set home position"),
hide_lite=true,
show_with = "interact", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {home=true}) then
ui.set_home(player, player:get_pos())
local home = ui.home_pos[player_name]
if home ~= nil then
if home.sethome(player:get_player_name()) == true then --modif MFF
minetest.sound_play("dingdong",
{to_player=player_name, gain = 1.0})
minetest.chat_send_player(player_name,
S("Home position set to: @1", minetest.pos_to_string(home)))
{to_player=player:get_player_name(), gain = 1.0})
end
else
minetest.chat_send_player(player_name,
S("You don't have the \"home\" privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name])
end
end,
condition = function(player)
return minetest.check_player_privs(player:get_player_name(), {home=true})
end,
end,
})
ui.register_button("home_gui_go", {
unified_inventory.register_button("home_gui_go", {
type = "image",
image = "ui_gohome_icon.png",
tooltip = S("Go home"),
hide_lite=true,
show_with = "interact", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {home=true}) then
if ui.go_home(player) then
minetest.sound_play("teleport", {to_player = player_name})
end
else
minetest.chat_send_player(player_name,
S("You don't have the \"home\" privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name])
if home.tohome(player:get_player_name()) == true then --modif MFF
minetest.sound_play("teleport",
{to_player=player:get_player_name(), gain = 1.0})
end
end,
condition = function(player)
return minetest.check_player_privs(player:get_player_name(), {home=true})
})
--]]
if minetest.get_modpath("news") then
unified_inventory.register_button("news", {
type = "image",
image = "ui_news_icon.png",
tooltip = S("News"),
hide_lite = true,
show_with = "interact",
action = function(player)
core.chatcommands["news"].func(player:get_player_name())
end,
})
end
unified_inventory.register_button("home_gui_set", { --new h2omes
type = "image",
image = "ui_gohome_icon.png",
tooltip = S("My Homes"),
hide_lite=true,
show_with = "home", --Modif MFF (Crabman 30/06/2015)
action = function(player)
h2omes.show_formspec_home(player:get_player_name())
end,
})
ui.register_button("misc_set_day", {
unified_inventory.register_button("misc_set_day", {
type = "image",
image = "ui_sun_icon.png",
tooltip = S("Set time to day"),
hide_lite=true,
show_with = "settime", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {settime=true}) then
minetest.sound_play("ui_morning",
minetest.sound_play("birds",
{to_player=player_name, gain = 1.0})
minetest.set_timeofday((6000 % 24000) / 24000)
minetest.chat_send_player(player_name,
@ -106,23 +112,20 @@ ui.register_button("misc_set_day", {
else
minetest.chat_send_player(player_name,
S("You don't have the settime privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name])
end
end,
condition = function(player)
return minetest.check_player_privs(player:get_player_name(), {settime=true})
end,
})
ui.register_button("misc_set_night", {
unified_inventory.register_button("misc_set_night", {
type = "image",
image = "ui_moon_icon.png",
tooltip = S("Set time to night"),
hide_lite=true,
show_with = "settime", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {settime=true}) then
minetest.sound_play("ui_owl",
minetest.sound_play("owl",
{to_player=player_name, gain = 1.0})
minetest.set_timeofday((21000 % 24000) / 24000)
minetest.chat_send_player(player_name,
@ -130,27 +133,23 @@ ui.register_button("misc_set_night", {
else
minetest.chat_send_player(player_name,
S("You don't have the settime privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name])
end
end,
condition = function(player)
return minetest.check_player_privs(player:get_player_name(), {settime=true})
end,
})
ui.register_button("clear_inv", {
unified_inventory.register_button("clear_inv", {
type = "image",
image = "ui_trash_icon.png",
tooltip = S("Clear inventory"),
show_with = "creative", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if not ui.is_creative(player_name) then
if not unified_inventory.is_creative(player_name) then
minetest.chat_send_player(player_name,
S("This button has been disabled outside"
.." of creative mode to prevent"
.." accidental inventory trashing."
.."\nUse the trash slot instead."))
ui.set_inventory_formspec(player, ui.current_page[player_name])
return
end
player:get_inventory():set_list("main", {})
@ -158,43 +157,30 @@ ui.register_button("clear_inv", {
minetest.sound_play("trash_all",
{to_player=player_name, gain = 1.0})
end,
condition = function(player)
return ui.is_creative(player:get_player_name())
end,
})
ui.register_page("craft", {
unified_inventory.register_page("craft", {
get_formspec = function(player, perplayer_formspec)
local formheaderx = perplayer_formspec.form_header_x
local formheadery = perplayer_formspec.form_header_y
local craftx = perplayer_formspec.craft_x
local crafty = perplayer_formspec.craft_y
local formspecy = perplayer_formspec.formspec_y
local formheadery = perplayer_formspec.form_header_y
local player_name = player:get_player_name()
local formspec = {
perplayer_formspec.standard_inv_bg,
perplayer_formspec.craft_grid,
"label["..formheaderx..","..formheadery..";" ..F(S("Crafting")).."]",
"listcolors[#00000000;#00000000]",
"listring[current_name;craft]",
"listring[current_player;main]"
}
local n=#formspec+1
if ui.trash_enabled or ui.is_creative(player_name) or minetest.get_player_privs(player_name).give then
formspec[n] = string.format("label[%f,%f;%s]", craftx + 6.35, crafty + 2.3, F(S("Trash:")))
formspec[n+1] = ui.make_trash_slot(craftx + 6.25, crafty + 2.5)
n=n + 2
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("Crafting").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;craftpreview;6,"..formspecy..";1,1;]"
formspec = formspec.."list[current_player;craft;2,"..formspecy..";3,3;]"
formspec = formspec.."label[7,"..(formspecy + 1.5)..";" .. F("Trash:") .. "]"
formspec = formspec.."list[detached:trash;main;7,"..(formspecy + 2)..";1,1;]"
formspec = formspec.."listring[current_name;craft]"
formspec = formspec.."listring[current_player;main]"
if unified_inventory.is_creative(player_name) then
formspec = formspec.."label[0,"..(formspecy + 1.5)..";" .. F("Refill:") .. "]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."refill;main;0,"..(formspecy +2)..";1,1;]"
end
if ui.is_creative(player_name) then
formspec[n] = ui.single_slot(craftx - 2.5, crafty + 2.5)
formspec[n+1] = string.format("label[%f,%f;%s]", craftx - 2.4, crafty + 2.3, F(S("Refill:")))
formspec[n+2] = string.format("list[detached:%srefill;main;%f,%f;1,1;]",
F(player_name), craftx - 2.5 + ui.list_img_offset, crafty + 2.5 + ui.list_img_offset)
end
return {formspec=table.concat(formspec)}
return {formspec=formspec}
end,
})
@ -207,176 +193,132 @@ ui.register_page("craft", {
local function stack_image_button(x, y, w, h, buttonname_prefix, item)
local name = item:get_name()
local description = item:get_meta():get_string("description")
local count = item:get_count()
local show_is_group = false
local displayitem = item:to_string()
local displayitem = name.." "..count
local selectitem = name
if name:sub(1, 6) == "group:" then
local group_name = name:sub(7)
local group_item = ui.get_group_item(group_name)
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 ""
-- Unique id to prevent tooltip being overridden
local id = string.format("%i%i_", x*10, y*10)
local buttonname = F(id..buttonname_prefix..ui.mangle_for_formspec(selectitem))
local buttonname = minetest.formspec_escape(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)
minetest.formspec_escape(displayitem), buttonname, label)
if show_is_group then
local groupstring, andcount = ui.extract_groupnames(name)
local groupstring, andcount = unified_inventory.extract_groupnames(name)
local grouptip
if andcount == 1 then
grouptip = S("Any item belonging to the @1 group", groupstring)
grouptip = string.format(S("Any item belonging to the %s group"), groupstring)
elseif andcount > 1 then
grouptip = S("Any item belonging to the groups @1", groupstring)
grouptip = string.format(S("Any item belonging to the groups %s"), groupstring)
end
grouptip = F(grouptip)
grouptip = minetest.formspec_escape(grouptip)
if andcount >= 1 then
button = button .. string.format("tooltip[%s;%s]", buttonname, grouptip)
end
elseif description ~= "" then
button = button .. string.format("tooltip[%s;%s]", buttonname, F(description))
end
return button
end
-- The recipe text contains parameters, hence they can yet not be translated.
-- Instead, use a dummy translation call so that it can be picked up by the
-- static parsing of the translation string update script
local recipe_text = {
recipe = NS("Recipe @1 of @2"),
usage = NS("Usage @1 of @2"),
recipe = "Recipe %d of %d",
usage = "Usage %d of %d",
}
local no_recipe_text = {
recipe = S("No recipes"),
usage = S("No usages"),
recipe = "No recipes",
usage = "No usages",
}
local role_text = {
recipe = S("Result"),
usage = S("Ingredient"),
recipe = "Result",
usage = "Ingredient",
}
local next_alt_text = {
recipe = S("Show next recipe"),
usage = S("Show next usage"),
recipe = "Show next recipe",
usage = "Show next usage",
}
local prev_alt_text = {
recipe = S("Show previous recipe"),
usage = S("Show previous usage"),
recipe = "Show previous recipe",
usage = "Show previous usage",
}
local other_dir = {
recipe = "usage",
usage = "recipe",
}
ui.register_page("craftguide", {
unified_inventory.register_page("craftguide", {
get_formspec = function(player, perplayer_formspec)
local craftguidex = perplayer_formspec.craft_guide_x
local craftguidey = perplayer_formspec.craft_guide_y
local craftguidearrowx = perplayer_formspec.craft_guide_arrow_x
local craftguideresultx = perplayer_formspec.craft_guide_result_x
local formheaderx = perplayer_formspec.form_header_x
local formheadery = perplayer_formspec.form_header_y
local give_x = perplayer_formspec.give_btn_x
local 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 player_privs = minetest.get_player_privs(player_name)
local formspec = ""
formspec = formspec.."background[0,"..(formspecy + 3.5)..";8,4;ui_main_inventory.png]"
formspec = formspec.."label[0,"..formheadery..";" .. F("Crafting Guide") .. "]"
formspec = formspec.."listcolors[#00000000;#00000000]"
local item_name = unified_inventory.current_item[player_name]
if not item_name then return {formspec=formspec} end
local formspec = {
perplayer_formspec.standard_inv_bg,
"label["..formheaderx..","..formheadery..";" .. F(S("Crafting Guide")) .. "]",
"listcolors[#00000000;#00000000]"
}
local item_name = ui.current_item[player_name]
if not item_name then
return { formspec = table.concat(formspec) }
end
local n = 4
local item_name_shown
if minetest.registered_items[item_name]
and minetest.registered_items[item_name].description then
item_name_shown = S("@1 (@2)",
minetest.registered_items[item_name].description, item_name)
else
item_name_shown = item_name
end
local dir = ui.current_craft_direction[player_name]
local rdir = dir == "recipe" and "usage" or "recipe"
local crafts = ui.crafts_for[dir][item_name]
local alternate = ui.alternate[player_name]
local dir = unified_inventory.current_craft_direction[player_name]
local rdir
if dir == "recipe" then rdir = "usage" end
if dir == "usage" then rdir = "recipe" end
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
if crafts ~= nil and #crafts > 0 then
alternates = #crafts
craft = crafts[alternate]
end
local has_give = player_privs.give or ui.is_creative(player_name)
formspec[n] = string.format("image[%f,%f;%f,%f;ui_crafting_arrow.png]",
craftguidearrowx, craftguidey, ui.imgscale, ui.imgscale)
formspec[n+1] = string.format("textarea[%f,%f;10,1;;%s: %s;]",
perplayer_formspec.craft_guide_resultstr_x, perplayer_formspec.craft_guide_resultstr_y,
F(role_text[dir]), item_name_shown)
n = n + 2
local giveme_form = table.concat({
"label[".. (give_x+0.1)..",".. (craftguidey + 2.7) .. ";" .. F(S("Give me:")) .. "]",
"button["..(give_x)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_1;1]",
"button["..(give_x+0.8)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_10;10]",
"button["..(give_x+1.6)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_99;99]"
})
formspec = formspec.."background[0.5,"..(formspecy + 0.2)..";8,3;ui_craftguide_form.png]"
formspec = formspec.."textarea["..craftresultx..","..craftresulty
..";10,1;;"..minetest.formspec_escape(F(role_text[dir])..": "..item_name)..";]"
formspec = formspec..stack_image_button(0, formspecy, 1.1, 1.1, "item_button_"
.. rdir .. "_", ItemStack(item_name))
if not craft then
-- No craft recipes available for this item.
formspec[n] = string.format("label[%f,%f;%s]", craftguidex+2.5, craftguidey+1.5, F(no_recipe_text[dir]))
local no_pos = dir == "recipe" and (craftguidex+2.5) or craftguideresultx
local item_pos = dir == "recipe" and craftguideresultx or (craftguidex+2.5)
formspec[n+1] = "image["..no_pos..","..craftguidey..";1.2,1.2;ui_no.png]"
formspec[n+2] = stack_image_button(item_pos, craftguidey, 1.2, 1.2,
"item_button_" .. other_dir[dir] .. "_", ItemStack(item_name))
if has_give then
formspec[n+3] = giveme_form
formspec = formspec.."label[5.5,"..(formspecy + 2.35)..";"
..minetest.formspec_escape(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
formspec = formspec.."image["..no_pos..","..formspecy..";1.1,1.1;ui_no.png]"
formspec = formspec..stack_image_button(item_pos, formspecy, 1.1, 1.1, "item_button_"
..other_dir[dir].."_", ItemStack(item_name))
if player_privs.give == true then
formspec = formspec.."label[0,"..(formspecy + 2.10)..";" .. F("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(formspec) }
else
formspec[n] = stack_image_button(craftguideresultx, craftguidey, 1.2, 1.2,
"item_button_" .. rdir .. "_", ItemStack(craft.output))
n = n + 1
return {formspec = formspec}
end
local craft_type = ui.registered_craft_types[craft.type] or
ui.craft_type_defaults(craft.type, {})
local craft_type = unified_inventory.registered_craft_types[craft.type] or
unified_inventory.craft_type_defaults(craft.type, {})
if craft_type.icon then
formspec[n] = string.format("image[%f,%f;%f,%f;%s]",
craftguidearrowx+0.35, craftguidey, 0.5, 0.5, craft_type.icon)
n = n + 1
formspec = formspec..string.format(" image[%f,%f;%f,%f;%s]",5.7,(formspecy + 0.05),0.5,0.5,craft_type.icon)
end
formspec[n] = string.format("label[%f,%f;%s]", craftguidearrowx + 0.15, craftguidey + 1.4, F(craft_type.description))
n = n + 1
local display_size = craft_type.dynamic_display_size
and craft_type.dynamic_display_size(craft)
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
formspec = formspec.."label[5.5,"..(formspecy + 1)..";" .. minetest.formspec_escape(craft_type.description).."]"
formspec = formspec..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 = craftguidex+3.75
local bspc = 1.25
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 optimization measures kick in
-- 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)
@ -385,12 +327,12 @@ ui.register_page("craftguide", {
-- Size modifier factor
local sf = math.min(1, of * (1.05 + 0.05*od))
-- Button size
local bsize = 1.2 * sf
if display_size.width >= mini_craft_size then -- it's not a normal 3x3 grid
bsize = 0.8 * sf
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 > 0.35 and display_size.width) then
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
@ -400,76 +342,67 @@ ui.register_page("craftguide", {
-- Flipped x, used to build formspec buttons from right to left
local fx = display_size.width - (x-1)
-- x offset, y offset
local xof = ((fx-1) * of + of) * bspc
local yof = ((y-1) * of + 1) * bspc
local xof = (fx-1) * of + of
local yof = (y-1) * of + 1
if item then
formspec[n] = stack_image_button(
xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize,
formspec = formspec..stack_image_button(
xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h,
"item_button_recipe_",
ItemStack(item))
else
-- Fake buttons just to make grid
formspec[n] = string.format("image_button[%f,%f;%f,%f;ui_blank_image.png;;]",
xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize)
formspec = formspec.."image_button["
..tostring(xoffset - xof)..","..tostring(formspecy - 1 + yof)
..";"..bsize_w..","..bsize_h..";ui_blank_image.png;;]"
end
n = n + 1
end
end
else
-- Error
formspec[n] = string.format("label[2,%f;%s]",
craftguidey, F(S("This recipe is too@nlarge to be displayed.")))
n = n + 1
formspec = formspec.."label["
..tostring(2)..","..tostring(formspecy)
..";"..minetest.formspec_escape(S("This recipe is too\nlarge to be displayed.")).."]"
end
if craft_type.uses_crafting_grid and display_size.width <= 3 then
formspec[n] = "label["..(give_x+0.1)..",".. (craftguidey + 1.7) .. ";" .. F(S("To craft grid:")) .. "]"
formspec[n+1] = "button[".. (give_x)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_1;1]"
formspec[n+2] = "button[".. (give_x+0.8)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_10;10]"
formspec[n+3] = "button[".. (give_x+1.6)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_max;" .. F(S("All")) .. "]"
n = n + 4
formspec = formspec.."label[0,"..(formspecy + 0.9)..";" .. F("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("All") .. "]"
end
if has_give then
formspec[n] = giveme_form
n = n + 1
if player_privs.give then
formspec = formspec.."label[0,"..(formspecy + 2.1)..";" .. F("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
formspec[n] = string.format("label[%f,%f;%s]",
craftguidex+4, craftguidey + 2.3, F(S(recipe_text[dir], alternate, alternates)))
formspec[n+1] = string.format("image_button[%f,%f;1.1,1.1;ui_left_icon.png;alternate_prev;]",
craftguidearrowx+0.2, craftguidey + 2.6)
formspec[n+2] = string.format("image_button[%f,%f;1.1,1.1;ui_right_icon.png;alternate;]",
craftguidearrowx+1.35, craftguidey + 2.6)
formspec[n+3] = "tooltip[alternate_prev;" .. F(prev_alt_text[dir]) .. "]"
formspec[n+4] = "tooltip[alternate;" .. F(next_alt_text[dir]) .. "]"
formspec = formspec.."label[5.5,"..(formspecy + 1.6)..";"
..string.format(F(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(formspec) }
return {formspec = formspec}
end,
})
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 ui.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_giveme_(.*)")
if amount then break end
end
if not amount then return end
amount = tonumber(amount) or 0
amount = tonumber(amount)
if amount == 0 then return end
local output = ui.current_item[player_name]
local player_name = player:get_player_name()
local output = unified_inventory.current_item[player_name]
if (not output) or (output == "") then return end
local player_inv = player:get_inventory()
@ -477,6 +410,80 @@ local function craftguide_giveme(player, formname, fields)
player_inv:add_item("main", {name = output, count = amount})
end
-- tells if an item can be moved and returns an index if so
local function item_fits(player_inv, craft_item, needed_item)
local need_group = string.sub(needed_item, 1, 6) == "group:"
if need_group then
need_group = string.sub(needed_item, 7)
end
if craft_item
and not craft_item:is_empty() then
local ciname = craft_item:get_name()
-- abort if the item there isn't usable
if ciname ~= needed_item
and not need_group then
return
end
-- abort if no item fits onto it
if craft_item:get_count() >= craft_item:get_definition().stack_max then
return
end
-- use the item there if it's in the right group and a group item is needed
if need_group then
if minetest.get_item_group(ciname, need_group) == 0 then
return
end
needed_item = ciname
need_group = false
end
end
if need_group then
-- search an item of the specific group
for i,item in pairs(player_inv:get_list("main")) do
if not item:is_empty()
and minetest.get_item_group(item:get_name(), need_group) > 0 then
return i
end
end
-- no index found
return
end
-- search an item with a the name needed_item
for i,item in pairs(player_inv:get_list("main")) do
if not item:is_empty()
and item:get_name() == needed_item then
return i
end
end
-- no index found
end
-- modifies the player inventory and returns the changed craft_item if possible
local function move_item(player_inv, craft_item, needed_item)
local stackid = item_fits(player_inv, craft_item, needed_item)
if not stackid then
return
end
local wanted_stack = player_inv:get_stack("main", stackid)
local taken_item = wanted_stack:take_item()
player_inv:set_stack("main", stackid, wanted_stack)
if not craft_item
or craft_item:is_empty() then
return taken_item
end
craft_item:add_item(taken_item)
return craft_item
end
local function craftguide_craft(player, formname, fields)
local amount
for k, v in pairs(fields) do
@ -484,42 +491,63 @@ local function craftguide_craft(player, formname, fields)
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 = ui.current_item[player_name] or ""
if output == "" then return end
local output = unified_inventory.current_item[player_name]
if (not output) or (output == "") then return end
local crafts = ui.crafts_for[
ui.current_craft_direction[player_name]][output] or {}
if #crafts == 0 then return end
local player_inv = player:get_inventory()
local alternate = ui.alternate[player_name]
local crafts = unified_inventory.crafts_for[unified_inventory.current_craft_direction[player_name]][output]
if (not crafts) or (#crafts == 0) then return end
local alternate = unified_inventory.alternate[player_name]
local craft = crafts[alternate]
if not craft.width then
if not craft.output then
minetest.log("warning", "[unified_inventory] Craft has no output.")
else
minetest.log("warning", ("[unified_inventory] Craft for '%s' has no width."):format(craft.output))
end
return
end
if craft.width > 3 then return end
ui.craftguide_match_craft(player, "main", "craft", craft, amount)
local needed = craft.items
ui.set_inventory_formspec(player, "craft")
local craft_list = player_inv:get_list("craft")
local width = craft.width
if width == 0 then
-- Shapeless recipe
width = 3
end
amount = tonumber(amount) or 99
--[[
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]
local newitem = move_item(player_inv, craft_item, needed_item)
if newitem then
craft_list[craft_index] = newitem
end
end
index = index + 1
end
end
end
player_inv:set_list("craft", craft_list)
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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -1,36 +0,0 @@
# Reduced formspec layout, optimized for smaller displays.
# Note: This may also disable some features to free up visual space.
unified_inventory_lite (Lite mode) bool false
# Provides craftable bag items to extend the inventory space.
unified_inventory_bags (Enable bags) bool true
# Shows the trash slot to everyone.
# When disabled, only players with the privilege "creative" or "give" will
# have this slot shown in their inventory.
unified_inventory_trash (Enable trash) bool true
# Provides waypoints on a per-player basis to remember positions on the map.
unified_inventory_waypoints (Enable waypoints) bool true
# If enabled, disabled buttons will be hidden instead of grayed out.
unified_inventory_hide_disabled_buttons (Hide disabled buttons) bool false
# Hides items with no known craft recipe from the category "all" (default).
# This setting has no effect on players in creative mode.
unified_inventory_hide_uncraftable_items (Hide uncraftable items) bool false
# Automatically categorizes registered items based on their
# groups. This is based on a fuzzy match, thus is not 100% accurate.
unified_inventory_automatic_categorization (Categories: add items automatically) bool true
# Shows the selected wielded item description in the HUD for a few seconds.
unified_inventory_item_names (Enable HUD item names) bool true
# Trims the shown wielded item description to the first line.
unified_inventory_only_names (HUD item name: first line only) bool true
# Hard character limit of the wielded item description.
# Crops the shown description to the specified length.
# 0 disables this functionality.
unified_inventory_max_item_name_length (HUD item names: character limit) int 80

BIN
sounds/birds.ogg Executable file

Binary file not shown.

BIN
sounds/click.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/dingdong.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/electricity.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/owl.ogg Executable file

Binary file not shown.

BIN
sounds/paperflip1.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/paperflip2.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/teleport.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/trash.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/trash_all.ogg Normal file → Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
textures/bags_large.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
textures/bags_medium.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
textures/bags_small.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 358 B

BIN
textures/ui_2_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 961 B

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 B

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 727 B

BIN
textures/ui_bags_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
textures/ui_bags_lg_form.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

BIN
textures/ui_bags_main_form.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 B

BIN
textures/ui_bags_med_form.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

BIN
textures/ui_bags_sm_form.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

BIN
textures/ui_blank_image.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

BIN
textures/ui_circular_arrows_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 543 B

BIN
textures/ui_form_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 234 B

BIN
textures/ui_group.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 509 B

Some files were not shown because too many files have changed in this diff Show More