Compare commits

..

No commits in common. "master" and "version-1" have entirely different histories.

58 changed files with 1057 additions and 3066 deletions

View File

@ -10,12 +10,10 @@ read_globals = {
string = {fields = {"split", "trim"}}, string = {fields = {"split", "trim"}},
table = {fields = {"copy", "getn"}}, table = {fields = {"copy", "getn"}},
"dump",
"minetest", "vector", "minetest", "vector",
"ItemStack", "datastorage", "ItemStack", "datastorage",
"hb", "hb",
"doors",
} }
files["callbacks.lua"].ignore = { "player", "draw_lite_mode" } files["callbacks.lua"].ignore = { "player", "draw_lite_mode" }

View File

@ -15,8 +15,7 @@ Unified Inventory replaces the default survival and creative inventory.
* Recipe search function by ingredients * Recipe search function by ingredients
* Up to four bags with up to 24 slots each * Up to four bags with up to 24 slots each
* Home function to teleport * Home function to teleport
* Trash slot and refill slot for creative * Trash slot
* Waypoints to keep track of important locations
* Lite mode: reduces the item browser width * Lite mode: reduces the item browser width
* `minetest.conf` setting `unified_inventory_lite = true` * `minetest.conf` setting `unified_inventory_lite = true`
* Mod API for modders: see [mod_api.txt](doc/mod_api.txt) * Mod API for modders: see [mod_api.txt](doc/mod_api.txt)
@ -25,11 +24,7 @@ Unified Inventory replaces the default survival and creative inventory.
## Requirements ## Requirements
* Minetest 5.4.0+ * Minetest 5.0.0+
* Mod `default` for category filters (contained in Minetest Game)
* Mod `farming` for craftable bags (contained in Minetest Game)
* For waypoint migration: `datastorage`
# Licenses # Licenses
@ -71,9 +66,6 @@ From http://www.clker.com (Public Domain, CC-BY-4.0):
* [`ui_pencil_icon.pnc`](http://www.clker.com/clipart-2256.html) * [`ui_pencil_icon.pnc`](http://www.clker.com/clipart-2256.html)
* [`ui_waypoint_set_icon.png`](http://www.clker.com/clipart-larger-flag.html) * [`ui_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+): Everaldo Coelho (YellowIcon) (LGPL v2.1+):
* [`ui_craftguide_icon.png` / `ui_craft_icon.png`](http://commons.wikimedia.org/wiki/File:Advancedsettings.png) * [`ui_craftguide_icon.png` / `ui_craft_icon.png`](http://commons.wikimedia.org/wiki/File:Advancedsettings.png)
@ -105,16 +97,3 @@ Other files from Wikimedia Commons:
RealBadAngel: (CC-BY-4.0) RealBadAngel: (CC-BY-4.0)
* Everything else. * 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)

286
api.lua
View File

@ -1,69 +1,55 @@
local S = minetest.get_translator("unified_inventory") local S = minetest.get_translator("unified_inventory")
local F = minetest.formspec_escape local F = minetest.formspec_escape
local ui = unified_inventory
local function is_recipe_craftable(recipe)
-- Ensure the ingedients exist
for _, itemname in pairs(recipe.items) do
local groups = string.find(itemname, "group:")
if groups then
if not ui.get_group_item(string.sub(groups, 8)).item then
return false
end
else
-- Possibly an item
local itemname_cleaned = ItemStack(itemname):get_name()
if not minetest.registered_items[itemname_cleaned]
or minetest.get_item_group(itemname_cleaned, "not_in_craft_guide") ~= 0 then
return false
end
end
end
return true
end
-- Create detached creative inventory after loading all mods -- Create detached creative inventory after loading all mods
minetest.after(0.01, function() minetest.after(0.01, function()
local rev_aliases = {} local rev_aliases = {}
for original, newname in pairs(minetest.registered_aliases) do for source, target in pairs(minetest.registered_aliases) do
if not rev_aliases[newname] then if not rev_aliases[target] then rev_aliases[target] = {} end
rev_aliases[newname] = {} table.insert(rev_aliases[target], source)
end
table.insert(rev_aliases[newname], original)
end end
unified_inventory.items_list = {}
-- Filtered item list
ui.items_list = {}
for name, def in pairs(minetest.registered_items) do for name, def in pairs(minetest.registered_items) do
if ui.is_itemdef_listable(def) then if (not def.groups.not_in_creative_inventory or
table.insert(ui.items_list, name) def.groups.not_in_creative_inventory == 0) and
def.description and def.description ~= "" then
-- Alias processing: Find recipes that belong to the current item name table.insert(unified_inventory.items_list, name)
local all_names = rev_aliases[name] or {} local all_names = rev_aliases[name] or {}
table.insert(all_names, name) table.insert(all_names, name)
for _, itemname in ipairs(all_names) do for _, player_name in ipairs(all_names) do
local recipes = minetest.get_all_craft_recipes(itemname) local recipes = minetest.get_all_craft_recipes(player_name)
for _, recipe in ipairs(recipes or {}) do if recipes then
if is_recipe_craftable(recipe) then for _, recipe in ipairs(recipes) do
ui.register_craft(recipe)
local unknowns
for _,chk in pairs(recipe.items) do
local groupchk = string.find(chk, "group:")
if (not groupchk and not minetest.registered_items[chk])
or (groupchk and not unified_inventory.get_group_item(string.gsub(chk, "group:", "")).item)
or minetest.get_item_group(chk, "not_in_craft_guide") ~= 0 then
unknowns = true
end
end
if not unknowns then
unified_inventory.register_craft(recipe)
end
end end
end end
end end
end end
end end
table.sort(unified_inventory.items_list)
table.sort(ui.items_list) unified_inventory.items_list_size = #unified_inventory.items_list
ui.items_list_size = #ui.items_list print("Unified Inventory. inventory size: "..unified_inventory.items_list_size)
print("Unified Inventory. Inventory size: "..ui.items_list_size) for _, name in ipairs(unified_inventory.items_list) do
-- Analyse dropped items -> custom "digging" recipes
for _, name in ipairs(ui.items_list) do
local def = minetest.registered_items[name] local def = minetest.registered_items[name]
-- Simple drops -- Simple drops
if type(def.drop) == "string" then if type(def.drop) == "string" then
local dstack = ItemStack(def.drop) local dstack = ItemStack(def.drop)
if not dstack:is_empty() and dstack:get_name() ~= name then if not dstack:is_empty() and dstack:get_name() ~= name then
ui.register_craft({ unified_inventory.register_craft({
type = "digging", type = "digging",
items = {name}, items = {name},
output = def.drop, output = def.drop,
@ -129,7 +115,7 @@ minetest.after(0.01, function()
end end
end end
for itemstring, count in pairs(drop_guaranteed) do for itemstring, count in pairs(drop_guaranteed) do
ui.register_craft({ unified_inventory.register_craft({
type = "digging", type = "digging",
items = {name}, items = {name},
output = itemstring .. " " .. count, output = itemstring .. " " .. count,
@ -137,7 +123,7 @@ minetest.after(0.01, function()
}) })
end end
for itemstring, count in pairs(drop_maybe) do for itemstring, count in pairs(drop_maybe) do
ui.register_craft({ unified_inventory.register_craft({
type = "digging_chance", type = "digging_chance",
items = {name}, items = {name},
output = itemstring .. " " .. count, output = itemstring .. " " .. count,
@ -146,86 +132,33 @@ minetest.after(0.01, function()
end end
end end
end end
for _, recipes in pairs(unified_inventory.crafts_for.recipe) do
-- 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 _, recipe in ipairs(recipes) do for _, recipe in ipairs(recipes) do
local ingredient_items = {} local ingredient_items = {}
for _, spec in pairs(recipe.items) do for _, spec in pairs(recipe.items) do
-- Get items that fit into this spec (group or item name) local matches_spec = unified_inventory.canonical_item_spec_matcher(spec)
local specname = ItemStack(spec):get_name() for _, name in ipairs(unified_inventory.items_list) do
for item_name, _ in pairs(get_matching_spec_items(specname)) do if matches_spec(name) then
ingredient_items[item_name] = true ingredient_items[name] = true
end
end end
end end
for name, _ in pairs(ingredient_items) do for name, _ in pairs(ingredient_items) do
if not ui.crafts_for.usage[name] then if unified_inventory.crafts_for.usage[name] == nil then
ui.crafts_for.usage[name] = {} unified_inventory.crafts_for.usage[name] = {}
end end
table.insert(ui.crafts_for.usage[name], recipe) table.insert(unified_inventory.crafts_for.usage[name], recipe)
end
if next(ingredient_items) then
-- There's at least one known ingredient: mark as good recipe
-- PS: What whatll be done about partially incomplete recipes?
table.insert(new_recipe_list, recipe)
end end
end end
ui.crafts_for.recipe[outputitemname] = new_recipe_list
end
-- Remove unknown items from all categories
local total_removed = 0
for cat_name, cat_def in pairs(ui.registered_category_items) do
for itemname, _ in pairs(cat_def) do
local idef = minetest.registered_items[itemname]
if not idef then
total_removed = total_removed + 1
--[[
-- For analysis
minetest.log("warning", "[unified_inventory] Removed item '"
.. itemname .. "' from category '" .. cat_name
.. "'. Reason: item not registered")
]]
cat_def[itemname] = nil
elseif not ui.is_itemdef_listable(idef) then
total_removed = total_removed + 1
--[[
-- For analysis
minetest.log("warning", "[unified_inventory] Removed item '"
.. itemname .. "' from category '" .. cat_name
.. "'. Reason: item is in 'not_in_creative_inventory' group")
]]
cat_def[itemname] = nil
end
end
end
if total_removed > 0 then
minetest.log("info", "[unified_inventory] Removed " .. total_removed ..
" items from the categories.")
end
for _, callback in ipairs(ui.initialized_callbacks) do
callback()
end end
end) end)
---------------- Home API ----------------
-- load_home
local function 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 if not input then
ui.home_pos = {} unified_inventory.home_pos = {}
return return
end end
while true do while true do
@ -234,32 +167,25 @@ local function load_home()
local y = input:read("*n") local y = input:read("*n")
local z = input:read("*n") local z = input:read("*n")
local name = input:read("*l") 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 end
io.close(input) io.close(input)
end end
load_home() load_home()
function ui.set_home(player, pos) function unified_inventory.set_home(player, pos)
local player_name = player:get_player_name() 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 -- save the home data from the table to the file
local output = io.open(ui.home_filename, "w") local output = io.open(unified_inventory.home_filename, "w")
if not output then for k, v in pairs(unified_inventory.home_pos) do
minetest.log("warning", "[unified_inventory] Failed to save file: "
.. ui.home_filename)
return
end
for k, v in pairs(ui.home_pos) do
output:write(v.x.." "..v.y.." "..v.z.." "..k.."\n") output:write(v.x.." "..v.y.." "..v.z.." "..k.."\n")
end end
io.close(output) io.close(output)
end end
function ui.go_home(player) function unified_inventory.go_home(player)
local pos = ui.home_pos[player:get_player_name()] local pos = unified_inventory.home_pos[player:get_player_name()]
if pos then if pos then
player:set_pos(pos) player:set_pos(pos)
return true return true
@ -267,9 +193,8 @@ function ui.go_home(player)
return false return false
end end
---------------- Crafting API ---------------- -- register_craft
function unified_inventory.register_craft(options)
function ui.register_craft(options)
if not options.output then if not options.output then
return return
end end
@ -280,24 +205,21 @@ function ui.register_craft(options)
if options.type == "normal" and options.width == 0 then if options.type == "normal" and options.width == 0 then
options = { type = "shapeless", items = options.items, output = options.output, width = 0 } options = { type = "shapeless", items = options.items, output = options.output, width = 0 }
end end
local item_name = itemstack:get_name() if not unified_inventory.crafts_for.recipe[itemstack:get_name()] then
if not ui.crafts_for.recipe[item_name] then unified_inventory.crafts_for.recipe[itemstack:get_name()] = {}
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)
end end
table.insert(unified_inventory.crafts_for.recipe[itemstack:get_name()],options)
end end
local craft_type_defaults = { local craft_type_defaults = {
width = 3, width = 3,
height = 3, height = 3,
uses_crafting_grid = false, uses_crafting_grid = false,
} }
function ui.craft_type_defaults(name, options)
function unified_inventory.craft_type_defaults(name, options)
if not options.description then if not options.description then
options.description = name options.description = name
end end
@ -306,12 +228,13 @@ function ui.craft_type_defaults(name, options)
end end
function ui.register_craft_type(name, options) function unified_inventory.register_craft_type(name, options)
ui.registered_craft_types[name] = ui.craft_type_defaults(name, options) unified_inventory.registered_craft_types[name] =
unified_inventory.craft_type_defaults(name, options)
end end
ui.register_craft_type("normal", { unified_inventory.register_craft_type("normal", {
description = F(S("Crafting")), description = F(S("Crafting")),
icon = "ui_craftgrid_icon.png", icon = "ui_craftgrid_icon.png",
width = 3, width = 3,
@ -327,7 +250,7 @@ ui.register_craft_type("normal", {
}) })
ui.register_craft_type("shapeless", { unified_inventory.register_craft_type("shapeless", {
description = F(S("Mixing")), description = F(S("Mixing")),
icon = "ui_craftgrid_icon.png", icon = "ui_craftgrid_icon.png",
width = 3, width = 3,
@ -342,7 +265,7 @@ ui.register_craft_type("shapeless", {
}) })
ui.register_craft_type("cooking", { unified_inventory.register_craft_type("cooking", {
description = F(S("Cooking")), description = F(S("Cooking")),
icon = "default_furnace_front.png", icon = "default_furnace_front.png",
width = 1, width = 1,
@ -350,96 +273,37 @@ ui.register_craft_type("cooking", {
}) })
ui.register_craft_type("digging", { unified_inventory.register_craft_type("digging", {
description = F(S("Digging")), description = F(S("Digging")),
icon = "default_tool_steelpick.png", icon = "default_tool_steelpick.png",
width = 1, width = 1,
height = 1, height = 1,
}) })
ui.register_craft_type("digging_chance", { unified_inventory.register_craft_type("digging_chance", {
description = "Digging (by chance)", description = "Digging (by chance)",
icon = "default_tool_steelpick.png^[transformFY.png", icon = "default_tool_steelpick.png^[transformFY.png",
width = 1, width = 1,
height = 1, height = 1,
}) })
---------------- GUI registrations ---------------- function unified_inventory.register_page(name, def)
unified_inventory.pages[name] = def
function ui.register_page(name, def)
ui.pages[name] = def
end end
function ui.register_button(name, def) function unified_inventory.register_button(name, def)
if not def.action then if not def.action then
def.action = function(player) def.action = function(player)
ui.set_inventory_formspec(player, name) unified_inventory.set_inventory_formspec(player, name)
end end
end end
def.name = name def.name = name
table.insert(ui.buttons, def) table.insert(unified_inventory.buttons, def)
end end
---------------- Callback registrations ----------------
function ui.register_on_initialized(callback) function unified_inventory.is_creative(playername)
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)
return minetest.check_player_privs(playername, {creative=true}) return minetest.check_player_privs(playername, {creative=true})
or minetest.settings:get_bool("creative_mode") or minetest.settings:get_bool("creative_mode")
end 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

179
bags.lua
View File

@ -7,36 +7,33 @@ License: GPLv3
local S = minetest.get_translator("unified_inventory") local S = minetest.get_translator("unified_inventory")
local F = minetest.formspec_escape local F = minetest.formspec_escape
local ui = unified_inventory local bags_inv_bg_prefix = "image[-0.1,1.0;10.05,"
ui.register_page("bags", { unified_inventory.register_page("bags", {
get_formspec = function(player, perplayer_formspec) get_formspec = function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
local std_inv_x = perplayer_formspec.std_inv_x return { formspec = table.concat({
local formspec = { string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4"),
perplayer_formspec.standard_inv_bg, bags_inv_bg_prefix.."1.175;ui_bags_header.png]",
"label[", perplayer_formspec.form_header_x, ",", "label[0,0;" .. F(S("Bags")) .. "]",
perplayer_formspec.form_header_y, ";", F(S("Bags")), "]", "button[0,2.2;2,0.5;bag1;" .. F(S("Bag @1", 1)) .. "]",
"button[2,2.2;2,0.5;bag2;" .. F(S("Bag @1", 2)) .. "]",
"button[4,2.2;2,0.5;bag3;" .. F(S("Bag @1", 3)) .. "]",
"button[6,2.2;2,0.5;bag4;" .. F(S("Bag @1", 4)) .. "]",
"listcolors[#00000000;#00000000]", "listcolors[#00000000;#00000000]",
} "list[detached:" .. F(player_name) .. "_bags;bag1;0.5,1.1;1,1;]",
"list[detached:" .. F(player_name) .. "_bags;bag2;2.5,1.1;1,1;]",
for i = 1, 4 do "list[detached:" .. F(player_name) .. "_bags;bag3;4.5,1.1;1,1;]",
local x = std_inv_x + i * 2.5 "list[detached:" .. F(player_name) .. "_bags;bag4;6.5,1.1;1,1;]"
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) }
end, end,
}) })
ui.register_button("bags", { unified_inventory.register_button("bags", {
type = "image", type = "image",
image = "ui_bags_icon.png", image = "ui_bags_icon.png",
tooltip = S("Bags"), tooltip = S("Bags"),
hide_lite=true
}) })
local function get_player_bag_stack(player, i) local function get_player_bag_stack(player, i)
@ -47,46 +44,33 @@ local function get_player_bag_stack(player, i)
end end
for bag_i = 1, 4 do for bag_i = 1, 4 do
ui.register_page("bag" .. bag_i, { unified_inventory.register_page("bag" .. bag_i, {
get_formspec = function(player, perplayer_formspec) get_formspec = function(player)
local stack = get_player_bag_stack(player, bag_i) local stack = get_player_bag_stack(player, bag_i)
local image = stack:get_definition().inventory_image local image = stack:get_definition().inventory_image
local slots = stack:get_definition().groups.bagslots local fs = {
local std_inv_x = perplayer_formspec.std_inv_x string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4"),
local lite_mode = perplayer_formspec.is_lite_mode "image[7,0;1,1;" .. image .. "]",
"label[0,0;" .. F(S("Bag @1", bag_i)) .. "]",
local bag_inv_y, header_x, header_y = 1.5, 0.3, 0.65
if lite_mode then
bag_inv_y = 0.5
header_x = perplayer_formspec.form_header_x
header_y = perplayer_formspec.form_header_y
end
local formspec = {
perplayer_formspec.standard_inv_bg,
ui.make_inv_img_grid(std_inv_x, bag_inv_y, 8, slots/8),
"label[", header_x, ",", header_y, ";", F(S("Bag @1", bag_i)), "]",
"listcolors[#00000000;#00000000]", "listcolors[#00000000;#00000000]",
"list[current_player;bag" .. bag_i .. "contents;0,1.1;8,3;]",
"listring[current_name;bag" .. bag_i .. "contents]",
"listring[current_player;main]", "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]",
} }
local slots = stack:get_definition().groups.bagslots
if lite_mode then if slots == 8 then
return { formspec = table.concat(formspec) } fs[#fs + 1] = bags_inv_bg_prefix.."1.175;ui_bags_inv_small.png]"
elseif slots == 16 then
fs[#fs + 1] = bags_inv_bg_prefix.."2.35;ui_bags_inv_medium.png]"
elseif slots == 24 then
fs[#fs + 1] = bags_inv_bg_prefix.."3.525;ui_bags_inv_large.png]"
end 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. local player_name = player:get_player_name() -- For if statement.
if ui.trash_enabled if unified_inventory.trash_enabled
or ui.is_creative(player_name) or unified_inventory.is_creative(player_name)
or minetest.get_player_privs(player_name).give then or minetest.get_player_privs(player_name).give then
formspec[n] = ui.make_trash_slot(7.8, 0.25) fs[#fs + 1] = "image[5.91,-0.06;1.21,1.15;ui_bags_trash.png]"
n = n + 1 .. "list[detached:trash;main;6,0.1;1,1;]"
end end
local inv = player:get_inventory() local inv = player:get_inventory()
for i = 1, 4 do for i = 1, 4 do
@ -103,12 +87,11 @@ for bag_i = 1, 4 do
end end
local img = def.inventory_image local img = def.inventory_image
local label = F(S("Bag @1", i)) .. "\n" .. used .. "/" .. size 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]", fs[#fs + 1] = string.format("image_button[%i,0;1,1;%s;bag%i;%s]",
(i + 1.35)*1.25, img, i, label) i + 1, img, i, label)
n = n + 1
end end
end end
return { formspec = table.concat(formspec) } return { formspec = table.concat(fs) }
end, end,
}) })
end end
@ -123,14 +106,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if not stack:get_definition().groups.bagslots then if not stack:get_definition().groups.bagslots then
return return
end end
ui.set_inventory_formspec(player, "bag" .. i) unified_inventory.set_inventory_formspec(player, "bag" .. i)
return return
end end
end 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 function save_bags_metadata(player, bags_inv)
local is_empty = true local is_empty = true
local bags = {} local bags = {}
@ -144,7 +125,7 @@ local function save_bags_metadata(player, bags_inv)
end end
local meta = player:get_meta() local meta = player:get_meta()
if is_empty then if is_empty then
meta:set_string("unified_inventory:bags", "") meta:set_string("unified_inventory:bags", nil)
else else
meta:set_string("unified_inventory:bags", meta:set_string("unified_inventory:bags",
minetest.serialize(bags)) minetest.serialize(bags))
@ -180,7 +161,7 @@ local function load_bags_metadata(player, bags_inv)
save_bags_metadata(player, bags_inv) save_bags_metadata(player, bags_inv)
end end
-- Legacy: Clean up old player lists -- Clean up deprecated garbage after saving
for i = 1, 4 do for i = 1, 4 do
local bag = "bag" .. i local bag = "bag" .. i
player_inv:set_size(bag, 0) player_inv:set_size(bag, 0)
@ -189,29 +170,46 @@ end
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
local bags_inv = minetest.create_detached_inventory(player_name .. "_bags", { local bags_inv = minetest.create_detached_inventory(player_name .. "_bags",{
allow_put = function(inv, listname, index, stack, player)
local new_slots = stack:get_definition().groups.bagslots
if not new_slots then
return 0 -- ItemStack is not a bag.
end
-- The execution order of `allow_put`/`allow_take` is not defined.
-- We do not know the replacement ItemStack if the items are swapped.
-- Hence, bag slot upgrades and downgrades are not possible with the
-- current API.
if not player:get_inventory():is_empty(listname .. "contents") then
-- Legacy: in case `allow_take` is not executed on old Minetest versions.
return 0
end
return 1
end,
on_put = function(inv, listname, index, stack, player) on_put = function(inv, listname, index, stack, player)
player:get_inventory():set_size(listname .. "contents", player:get_inventory():set_size(listname .. "contents",
stack:get_definition().groups.bagslots) stack:get_definition().groups.bagslots)
save_bags_metadata(player, inv) save_bags_metadata(player, inv)
end, end,
allow_put = function(inv, listname, index, stack, player)
local new_slots = stack:get_definition().groups.bagslots
if not new_slots then
return 0
end
local player_inv = player:get_inventory()
local old_slots = player_inv:get_size(listname .. "contents")
if new_slots >= old_slots then
return 1
end
-- using a smaller bag, make sure it fits
local old_list = player_inv:get_list(listname .. "contents")
local new_list = {}
local slots_used = 0
local use_new_list = false
for i, v in ipairs(old_list) do
if v and not v:is_empty() then
slots_used = slots_used + 1
use_new_list = i > new_slots
new_list[slots_used] = v
end
end
if new_slots >= slots_used then
if use_new_list then
player_inv:set_list(listname .. "contents", new_list)
end
return 1
end
-- New bag is smaller: Disallow inserting
return 0
end,
allow_take = function(inv, listname, index, stack, player) allow_take = function(inv, listname, index, stack, player)
if player:get_inventory():is_empty(listname .. "contents") then if player:get_inventory():is_empty(listname .. "contents") then
return stack:get_count() return stack:get_count()
@ -221,11 +219,6 @@ minetest.register_on_joinplayer(function(player)
on_take = function(inv, listname, index, stack, player) on_take = function(inv, listname, index, stack, player)
player:get_inventory():set_size(listname .. "contents", 0) player:get_inventory():set_size(listname .. "contents", 0)
save_bags_metadata(player, inv) 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, end,
allow_move = function() allow_move = function()
return 0 return 0
@ -235,20 +228,6 @@ minetest.register_on_joinplayer(function(player)
load_bags_metadata(player, bags_inv) load_bags_metadata(player, bags_inv)
end) end)
minetest.register_allow_player_inventory_action(function(player, action, inventory, info)
-- From detached inventory -> player inventory: put & take callbacks
if action ~= "put" or not info.listname:find("bag%dcontents") then
return
end
if info.stack:get_definition().groups.bagslots then
-- Problem 1: empty bags could be moved into their own slots
-- Problem 2: cannot reliably keep track of ItemStack ownership due to
--> Disallow all external bag movements into this list
return 0
end
end)
-- register bag tools -- register bag tools
minetest.register_tool("unified_inventory:bag_small", { minetest.register_tool("unified_inventory:bag_small", {
description = S("Small Bag"), description = S("Small Bag"),

View File

@ -1,5 +1,3 @@
local ui = unified_inventory
local function default_refill(stack) local function default_refill(stack)
stack:set_count(stack:get_stack_max()) stack:set_count(stack:get_stack_max())
local itemdef = minetest.registered_items[stack:get_name()] local itemdef = minetest.registered_items[stack:get_name()]
@ -14,17 +12,18 @@ end
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
unified_inventory.players[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.filtered_items_list[player_name] =
unified_inventory.items_list unified_inventory.items_list
unified_inventory.activefilter[player_name] = "" unified_inventory.activefilter[player_name] = ""
unified_inventory.active_search_direction[player_name] = "nochange" unified_inventory.active_search_direction[player_name] = "nochange"
unified_inventory.apply_filter(player, "", "nochange")
unified_inventory.current_searchbox[player_name] = "" 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.alternate[player_name] = 1
unified_inventory.current_item[player_name] = nil unified_inventory.current_item[player_name] = nil
unified_inventory.current_craft_direction[player_name] = "recipe" unified_inventory.current_craft_direction[player_name] = "recipe"
unified_inventory.set_inventory_formspec(player,
unified_inventory.default)
-- Refill slot -- Refill slot
local refill = minetest.create_detached_inventory(player_name.."refill", { local refill = minetest.create_detached_inventory(player_name.."refill", {
@ -46,92 +45,34 @@ minetest.register_on_joinplayer(function(player)
refill:set_size("main", 1) refill:set_size("main", 1)
end) 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 function apply_new_filter(player, search_text, new_dir)
local player_name = player:get_player_name() local player_name = player:get_player_name()
minetest.sound_play("click", {to_player=player_name, gain = 0.1})
minetest.sound_play("ui_click", {to_player=player_name, gain = 0.1}) unified_inventory.apply_filter(player, search_text, new_dir)
ui.apply_filter(player, search_text, new_dir) unified_inventory.current_searchbox[player_name] = search_text
ui.current_searchbox[player_name] = search_text unified_inventory.set_inventory_formspec(player,
ui.set_inventory_formspec(player, ui.current_page[player_name]) unified_inventory.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 end
minetest.register_on_player_receive_fields(function(player, formname, fields) 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 player_name = player:get_player_name()
local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name) local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
local clicked_category if formname ~= "" then
for name, value in pairs(fields) do return
local category_name = string.match(name, "^category_(.+)$")
if category_name then
clicked_category = category_name
break
end
end end
if clicked_category -- always take new search text, even if not searching on it yet
and clicked_category ~= unified_inventory.current_category[player_name] then if fields.searchbox
unified_inventory.current_category[player_name] = clicked_category and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange") unified_inventory.current_searchbox[player_name] = fields.searchbox
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
end
if fields.next_category or fields.prev_category then
local step = fields.next_category and 1 or -1
local scroll_old = ui.current_category_scroll[player_name]
local scroll_new = math.max(0, math.min(#ui.category_list - ui_peruser.pagecols, scroll_old + step))
if scroll_old ~= scroll_new then
ui.current_category_scroll[player_name] = scroll_new
ui.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
end
end end
for i, def in pairs(unified_inventory.buttons) do for i, def in pairs(unified_inventory.buttons) do
if fields[def.name] then if fields[def.name] then
def.action(player) def.action(player)
minetest.sound_play("ui_click", minetest.sound_play("click",
{to_player=player_name, gain = 0.1}) {to_player=player_name, gain = 0.1})
return return
end end
@ -180,12 +121,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
-- Check clicked item image button -- Check clicked item image button
local clicked_item local clicked_item
for name, value in pairs(fields) do for name, value in pairs(fields) do
local new_dir, mangled_item = string.match(name, "^[0-9]*_?item_button_([a-z]+)_(.*)$") local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$")
if new_dir and mangled_item then if new_dir and mangled_item then
clicked_item = unified_inventory.demangle_for_formspec(mangled_item) clicked_item = unified_inventory.demangle_for_formspec(mangled_item)
if string.sub(clicked_item, 1, 6) == "group:" then if string.sub(clicked_item, 1, 6) == "group:" then
-- Change search filter to this group -- Change search filter to this group
unified_inventory.current_category[player_name] = "all"
apply_new_filter(player, clicked_item, new_dir) apply_new_filter(player, clicked_item, new_dir)
return return
end end
@ -196,7 +136,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
end end
if clicked_item then if clicked_item then
minetest.sound_play("ui_click", minetest.sound_play("click",
{to_player=player_name, gain = 0.1}) {to_player=player_name, gain = 0.1})
local page = unified_inventory.current_page[player_name] local page = unified_inventory.current_page[player_name]
local player_creative = unified_inventory.is_creative(player_name) local player_creative = unified_inventory.is_creative(player_name)
@ -218,11 +158,22 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end end
end end
if fields.searchbutton
or fields.key_enter_field == "searchbox" then
unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange")
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
minetest.sound_play("paperflip2",
{to_player=player_name, gain = 1.0})
elseif fields.searchresetbutton then
apply_new_filter(player, "", "nochange")
end
-- alternate buttons -- alternate buttons
if not (fields.alternate or fields.alternate_prev) then if not (fields.alternate or fields.alternate_prev) then
return return
end end
minetest.sound_play("ui_click", minetest.sound_play("click",
{to_player=player_name, gain = 0.1}) {to_player=player_name, gain = 0.1})
local item_name = unified_inventory.current_item[player_name] local item_name = unified_inventory.current_item[player_name]
if not item_name then if not item_name then
@ -253,8 +204,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
unified_inventory.current_page[player_name]) unified_inventory.current_page[player_name])
end) end)
minetest.register_on_leaveplayer(function(player) if minetest.delete_detached_inventory then
local player_name = player:get_player_name() minetest.register_on_leaveplayer(function(player)
minetest.remove_detached_inventory(player_name.."_bags") local player_name = player:get_player_name()
minetest.remove_detached_inventory(player_name.."refill") minetest.delete_detached_inventory(player_name.."_bags")
end) minetest.delete_detached_inventory(player_name.."craftrecipe")
minetest.delete_detached_inventory(player_name.."refill")
end)
end

View File

@ -1,158 +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)
if type(item) ~= "string" then
minetest.log("warning", "[unified_inventory] Cannot register category item: " .. dump(item))
return
end
ensure_category_exists(category_name)
unified_inventory.registered_category_items[category_name][item] = true
end
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")
local ui = 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")
})
local function register_automatic_categorization()
-- Add biome nodes to environment category
for _,def in pairs(minetest.registered_biomes) do
local env_nodes = {
def.node_riverbed, def.node_top, def.node_filler, def.node_dust,
}
for i,node in pairs(env_nodes) do
if node then
unified_inventory.add_category_item('environment', node)
end
end
end
-- Preparation for ore registration: find all possible drops (digging)
local possible_node_dig_drops = {
-- ["default:stone_with_coal"] = { "default:coal_lump", "mymod:raregem" }
-- Ores may be contained multiple times, depending on drop chances.
}
for itemname, recipes in pairs(ui.crafts_for.usage) do
for _, recipe in ipairs(recipes) do
if recipe.type == "digging" or recipe.type == "digging_chance" then
if not possible_node_dig_drops[itemname] then
possible_node_dig_drops[itemname] = {}
end
local stack = ItemStack(recipe.output)
table.insert(possible_node_dig_drops[itemname], stack:get_name())
end
end
end
-- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment
for _, odef in pairs(minetest.registered_ores) do
local drops = possible_node_dig_drops[odef.ore]
if drops and odef.ore_type == "scatter" then
ui.add_category_item('minerals', odef.ore)
-- Register all possible drops as "minerals"
ui.add_category_items('minerals', drops)
possible_node_dig_drops[odef.ore] = {} -- mask as handled
else
ui.add_category_item('environment', odef.ore)
end
end
-- Add items by item definition
for name, def in pairs(minetest.registered_items) do
local group = def.groups or {}
if not group.not_in_creative_inventory then
if group.stair or
group.slab or
group.wall or
group.fence then
unified_inventory.add_category_item('building', name)
elseif group.flora or
group.flower or
group.seed or
group.leaves or
group.sapling or
group.tree then
unified_inventory.add_category_item('plants', name)
elseif def.type == 'tool' then
unified_inventory.add_category_item('tools', name)
elseif def.liquidtype == 'source' then
unified_inventory.add_category_item('environment', name)
elseif def.light_source and def.light_source > 0 then
unified_inventory.add_category_item('lighting', name)
elseif group.door or
minetest.global_exists("doors") and (
doors.registered_doors and doors.registered_doors[name..'_a'] or
doors.registered_trapdoors and doors.registered_trapdoors[name]
) then
unified_inventory.add_category_item('building', name)
end
end
end
end
if ui.automatic_categorization then
ui.register_on_initialized(register_automatic_categorization)
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",
})
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)
--]]

View File

@ -1,17 +1,8 @@
unified_inventory API unified_inventory API
===================== =====================
This file provides information about the API of unified_inventory 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 Misc functions
-------------- --------------
@ -21,66 +12,6 @@ Grouped by use-case, afterwards sorted alphabetically.
* Checks whether creative is enabled or the player has `creative` * 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 Pages
----- -----
@ -162,61 +93,3 @@ Register a non-standard craft recipe:
-- ^ Same as `minetest.register_recipe` -- ^ 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)

101
group.lua
View File

@ -1,5 +1,29 @@
local S = minetest.get_translator("unified_inventory") local S = minetest.get_translator("unified_inventory")
local ui = unified_inventory
function unified_inventory.canonical_item_spec_matcher(spec)
local specname = ItemStack(spec):get_name()
if specname:sub(1, 6) ~= "group:" then
return function (itemname)
return itemname == specname
end
end
local group_names = specname:sub(7):split(",")
return function (itemname)
local itemdef = minetest.registered_items[itemname]
for _, group_name in ipairs(group_names) do
if (itemdef.groups[group_name] or 0) == 0 then
return false
end
end
return true
end
end
function unified_inventory.item_matches_spec(item, spec)
local itemname = ItemStack(item):get_name()
return unified_inventory.canonical_item_spec_matcher(spec)(itemname)
end
function unified_inventory.extract_groupnames(groupname) function unified_inventory.extract_groupnames(groupname)
local specname = ItemStack(groupname):get_name() local specname = ItemStack(groupname):get_name()
@ -10,6 +34,22 @@ function unified_inventory.extract_groupnames(groupname)
return table.concat(group_names, S(" and ")), #group_names return table.concat(group_names, S(" and ")), #group_names
end end
unified_inventory.registered_group_items = {
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
stone = "default:cobble",
wood = "default:wood",
book = "default:book",
sand = "default:sand",
leaves = "default:leaves",
tree = "default:tree",
vessel = "vessels:glass_bottle",
wool = "wool:white",
}
function unified_inventory.register_group_item(groupname, itemname)
unified_inventory.registered_group_items[groupname] = itemname
end
-- This is used when displaying craft recipes, where an ingredient is -- This is used when displaying craft recipes, where an ingredient is
-- specified by group rather than as a specific item. A single-item group -- specified by group rather than as a specific item. A single-item group
@ -27,7 +67,6 @@ end
-- It may be a comma-separated list of group names. This is really a -- It may be a comma-separated list of group names. This is really a
-- "group:..." ingredient specification, minus the "group:" prefix. -- "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 function compute_group_item(group_name_list)
local group_names = group_name_list:split(",") local group_names = group_name_list:split(",")
local candidate_items = {} local candidate_items = {}
@ -86,61 +125,3 @@ function unified_inventory.get_group_item(group_name)
return group_item_cache[group_name] return group_item_cache[group_name]
end 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

153
init.lua
View File

@ -1,10 +1,4 @@
-- Unified Inventory -- Unified Inventory for Minetest >= 0.4.16
if not minetest.features.formspec_version_element then
-- At least formspec_version[] is the minimal feature requirement
error("Unified Inventory requires Minetest version 5.4.0 or newer.\n" ..
" Please update Minetest or use an older version of Unified Inventory.")
end
local modpath = minetest.get_modpath(minetest.get_current_modname()) local modpath = minetest.get_modpath(minetest.get_current_modname())
local worldpath = minetest.get_worldpath() local worldpath = minetest.get_worldpath()
@ -16,8 +10,6 @@ unified_inventory = {
alternate = {}, alternate = {},
current_page = {}, current_page = {},
current_searchbox = {}, current_searchbox = {},
current_category = {},
current_category_scroll = {},
current_index = {}, current_index = {},
current_item = {}, current_item = {},
current_craft_direction = {}, current_craft_direction = {},
@ -30,8 +22,6 @@ unified_inventory = {
filtered_items_list = {}, filtered_items_list = {},
pages = {}, pages = {},
buttons = {}, buttons = {},
initialized_callbacks = {},
craft_registered_callbacks = {},
-- Homepos stuff -- Homepos stuff
home_pos = {}, home_pos = {},
@ -43,130 +33,23 @@ unified_inventory = {
-- "Lite" mode -- "Lite" mode
lite_mode = minetest.settings:get_bool("unified_inventory_lite"), lite_mode = minetest.settings:get_bool("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
trash_enabled = (minetest.settings:get_bool("unified_inventory_trash") ~= false), 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, pagecols = 8,
pagerows = 9, pagerows = 10,
page_x = 10.75, page_y = 0,
page_y = 2.30, formspec_y = 1,
-- Item browser controls main_button_x = 0,
page_buttons_x = 11.60, main_button_y = 9,
page_buttons_y = 10.15, craft_result_x = 0.3,
searchwidth = 3.4, craft_result_y = 0.5,
-- Crafting grid positions form_header_y = 0,
craft_x = 2.8, standard_background = "background[-0.2,-0.2;1,1;ui_form_bg.png;true]", -- the 'true' scales to fill, overrides the 1,1
craft_y = 1.15, standard_inv = "list[current_player;main;0,YYY;8,4;]", -- the YYY's are placeholders which get
craftresult_x = 7.8, standard_inv_bg = "image[-0.1,YYY;10.05,4.70;ui_main_inventory.png]", -- replaced later by string.gsub()
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,
} }
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 -- Disable default creative inventory
local creative = rawget(_G, "creative") or rawget(_G, "creative_inventory") local creative = rawget(_G, "creative") or rawget(_G, "creative_inventory")
if creative then if creative then
@ -182,8 +65,7 @@ if sfinv then
end end
dofile(modpath.."/group.lua") dofile(modpath.."/group.lua")
dofile(modpath.."/category.lua") dofile(modpath.."/api.lua")
dofile(modpath.."/default-categories.lua")
dofile(modpath.."/internal.lua") dofile(modpath.."/internal.lua")
dofile(modpath.."/callbacks.lua") dofile(modpath.."/callbacks.lua")
dofile(modpath.."/match_craft.lua") dofile(modpath.."/match_craft.lua")
@ -192,10 +74,9 @@ dofile(modpath.."/register.lua")
if minetest.settings:get_bool("unified_inventory_bags") ~= false then if minetest.settings:get_bool("unified_inventory_bags") ~= false then
dofile(modpath.."/bags.lua") dofile(modpath.."/bags.lua")
end end
if minetest.settings:get_bool("unified_inventory_item_names") ~= false then
dofile(modpath.."/item_names.lua") dofile(modpath.."/item_names.lua")
end
if minetest.settings:get_bool("unified_inventory_waypoints") ~= false then if minetest.get_modpath("datastorage") then
dofile(modpath.."/waypoints.lua") dofile(modpath.."/waypoints.lua")
end end
dofile(modpath.."/legacy.lua") -- mod compatibility

View File

@ -1,6 +1,5 @@
local S = minetest.get_translator("unified_inventory") local S = minetest.get_translator("unified_inventory")
local F = minetest.formspec_escape local F = minetest.formspec_escape
local ui = unified_inventory
-- This pair of encoding functions is used where variable text must go in -- This pair of encoding functions is used where variable text must go in
-- button names, where the text might contain formspec metacharacters. -- button names, where the text might contain formspec metacharacters.
@ -10,368 +9,278 @@ local ui = unified_inventory
-- This is a game engine bug, and in the anticipation that it might be -- 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 -- fixed some day we don't want to rely on it. So for safety we apply
-- an encoding that avoids all formspec metacharacters. -- an encoding that avoids all formspec metacharacters.
function unified_inventory.mangle_for_formspec(str)
function ui.mangle_for_formspec(str)
return string.gsub(str, "([^A-Za-z0-9])", function (c) return string.format("_%d_", string.byte(c)) end) return string.gsub(str, "([^A-Za-z0-9])", function (c) return string.format("_%d_", string.byte(c)) end)
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) return string.gsub(str, "_([0-9]+)_", function (v) return string.char(v) end)
end end
-- Get the player-specific unified_inventory style function unified_inventory.get_per_player_formspec(player_name)
function ui.get_per_player_formspec(player_name) local lite = unified_inventory.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true})
local draw_lite_mode = ui.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) local ui = {}
style.is_lite_mode = draw_lite_mode ui.pagecols = unified_inventory.pagecols
return style 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 end
-- Creates an item image or regular image button with a tooltip function unified_inventory.get_formspec(player, page)
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)
if not player then if not player then
return "" return ""
end end
local player_name = player:get_player_name() 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 unified_inventory.current_page[player_name] = page
local pagedef = ui.pages[page] local pagedef = unified_inventory.pages[page]
if not pagedef then if not pagedef then
return "" -- Invalid page name return "" -- Invalid page name
end end
local fs = { local formspec = {
"formspec_version[4]", "size[14,10]",
"size["..ui_peruser.formw..","..ui_peruser.formh.."]",
pagedef.formspec_prepend and "" or "no_prepend[]", pagedef.formspec_prepend and "" or "no_prepend[]",
ui.standard_background unified_inventory.standard_background -- Background
} }
local n = 4
local perplayer_formspec = ui.get_per_player_formspec(player_name) if draw_lite_mode then
formspec[1] = "size[11,7.7]"
formspec[3] = unified_inventory.standard_background
end
if unified_inventory.is_creative(player_name)
and page == "craft" then
formspec[n] = "background[0,"..(ui_peruser.formspec_y + 2)..";1,1;ui_single_slot.png]"
n = n+1
end
local perplayer_formspec = unified_inventory.get_per_player_formspec(player_name)
local fsdata = pagedef.get_formspec(player, perplayer_formspec) 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 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) then
table.insert(filtered_inv_buttons, def)
end
end
for i, def in pairs(filtered_inv_buttons) do
if draw_lite_mode and i > 4 then
button_row = 1
button_col = 1
end
if def.type == "image" then
if (def.condition == nil or def.condition(player) == true) then
formspec[n] = "image_button["
formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4)
formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;"
formspec[n+3] = F(def.image)..";"
formspec[n+4] = F(def.name)..";]"
formspec[n+5] = "tooltip["..F(def.name)
formspec[n+6] = ";"..(def.tooltip or "").."]"
n = n+7
else
formspec[n] = "image["
formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4)
formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;"
formspec[n+3] = F(def.image).."^[colorize:#808080:alpha]"
n = n+4
end
end
end
if fsdata.draw_inventory ~= false then if fsdata.draw_inventory ~= false then
-- Player inventory -- Player inventory
fs[#fs + 1] = "listcolors[#00000000;#00000000]" formspec[n] = "listcolors[#00000000;#00000000]"
fs[#fs + 1] = ui_peruser.standard_inv formspec[n+1] = string.gsub(unified_inventory.standard_inv, "YYY", ui_peruser.formspec_y + 3.5)
n = n+2
end end
if fsdata.draw_item_list == false then if fsdata.draw_item_list == false then
return table.concat(fs, "") return table.concat(formspec, "")
end end
formspec_add_categories(player, fs, ui_peruser) -- Controls to flip items pages
formspec_add_search_box(player, fs, ui_peruser) local start_x = 9.2
formspec_add_item_browser(player, fs, ui_peruser)
return table.concat(fs) if not draw_lite_mode then
formspec[n] =
"image_button[" .. (start_x + 0.6 * 0)
.. ",9;.8,.8;ui_skip_backward_icon.png;start_list;]"
.. "tooltip[start_list;" .. F(S("First page")) .. "]"
.. "image_button[" .. (start_x + 0.6 * 1)
.. ",9;.8,.8;ui_doubleleft_icon.png;rewind3;]"
.. "tooltip[rewind3;" .. F(S("Back three pages")) .. "]"
.. "image_button[" .. (start_x + 0.6 * 2)
.. ",9;.8,.8;ui_left_icon.png;rewind1;]"
.. "tooltip[rewind1;" .. F(S("Back one page")) .. "]"
.. "image_button[" .. (start_x + 0.6 * 3)
.. ",9;.8,.8;ui_right_icon.png;forward1;]"
.. "tooltip[forward1;" .. F(S("Forward one page")) .. "]"
.. "image_button[" .. (start_x + 0.6 * 4)
.. ",9;.8,.8;ui_doubleright_icon.png;forward3;]"
.. "tooltip[forward3;" .. F(S("Forward three pages")) .. "]"
.. "image_button[" .. (start_x + 0.6 * 5)
.. ",9;.8,.8;ui_skip_forward_icon.png;end_list;]"
.. "tooltip[end_list;" .. F(S("Last page")) .. "]"
else
formspec[n] =
"image_button[" .. (8.2 + 0.65 * 0)
.. ",5.8;.8,.8;ui_skip_backward_icon.png;start_list;]"
.. "tooltip[start_list;" .. F(S("First page")) .. "]"
.. "image_button[" .. (8.2 + 0.65 * 1)
.. ",5.8;.8,.8;ui_left_icon.png;rewind1;]"
.. "tooltip[rewind1;" .. F(S("Back one page")) .. "]"
.. "image_button[" .. (8.2 + 0.65 * 2)
.. ",5.8;.8,.8;ui_right_icon.png;forward1;]"
.. "tooltip[forward1;" .. F(S("Forward one page")) .. "]"
.. "image_button[" .. (8.2 + 0.65 * 3)
.. ",5.8;.8,.8;ui_skip_forward_icon.png;end_list;]"
.. "tooltip[end_list;" .. F(S("Last page")) .. "]"
end
n = n+1
-- Search box
formspec[n] = "field_close_on_enter[searchbox;false]"
n = n+1
if not draw_lite_mode then
formspec[n] = "field[9.5,8.325;3,1;searchbox;;"
.. F(unified_inventory.current_searchbox[player_name]) .. "]"
formspec[n+1] = "image_button[12.2,8.1;.8,.8;ui_search_icon.png;searchbutton;]"
.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
formspec[n+2] = "image_button[12.9,8.1;.8,.8;ui_reset_icon.png;searchresetbutton;]"
.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
.. "tooltip[searchresetbutton;" ..F(S("Reset search and display everything")) .. "]"
else
formspec[n] = "field[8.5,5.225;2.2,1;searchbox;;"
.. F(unified_inventory.current_searchbox[player_name]) .. "]"
formspec[n+1] = "image_button[10.3,5;.8,.8;ui_search_icon.png;searchbutton;]"
.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
formspec[n+2] = "image_button[11,5;.8,.8;ui_reset_icon.png;searchresetbutton;]"
.. "tooltip[searchbutton;" ..F(S("Search")) .. "]"
.. "tooltip[searchresetbutton;" ..F(S("Reset search and display everything")) .. "]"
end
n = n+3
local no_matches = S("No matching items")
if draw_lite_mode then
no_matches = S("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 page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1)
local pagemax = math.floor(
(#unified_inventory.filtered_items_list[player_name] - 1)
/ (ui_peruser.items_per_page) + 1)
for y = 0, ui_peruser.pagerows - 1 do
for x = 0, ui_peruser.pagecols - 1 do
local name = unified_inventory.filtered_items_list[player_name][list_index]
local item = minetest.registered_items[name]
if item then
-- Clicked on current item: Flip crafting direction
if name == unified_inventory.current_item[player_name] then
local cdir = unified_inventory.current_craft_direction[player_name]
if cdir == "recipe" then
dir = "usage"
elseif cdir == "usage" then
dir = "recipe"
end
else
-- Default: use active search direction by default
dir = unified_inventory.active_search_direction[player_name]
end
local button_name = "item_button_" .. dir .. "_"
.. unified_inventory.mangle_for_formspec(name)
formspec[n] = ("item_image_button[%f,%f;.81,.81;%s;%s;]"):format(
8.2 + x * 0.7, ui_peruser.formspec_y + ui_peruser.page_y + y * 0.7,
name, button_name
)
formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format(
button_name, minetest.formspec_escape(item.description),
item.mod_origin or "??"
)
n = n + 2
list_index = list_index + 1
end
end
end
formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";"..F(S("Page")) .. ": "
.. S("@1 of @2",page2,pagemax).."]"
end
n= n+1
if unified_inventory.activefilter[player_name] ~= "" then
formspec[n] = "label[8.2,"..(ui_peruser.form_header_y + 0.4)..";" .. F(S("Filter")) .. ":]"
formspec[n+1] = "label[9.1,"..(ui_peruser.form_header_y + 0.4)..";"..F(unified_inventory.activefilter[player_name]).."]"
end
return table.concat(formspec, "")
end end
function ui.set_inventory_formspec(player, page) function unified_inventory.set_inventory_formspec(player, page)
if player then if player then
player:set_inventory_formspec(ui.get_formspec(player, page)) player:set_inventory_formspec(unified_inventory.get_formspec(player, page))
end end
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) --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 if not player then
return false return false
end end
local player_name = player:get_player_name() 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 lfilter = string.lower(filter)
local ffilter local ffilter
if lfilter:sub(1, 6) == "group:" then if lfilter:sub(1, 6) == "group:" then
-- Group filter: all groups of the item must match
local groups = lfilter:sub(7):split(",") local groups = lfilter:sub(7):split(",")
ffilter = function(name) ffilter = function(name, def)
local def = registered_items[name]
if not def then
return false
end
for _, group in ipairs(groups) do for _, group in ipairs(groups) do
if not def.groups[group] if not def.groups[group]
or def.groups[group] <= 0 then or def.groups[group] <= 0 then
@ -381,16 +290,8 @@ function ui.apply_filter(player, filter, search_dir)
return true return true
end end
else else
-- Name filter: fuzzy match item names and descriptions local lang = minetest.get_player_information(player_name).lang_code
local player_info = minetest.get_player_information(player_name) ffilter = function(name, def)
local lang = player_info and player_info.lang_code or ""
ffilter = function(name)
local def = registered_items[name]
if not def then
return false
end
local lname = string.lower(name) local lname = string.lower(name)
local ldesc = string.lower(def.description) local ldesc = string.lower(def.description)
local llocaldesc = minetest.get_translated_string local llocaldesc = minetest.get_translated_string
@ -399,50 +300,78 @@ function ui.apply_filter(player, filter, search_dir)
or llocaldesc and string.find(llocaldesc, lfilter, 1, true) or llocaldesc and string.find(llocaldesc, lfilter, 1, true)
end end
end end
unified_inventory.filtered_items_list[player_name]={}
local filtered_items = {} for name, def in pairs(minetest.registered_items) do
if (not def.groups.not_in_creative_inventory
local category = ui.current_category[player_name] or 'all' or def.groups.not_in_creative_inventory == 0)
if category == 'all' then and def.description
for _, name in ipairs(ui.items_list) do and def.description ~= ""
if fprefilter(name) and ffilter(name) then and ffilter(name, def) then
table.insert(filtered_items, name) table.insert(unified_inventory.filtered_items_list[player_name], name)
end
end
elseif category == 'uncategorized' then
for _, name in ipairs(ui.items_list) do
if not ui.find_category(name)
and fprefilter(name)
and ffilter(name) then
table.insert(filtered_items, name)
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
end end
end end
table.sort(filtered_items) table.sort(unified_inventory.filtered_items_list[player_name])
unified_inventory.filtered_items_list_size[player_name] = #unified_inventory.filtered_items_list[player_name]
ui.filtered_items_list_size[player_name] = #filtered_items unified_inventory.current_index[player_name] = 1
ui.filtered_items_list[player_name] = filtered_items unified_inventory.activefilter[player_name] = filter
ui.current_index[player_name] = 1 unified_inventory.active_search_direction[player_name] = search_dir
ui.activefilter[player_name] = filter unified_inventory.set_inventory_formspec(player,
ui.active_search_direction[player_name] = search_dir unified_inventory.current_page[player_name])
ui.set_inventory_formspec(player, ui.current_page[player_name])
end end
-- Inform players about potential visual issues function unified_inventory.items_in_group(groups)
minetest.register_on_joinplayer(function(player) local items = {}
local player_name = player:get_player_name() for name, item in pairs(minetest.registered_items) do
local info = minetest.get_player_information(player_name) for _, group in pairs(groups:split(',')) do
if info and (info.formspec_version or 0) < 4 then if item.groups[group] then
minetest.chat_send_player(player_name, S("Unified Inventory: Your game version is too old" table.insert(items, name)
.. " and does not support the GUI requirements. You might experience visual issues.")) end
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

View File

@ -3,8 +3,6 @@
local item_names = {} -- [player_name] = { hud, dtime, itemname } local item_names = {} -- [player_name] = { hud, dtime, itemname }
local dlimit = 3 -- HUD element will be hidden after this many seconds local dlimit = 3 -- HUD element will be hidden after this many seconds
local hudbars_mod = minetest.get_modpath("hudbars") 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 function set_hud(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
@ -18,8 +16,7 @@ local function set_hud(player)
item_names[player_name] = { item_names[player_name] = {
hud = player:hud_add({ hud = player:hud_add({
-- TODO: remove compatibility code when 5.8.0 is no longer used hud_elem_type = "text",
[minetest.features.hud_def_type_field and "type" or "hud_elem_type"] = "text",
position = {x=0.5, y=1}, position = {x=0.5, y=1},
offset = off, offset = off,
alignment = {x=0, y=-1}, alignment = {x=0, y=-1},
@ -63,7 +60,6 @@ minetest.register_globalstep(function(dtime)
data.itemname = itemname data.itemname = itemname
data.index = index data.index = index
data.dtime = 0 data.dtime = 0
local lang_code = minetest.get_player_information(player:get_player_name()).lang_code
local desc = stack.get_meta local desc = stack.get_meta
and stack:get_meta():get_string("description") and stack:get_meta():get_string("description")
@ -73,14 +69,6 @@ minetest.register_globalstep(function(dtime)
local def = minetest.registered_items[itemname] local def = minetest.registered_items[itemname]
desc = def and def.description or "" desc = def and def.description or ""
end 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) player:hud_change(data.hud, 'text', desc)
end 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

View File

@ -1,4 +1,5 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Crafting=Fertigung
Mixing=Mischen Mixing=Mischen
Cooking=Kochen Cooking=Kochen
Digging=Graben Digging=Graben
@ -7,32 +8,21 @@ Bag @1=Tasche @1
Small Bag=Kleine Tasche Small Bag=Kleine Tasche
Medium Bag=Mittelgroße Tasche Medium Bag=Mittelgroße Tasche
Large Bag=Groß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 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 First page=Erste Seite
Back three pages=3 Seiten zurückblättern Back three pages=3 Seiten zurückblättern
Back one page=1 Seite zurückblättern Back one page=1 Seite zurückblättern
Forward one page=1 Seite vorblättern Forward one page=1 Seite vorblättern
Forward three pages=3 Seiten vorblättern Forward three pages=3 Seiten vorblättern
Last page=Letzte Seite Last page=Letzte Seite
Search=Suchen
Reset search and display everything=Suche zurücksetzen und alles anzeigen
No matching items=Keine passenden Gegenstände No matching items=Keine passenden Gegenstände
No matches.=Keine Treffer No matches.=Keine Treffer
Page=Seite Page=Seite
@1 of @2=@1 von @2 @1 of @2=@1 von @2
Filter=Filter Filter=Filter
Can use the creative inventory=Kann das Kreativinventar nutzen 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 Grid=Fertigungsraster
Crafting Guide=Fertigungsführer Crafting Guide=Fertigungsführer
Set home position=Heimatposition setzen Set home position=Heimatposition setzen
@ -45,7 +35,6 @@ You don't have the settime privilege!=Du hast das „settime“-Privileg nicht!
Set time to night=Zur Nachtzeit wechseln Set time to night=Zur Nachtzeit wechseln
Time of day set to 9pm=Tageszeit auf 21 Uhr gesetzt Time of day set to 9pm=Tageszeit auf 21 Uhr gesetzt
Clear inventory=Inventar leeren 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! Inventory cleared!=Inventar geleert!
Trash:=Müll: Trash:=Müll:
Refill:=Nachfüllen: Refill:=Nachfüllen:
@ -61,12 +50,9 @@ Show next recipe=Nächstes Rezept zeigen
Show next usage=Nächste Verwendung zeigen Show next usage=Nächste Verwendung zeigen
Show previous recipe=Vorheriges Rezept zeigen Show previous recipe=Vorheriges Rezept zeigen
Show previous usage=Vorherige Verwendung zeigen Show previous usage=Vorherige Verwendung zeigen
@1 (@2)=
Give me:=Gib mir: Give me:=Gib mir:
This recipe is too@@large to be displayed.=
To craft grid:=Ins Fertigungsraster: To craft grid:=Ins Fertigungsraster:
All=Alles All=Alles
Crafting=Fertigung
White=Weiß White=Weiß
Yellow=Gelb Yellow=Gelb
Red=Rot Red=Rot
@ -76,10 +62,12 @@ Waypoints=Wegpunkte
Select Waypoint #@1=Wegpunkt Nr. @1 auswählen Select Waypoint #@1=Wegpunkt Nr. @1 auswählen
Waypoint @1=Wegpunkt Nr. @1 Waypoint @1=Wegpunkt Nr. @1
Set waypoint to current location=Setze Wegpunkt zur derzeitigen Position Set waypoint to current location=Setze Wegpunkt zur derzeitigen Position
Hide waypoint=Wegpunkt verstecken invisible=unsichtbar
Show waypoint=Wegpunkt zeigen visible=sichtbar
Hide coordinates=Koordinaten verstecken Make waypoint @1=Wegpunkt @1 machen
Show coordinates=Koordinaten zeigen Disable=ausschalten
Enable=einschalten
@1 display of waypoint coordinates=Anzeige der Wegpunktkoordinaten @1
Change color of waypoint display=Farbe der Darstellung der Wegpunkte ändern Change color of waypoint display=Farbe der Darstellung der Wegpunkte ändern
Edit waypoint name=Name des Wegpunkts ändern Edit waypoint name=Name des Wegpunkts ändern
Waypoint active=Wegpunkt aktiv Waypoint active=Wegpunkt aktiv
@ -88,13 +76,4 @@ Finish editing=Bearbeitung abschließen
World position=Weltposition World position=Weltposition
Name=Name Name=Name
HUD text color=HUD-Textfarbe HUD text color=HUD-Textfarbe
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Zwingt Unified Inventory, im Vollmodus angezeigt zu werden, wenn der Minimalmodus global eingestellt ist
##### 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,57 +1,54 @@
# textdomain: unified_inventory # textdomain: unified_inventory
# api.lua
Mixing=Mezclar # waypoints.lua
Cooking=Hornear
Digging=Recoger White=Blanco
# bags.lua Yellow=Amarillo
Bags=Bolsos Red=Rojo
Bag @1=Bolso @1 Green=Verde
Small Bag=Bolso Pequeño Blue=Azul
Medium Bag=Bolso Mediano Waypoints=Puntos
Large Bag=Bolso Grande Select Waypoint #@1=Seleccionar Punto #@1
All Items= Waypoint @1=Punto @1
Misc. Items= Set waypoint to current location=Establecer el punto a la ubicación actual
Plant Life= Make waypoint @1=Hacer punto @1
Building Materials= invisible=invisible
Tools= visible=visible
Minerals and Metals= @1 display of waypoint coordinates=Visualizar coordenadas del punto @1
Environment and Worldgen= Disable=Deshabilitado
Lighting= Enable=Habilitado
Change color of waypoint display=Cambiar el color del punto
Edit waypoint name=Editar nombre del punto
Waypoint active=Punto activo
Waypoint inactive=Punto inactivo
Finish editing=Terminar edición
World position=Posición en el mundo
Name=Nombre
HUD text color=Color del texto de la Interfaz
# group.lua # group.lua
and = y 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 # register.lua
Can use the creative inventory=Puede usar el inventario creativo 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 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 Grid=Cuadricula de Elaboración
Crafting Guide=Guía de Elaboración Crafting Guide=Guía de Elaboración
Set home position=Establecer posición de la casa Set home position=Establecer posición de la casa
Home position set to: @1=Posición de la casa cambiada a: @1 Home position set to: @1=Posición de la casa cambiada a: @1
You don't have the "home" privilege!= You don't have the \"home\" privilege!=¡No tienes el privilegio \"home\"!
Go home=Ir a casa Go home=Ir a casa
Set time to day=Cambiar a dia 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 Set time to night=Cambiar a noche
Time of day set to 6am=Hora del día cambiada a 6 AM
Time of day set to 9pm=Hora del día cambiada a 9 PM Time of day set to 9pm=Hora del día cambiada a 9 PM
You don't have the settime privilege!=¡No tienes el privilegio "settime"!
Clear inventory=Limpiar inventario 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! Inventory cleared!=¡Inventario limpio!
This button has been disabled outside=Este botón ha sido deshabilitado
Crafting=Elaboración
Trash:=Basura: Trash:=Basura:
Refill:=Rellenar: Refill:=Rellenar:
Any item belonging to the @1 group=Cualquier elemento que pertenezca al grupo @1 Any item belonging to the @1 group=Cualquier elemento que pertenezca al grupo @1
@ -68,41 +65,36 @@ Show previous recipe=Mostrar la receta anterior
Show previous usage=Mostrar el uso anterior Show previous usage=Mostrar el uso anterior
@1 (@2)=@1 (@2) @1 (@2)=@1 (@2)
Give me:=Dame: Give me:=Dame:
This recipe is too@@large to be displayed.= This recipe is too@nlarge to be displayed.=Esta receta es demasiado@ngrande para ser mostrada.
To craft grid:=Construir: To craft grid:=Construir:
All=Todos 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
# api.lua
##### not used anymore ##### Mixing=Mezclar
Cooking=Hornear
Digging=Recoger
Make waypoint @1=Hacer punto @1 # internal.lua
invisible=invisible
visible=visible First page=Primera página
@1 display of waypoint coordinates=Visualizar coordenadas del punto @1 Back three pages=Volver tres páginas
Disable=Deshabilitado Back one page=Volver una página
Enable=Habilitado Forward one page=Avanzar una página
You don't have the \"home\" privilege!=¡No tienes el privilegio \"home\"! Forward three pages=Avanzar tres páginas
This button has been disabled outside=Este botón ha sido deshabilitado Last page=Ultima Pagina
This recipe is too@nlarge to be displayed.=Esta receta es demasiado@ngrande para ser mostrada. Search=Buscar
Reset search and display everything=Limpiar la busqueda y mostrar todo
No matching items=No se encontraron elementos
No matches.=No hay resultados.
Page=Página
@1 of @2=@1 de @2
Filter=Filtro
# bags.lua
Bags=Bolsos
Bag @1=Bolso @1
Small Bag=Bolso Pequeño
Medium Bag=Bolso Mediano
Large Bag=Bolso Grande

View File

@ -1,5 +1,5 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Mixing= Crafting=Création
Cooking=Cuisson Cooking=Cuisson
Digging=Creuser Digging=Creuser
Bags=Sacs Bags=Sacs
@ -7,66 +7,35 @@ Bag @1=Sac @1
Small Bag=Petit sac Small Bag=Petit sac
Medium Bag=Sac moyen Medium Bag=Sac moyen
Large Bag=Grand sac Large Bag=Grand sac
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = et and = et
Scroll categories left=
Scroll categories right=
Search=Rechercher
Reset search and display everything=
First page=1ère page First page=1ère page
Back three pages=3 pages en arrière Back three pages=3 pages en arrière
Back one page=Page précédente Back one page=Page précédente
Forward one page=Page suivante Forward one page=Page suivante
Forward three pages=3 pages en avant Forward three pages=3 pages en avant
Last page=Dernière page Last page=Dernière page
Search=Rechercher
No matching items=Aucun élément correspondant No matching items=Aucun élément correspondant
No matches.=Aucun match No matches.=Aucun match
Page=Page Page=Page
@1 of @2=@1 de @2 @1 of @2=@1 de @2
Filter=Filtre Filter=Filtre
Can use the creative inventory=Vous pouvez utiliser l'inventaire créatif 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 Grid=Grille de création
Crafting Guide=Guide de création Crafting Guide=Guide de création
Set home position=Position dans le monde Set home position=Position dans le monde
Home position set to: @1=Position de votre base fixée à: @1 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"! 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 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"! 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 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é ! Inventory cleared!=Inventaire vidé !
Trash:=Poubelle : Trash:=Poubelle :
Refill:=Remplir : Refill:=Remplir :
Any item belonging to the @1 group=
Any item belonging to the groups @1=
Recipe @1 of @2=Recette @1 de @2 Recipe @1 of @2=Recette @1 de @2
Usage @1 of @2=
No recipes=
No usages=
Result=Résultat 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: To craft grid:=Sur de création:
All=Tout All=Tout
Crafting=Création
White=Blanc White=Blanc
Yellow=Jaune Yellow=Jaune
Red=Rouge Red=Rouge
@ -76,10 +45,8 @@ Waypoints=Point de passage
Select Waypoint #@1=Choisir un point de passage #@1 Select Waypoint #@1=Choisir un point de passage #@1
Waypoint @1=Point de passage @1 Waypoint @1=Point de passage @1
Set waypoint to current location=Marquer un point de passage à la position actuelle Set waypoint to current location=Marquer un point de passage à la position actuelle
Hide waypoint= Make waypoint @1=Rendre @1 le point de passage
Show waypoint= @1 display of waypoint coordinates=@1 montrer les coordonnées des points de passages
Hide coordinates=
Show coordinates=
Change color of waypoint display=Changer la couleur du point de passage Change color of waypoint display=Changer la couleur du point de passage
Edit waypoint name=Editer le nom du point de passage Edit waypoint name=Editer le nom du point de passage
Waypoint active=Point de passage actif Waypoint active=Point de passage actif
@ -88,9 +55,3 @@ Finish editing=Terminer l'édition
World position=Position dans le monde World position=Position dans le monde
Name=Nom Name=Nom
HUD text color=Couleur de texte du HUD 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,4 +1,5 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Crafting=Assemblaggio
Mixing=Unione Mixing=Unione
Cooking=Cottura Cooking=Cottura
Digging=Scavo Digging=Scavo
@ -7,32 +8,21 @@ Bag @1=Borsa @1
Small Bag=Borsa piccola Small Bag=Borsa piccola
Medium Bag=Borsa media Medium Bag=Borsa media
Large Bag=Borsa grande Large Bag=Borsa grande
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = e 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 First page=Prima pagina
Back three pages=Indietro di tre pagine Back three pages=Indietro di tre pagine
Back one page=Indietro di una pagina Back one page=Indietro di una pagina
Forward one page=Avanti di una pagina Forward one page=Avanti di una pagina
Forward three pages=Avanti di tre pagine Forward three pages=Avanti di tre pagine
Last page=Ultima pagina Last page=Ultima pagina
Search=Cerca
Reset search and display everything=Azzera la ricerca e mostra tutto
No matching items=Nessun oggetto corrispondente No matching items=Nessun oggetto corrispondente
No matches.=Nessuna corrispondenza. No matches.=Nessuna corrispondenza.
Page=Pagina Page=Pagina
@1 of @2=@1 di @2 @1 of @2=@1 di @2
Filter=Filtro Filter=Filtro
Can use the creative inventory=Può usare l'inventario creativo 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 Grid=Griglia di assemblaggio
Crafting Guide=Guida di assemblaggio Crafting Guide=Guida di assemblaggio
Set home position=Imposta la residenza Set home position=Imposta la residenza
@ -45,7 +35,6 @@ You don't have the settime privilege!=Non hai il privilegio "time"!
Set time to night=Imposta l'orario sulla notte Set time to night=Imposta l'orario sulla notte
Time of day set to 9pm=Orario impostato sulle 9am Time of day set to 9pm=Orario impostato sulle 9am
Clear inventory=Ripulisci l'inventario 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! Inventory cleared!=Inventario ripulito!
Trash:=Butta: Trash:=Butta:
Refill:=Riempi: Refill:=Riempi:
@ -61,12 +50,9 @@ Show next recipe=Mostra la prossima ricetta
Show next usage=Mostra il prossimo utilizzo Show next usage=Mostra il prossimo utilizzo
Show previous recipe=Mostra la ricetta precedente Show previous recipe=Mostra la ricetta precedente
Show previous usage=Mostra l'utilizzo precedente Show previous usage=Mostra l'utilizzo precedente
@1 (@2)=
Give me:=Dammi: Give me:=Dammi:
This recipe is too@@large to be displayed.=
To craft grid:=Alla griglia di assemblaggio: To craft grid:=Alla griglia di assemblaggio:
All=Tutto All=Tutto
Crafting=Assemblaggio
White=Bianco White=Bianco
Yellow=Giallo Yellow=Giallo
Red=Rosso Red=Rosso
@ -76,10 +62,12 @@ Waypoints=Tappe
Select Waypoint #@1=Seleziona tappa n°@1 Select Waypoint #@1=Seleziona tappa n°@1
Waypoint @1=Tappa @1 Waypoint @1=Tappa @1
Set waypoint to current location=Imposta tappa alla posizione attuale Set waypoint to current location=Imposta tappa alla posizione attuale
Hide waypoint= invisible=invisibile
Show waypoint= visible=visibile
Hide coordinates= Make waypoint @1=Crea tappa @1
Show coordinates= Disable=Disabilita
Enable=Abilita
@1 display of waypoint coordinates=@1 la visualizzazione delle coordinate della tappa
Change color of waypoint display=Modifica il colore della visualizzazione della tappa Change color of waypoint display=Modifica il colore della visualizzazione della tappa
Edit waypoint name=Modifica il nome della tappa Edit waypoint name=Modifica il nome della tappa
Waypoint active=Tappa attiva Waypoint active=Tappa attiva
@ -88,13 +76,4 @@ Finish editing=Termina la modifica
World position=Posizione del mondo World position=Posizione del mondo
Name=Nome Name=Nome
HUD text color=Colore del testo del visore HUD text color=Colore del testo del visore
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Forza la visualizzazione di Unified Inventory in modalità completa se è configurata globalmente la visualizzazione semplice
##### 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,4 +1,5 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Crafting=Pertukangan
Mixing=Pencampuran Mixing=Pencampuran
Cooking=Pemasakan Cooking=Pemasakan
Digging=Penggalian Digging=Penggalian
@ -7,32 +8,21 @@ Bag @1=Beg @1
Small Bag=Beg Kecil Small Bag=Beg Kecil
Medium Bag=Beg Sederhana Medium Bag=Beg Sederhana
Large Bag=Beg Besar Large Bag=Beg Besar
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = dan 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 First page=Halaman pertama
Back three pages=Tiga halaman sebelumnya Back three pages=Tiga halaman sebelumnya
Back one page=Halaman sebelumnya Back one page=Halaman sebelumnya
Forward one page=Halaman seterusnya Forward one page=Halaman seterusnya
Forward three pages=Tiga halaman seterusnya Forward three pages=Tiga halaman seterusnya
Last page=Halaman terakhir Last page=Halaman terakhir
Search=Cari
Reset search and display everything=Set semula carian dan tunjukkan semua benda
No matching items=Tiada item sepadan No matching items=Tiada item sepadan
No matches.=Tiada padanan. No matches.=Tiada padanan.
Page=Halaman Page=Halaman
@1 of @2=@1 drpd @2 @1 of @2=@1 drpd @2
Filter=Tapis Filter=Tapis
Can use the creative inventory=Boleh guna inventori kreatif 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 Grid=Grid Pertukangan
Crafting Guide=Panduan Pertukangan Crafting Guide=Panduan Pertukangan
Set home position=Tetapkan kedudukan rumah Set home position=Tetapkan kedudukan rumah
@ -45,7 +35,6 @@ You don't have the settime privilege!=Anda tidak ada keistimewaan settime!
Set time to night=Tetapkan masa jadi malam Set time to night=Tetapkan masa jadi malam
Time of day set to 9pm=Masa ditetapkan ke 9 malam Time of day set to 9pm=Masa ditetapkan ke 9 malam
Clear inventory=Kosongkan inventori 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! Inventory cleared!=Inventori dikosongkan!
Trash:=Buang: Trash:=Buang:
Refill:=Isi balik: Refill:=Isi balik:
@ -63,10 +52,7 @@ Show previous recipe=Tunjuk resipi sebelumnya
Show previous usage=Tunjuk kegunaan sebelumnya Show previous usage=Tunjuk kegunaan sebelumnya
@1 (@2)=@1 (@2) @1 (@2)=@1 (@2)
Give me:=Beri saya: Give me:=Beri saya:
This recipe is too@@large to be displayed.=
To craft grid:=Ke grid pertukangan: To craft grid:=Ke grid pertukangan:
All=
Crafting=Pertukangan
White=Putih White=Putih
Yellow=Kuning Yellow=Kuning
Red=Merah Red=Merah
@ -76,10 +62,12 @@ Waypoints=Titik Arah
Select Waypoint #@1=Pilih Titik Arah #@1 Select Waypoint #@1=Pilih Titik Arah #@1
Waypoint @1=Titik Arah @1 Waypoint @1=Titik Arah @1
Set waypoint to current location=Tetapkan titik arah ke lokasi semasa Set waypoint to current location=Tetapkan titik arah ke lokasi semasa
Hide waypoint= invisible=Sembunyikan
Show waypoint= visible=Paparkan
Hide coordinates= Make waypoint @1=@1 titik arah
Show coordinates= Disable=Sembunyikan
Enable=Paparkan
@1 display of waypoint coordinates=@1 koordinat untuk titik arah
Change color of waypoint display=Tukar warna paparan titik arah Change color of waypoint display=Tukar warna paparan titik arah
Edit waypoint name=Edit nama titik arah Edit waypoint name=Edit nama titik arah
Waypoint active=Titik arah aktif Waypoint active=Titik arah aktif
@ -88,13 +76,3 @@ Finish editing=Selesai edit
World position=Kedudukan dunia World position=Kedudukan dunia
Name=Nama Name=Nama
HUD text color=Warna tulisan HUD 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 +1,61 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Category:=Kategorie:
Mixing=Miksowanie
Cooking=Gotowanie
Digging=Kopanie
Bags=Plecaki Bags=Plecaki
Bag @1=Plecak @1 Bag @1=Plecak @1
Small Bag=Mały plecak Small Bag=Maly plecak
Medium Bag=Średni plecak Medium Bag=Sredni plecak
Large Bag=Duży plecak Large Bag=Duzy 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 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 First page=Pierwsza strona
Back three pages=Trzy strony do tyłu Back three pages=3 strony w tyl
Back one page=Stronę do tyłu Back one page=1 strona w tyl
Forward one page=Stronę do przodu Forward one page=1 strona do przodu
Forward three pages=Trzy strony do przodu Forward three pages=3 strony do przodu
Last page=Ostatnia strona Last page=Ostatnia strona
No matching items=Brak pasujących przedmiotów Search=Szukaj
No matching items=Brak pasujacych przedmiotow
No matches.=Brak wyników No matches.=Brak wyników
Page=Strona Page=Strona
@1 of @2=@1 z @2 @1 of @2=@1 z @2
Filter=Filtr Filter=Filtr
Can use the creative inventory=Może używać kreatywnego ekwipunku Set home position=Ustaw pozycję wyjściową
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 Home position set to: @1=Pozycja domowa ustawiona na: @1
Crafting Grid=Siatka craftingu You don't have the "home" privilege!=Nie masz uprawnien do zmiany czasu "home"!
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 Go home=Idź do domu
Set time to day=Ustaw czas na dzień Set time to day=Ustaw czas na dzień
Time of day set to 6am=Czas ustawiony na 6:00 Time of day set to 6am=Czas ustawiony na 6:00
You don't have the settime privilege!=Brak uprawnień "settime"! You don't have the settime privilege!=Nie masz uprawnien do zmiany czasu "settime"!
Set time to night=Ustaw czas na noc Set time to night=Ustaw czas na noc
Time of day set to 9pm=Czas ustawiony na 21:00 Time of day set to 9pm=Czas ustawiony na 21:00
Clear inventory=Wyczyść ekwipunek Clear inventory=Wyczyść zapasy
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!=Zapasy zostały wyczyszczone!
Inventory cleared!=Ekwipunek został wyczyszczony! Trash:=Smietnik:
Trash:=Śmietnik: Refill:=Uzupelnianie:
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 Recipe @1 of @2=Recepta @1 z @2
Usage @1 of @2=Użycie @1 z @2 Usage @1 of @2=Użycie @1 z @2
No recipes=Brak recepty No recipes=Brak recepty
No usages=Bez użycia No usages=Bez użycia
Result=Wynik Result=Wynik
Ingredient=Składnik 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: 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 All=Wszystko
Crafting=Crafting White=Bialy
White=Biały Yellow=Zolty
Yellow=Zółty
Red=Czerwony Red=Czerwony
Green=Zielony Green=Zielony
Blue=Niebieski Blue=Niebieski
Waypoints=Punkty orientacyjne Waypoints=Punkty orientacyjne
Select Waypoint #@1=Wybierz punkt #@1 Select Waypoint #@1=Wybierz punkt #@1
Waypoint @1=Punkty orientacyjne @1 Waypoint @1=Punkty orientacyjne @1
Set waypoint to current location=Ustaw punkt orientacyjny na bieżacej pozycji Set waypoint to current location=Ustaw punkt orientacyjny na biezacej pozycji
Hide waypoint=Ukryj punkt orientacyjny invisible=niewidzialny
Show waypoint=Pokaż punkt orientacyjny visible=widomy
Hide coordinates=Ukryj koordynaty Make waypoint @1=Robić punkt @1
Show coordinates=Pokaż koordynaty @1 display of waypoint coordinates=@1 koordynatow punktu
Change color of waypoint display=Zmień kolor punktu Change color of waypoint display=Zmien kolor punktu
Edit waypoint name=Edytuj nazwę punktu Edit waypoint name=Edytuj nazwe punktu
Waypoint active=Punkt włączony Waypoint active=Punkt wlaczony
Waypoint inactive=Punkt wyłączony Waypoint inactive=Punkt wylaczony
Finish editing=Zakończ edycję Finish editing=Zakoncz edycje
World position=Pozycja World position=Pozycja
Name=Nazwa Name=Nazwa
HUD text color=Kolor tekstu HUD HUD text color=Kolor tekstu HUD

View File

@ -1,4 +1,5 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Crafting=Artesanato
Mixing=Muistura Mixing=Muistura
Cooking=Cozimento Cooking=Cozimento
Digging=Escavação Digging=Escavação
@ -7,32 +8,21 @@ Bag @1=Bolsa @1
Small Bag=Bolsa Pequena Small Bag=Bolsa Pequena
Medium Bag=Bolsa Média Medium Bag=Bolsa Média
Large Bag=Bolsa Grande Large Bag=Bolsa Grande
All Items=
Misc. Items=
Plant Life=
Building Materials=
Tools=
Minerals and Metals=
Environment and Worldgen=
Lighting=
and = e 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 First page=Primeira Página
Back three pages=Voltar 3 Páginas Back three pages=Voltar 3 Páginas
Back one page=Voltar 1 Página Back one page=Voltar 1 Página
Forward one page=Avançar 1 Página Forward one page=Avançar 1 Página
Forward three pages=Avançar 3 Páginas Forward three pages=Avançar 3 Páginas
Last page=Ultima Página Last page=Ultima Página
Search=Pesquisar
Reset search and display everything=Redefinir pesquisa e exibir tudo
No matching items=Nenhum item correspondente No matching items=Nenhum item correspondente
No matches.=Sem correspondências No matches.=Sem correspondências
Page=Página Page=Página
@1 of @2=@1 de @2 @1 of @2=@1 de @2
Filter=Filtro Filter=Filtro
Can use the creative inventory=Pode usar o inventário do criativo 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 Grid=Grade de Artesanato
Crafting Guide=Guia de Artesanato Crafting Guide=Guia de Artesanato
Set home position=Definir posição de casa Set home position=Definir posição de casa
@ -45,7 +35,6 @@ You don't have the settime privilege!=Você não tem o privilégio de "settime"!
Set time to night=Definir turno para noite Set time to night=Definir turno para noite
Time of day set to 9pm=Hora do dia ajustada para 21h Time of day set to 9pm=Hora do dia ajustada para 21h
Clear inventory=Limpar Inventário 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! Inventory cleared!=Inventário Apagado!
Trash:=Lixo: Trash:=Lixo:
Refill:=Recarga: Refill:=Recarga:
@ -61,12 +50,9 @@ Show next recipe=Exibir Próxima Receita
Show next usage=Mostrar Próxima Utilização Show next usage=Mostrar Próxima Utilização
Show previous recipe=Exibir Receita Anterior Show previous recipe=Exibir Receita Anterior
Show previous usage=Exibir Utilização Anterior Show previous usage=Exibir Utilização Anterior
@1 (@2)=
Give me:=Gerado: Give me:=Gerado:
This recipe is too@@large to be displayed.=
To craft grid:=Para Grade de Artesanato To craft grid:=Para Grade de Artesanato
All=MAX All=MAX
Crafting=Artesanato
White=Branco White=Branco
Yellow=Amarelo Yellow=Amarelo
Red=Vermelho Red=Vermelho
@ -76,10 +62,10 @@ Waypoints=Apontador de Direção
Select Waypoint #@1=Seleção de Apontador de Direção #@1 Select Waypoint #@1=Seleção de Apontador de Direção #@1
Waypoint @1=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 Set waypoint to current location=Configurar localização atual do Apontador de Direção
Hide waypoint= invisible=invisível
Show waypoint= visible=visível
Hide coordinates= Make waypoint @1=Fazer Apontador de Direção @1
Show coordinates= @1 display of waypoint coordinates=@1 exibição de coordenadas de Fazer Apontador de Direção
Change color of waypoint display=Mudar cor exibida do Apontador de Direção Change color of waypoint display=Mudar cor exibida do Apontador de Direção
Edit waypoint name=Editar Nome de Apontador de Direção Edit waypoint name=Editar Nome de Apontador de Direção
Waypoint active=Apontador de Direção Ativo Waypoint active=Apontador de Direção Ativo
@ -88,11 +74,3 @@ Finish editing=Edição Finalizada
World position=Posição Mundial World position=Posição Mundial
Name=Nome Name=Nome
HUD text color=Cor de HUD 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,38 +1,28 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Crafting=Крафт
Mixing=Мешать Mixing=Мешать
Cooking=Готовить Cooking=Варить
Digging=Копать Digging=Копать
Bags=Сумки Bags=Сумки
Bag @1=Сумка @1 Bag @1=Сумка @1
Small Bag=Малая сумка Small Bag=Малая сумка
Medium Bag=Средняя сумка Medium Bag=Средняя сумка
Large Bag=Большая сумка Large Bag=Большая сумка
All Items=Все предметы
Misc. Items=Разн. предметы
Plant Life=Растения
Building Materials=Стройматериалы
Tools=Инструменты
Minerals and Metals=Металлы и минералы
Environment and Worldgen=Окружение и генер.мира
Lighting=Освещение
and = и and = и
Scroll categories left=Листать влево
Scroll categories right=Листать вправо
Search=Поиск
Reset search and display everything=Сброс поиска, показать всё
First page=Первая страница First page=Первая страница
Back three pages=3 страницы назад Back three pages=3 страницы назад
Back one page=1 страницу назад Back one page=1 страницу назад
Forward one page=1 страницу вперёд Forward one page=1 страницу вперёд
Forward three pages=3 страницы вперёд Forward three pages=3 страницы вперёд
Last page=Последняя страница Last page=Последняя страница
Search=Поиск
Reset search and display everything=Сброс поиска, показать всё
No matching items=Нет подходящих элементов No matching items=Нет подходящих элементов
No matches.=Ничего не найдено No matches.=Ничего не найдено
Page=Страница Page=Страница
@1 of @2=@1 из @2 @1 of @2=@1 из @2
Filter=Фильтр Filter=Фильтр
Can use the creative inventory=Можно использовать инвентарь творческого режима Can use the creative inventory=Можно использовать инвентарь творческого режима
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Отображает инвентарь в полном режиме, если простой режим установлен глобально
Crafting Grid=Решетка крафта Crafting Grid=Решетка крафта
Crafting Guide=Книга рецептов Crafting Guide=Книга рецептов
Set home position=Установить позицию дома Set home position=Установить позицию дома
@ -45,7 +35,6 @@ You don't have the settime privilege!=Вам не разрешено устан
Set time to night=Ночь Set time to night=Ночь
Time of day set to 9pm=Установлено время 9 вечера Time of day set to 9pm=Установлено время 9 вечера
Clear inventory=Очистить инвентарь Clear inventory=Очистить инвентарь
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
Inventory cleared!=Инвентарь очищен! Inventory cleared!=Инвентарь очищен!
Trash:=Мусор: Trash:=Мусор:
Refill:=Наполнить: Refill:=Наполнить:
@ -59,14 +48,11 @@ Result=Результат
Ingredient=Состав Ingredient=Состав
Show next recipe=Следующий рецепт Show next recipe=Следующий рецепт
Show next usage=Следующее использование Show next usage=Следующее использование
Show previous recipe=Предыдущий рецепт Show previous recipe=Прошлый рецепт
Show previous usage=Предыдущая страница Show previous usage=Прошлая страница
@1 (@2)=
Give me:=Дай мне: Give me:=Дай мне:
This recipe is too@@large to be displayed.=Этот рецепт слишком большой
To craft grid:=На решeтку крафта: To craft grid:=На решeтку крафта:
All=Все All=Все
Crafting=Крафт
White=Белый White=Белый
Yellow=Желтый Yellow=Желтый
Red=Красный Red=Красный
@ -76,10 +62,12 @@ Waypoints=Путевые точки
Select Waypoint #@1=Выбрать путевую точку №@1 Select Waypoint #@1=Выбрать путевую точку №@1
Waypoint @1=Путевая точка @1 Waypoint @1=Путевая точка @1
Set waypoint to current location=Установить путевую точку по текущей позиции Set waypoint to current location=Установить путевую точку по текущей позиции
Hide waypoint=Скрыть точку invisible=невидимой
Show waypoint=Показать точку visible=видимой
Hide coordinates=Скрыть координаты Make waypoint @1=Сделать путевую точку @1
Show coordinates=Показать координаты Disable=Выключить
Enable=Включить
@1 display of waypoint coordinates=@1 показ координат путевых точек
Change color of waypoint display=Поменять цвет путевой точки Change color of waypoint display=Поменять цвет путевой точки
Edit waypoint name=Переименовать путевую точку Edit waypoint name=Переименовать путевую точку
Waypoint active=Путевая точка включена Waypoint active=Путевая точка включена
@ -88,4 +76,3 @@ Finish editing=Закончить редакцию
World position=Позиция мира World position=Позиция мира
Name=Имя Name=Имя
HUD text color=Цвет текста HUDа HUD text color=Цвет текста HUDа
Category:=Категории:

View File

@ -1,52 +1,54 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Mixing=
Cooking= # waypoints.lua
Digging=
Bags= White=
Bag @1= Yellow=
Small Bag= Red=
Medium Bag= Green=
Large Bag= Blue=
All Items= Waypoints=
Misc. Items= Select Waypoint #@1=
Plant Life= Waypoint @1=
Building Materials= Set waypoint to current location=
Tools= Make waypoint @1=
Minerals and Metals= invisible=
Environment and Worldgen= visible=
Lighting= @1 display of waypoint coordinates=
Disable=
Enable=
Change color of waypoint display=
Edit waypoint name=
Waypoint active=
Waypoint inactive=
Finish editing=
World position=
Name=
HUD text color=
# group.lua
and = and =
Scroll categories left=
Scroll categories right= # register.lua
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= Can use the creative inventory=
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=
Crafting Grid= Crafting Grid=
Crafting Guide= Crafting Guide=
Set home position= Set home position=
Home position set to: @1= Home position set to: @1=
You don't have the "home" privilege!= You don't have the \"home\" privilege!=
Go home= Go home=
Set time to day= Set time to day=
Time of day set to 6am=
You don't have the settime privilege!=
Set time to night= Set time to night=
Time of day set to 6am=
Time of day set to 9pm= Time of day set to 9pm=
You don't have the settime privilege!=
Clear inventory= Clear inventory=
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
Inventory cleared!= Inventory cleared!=
This button has been disabled outside=
Crafting=
Trash:= Trash:=
Refill:= Refill:=
Any item belonging to the @1 group= Any item belonging to the @1 group=
@ -63,28 +65,36 @@ Show previous recipe=
Show previous usage= Show previous usage=
@1 (@2)= @1 (@2)=
Give me:= Give me:=
This recipe is too@@large to be displayed.= This recipe is too@nlarge to be displayed.=
To craft grid:= To craft grid:=
All= All=
Crafting=
White= # api.lua
Yellow=
Red= Mixing=
Green= Cooking=
Blue= Digging=
Waypoints=
Select Waypoint #@1= # internal.lua
Waypoint @1=
Set waypoint to current location= First page=
Hide waypoint= Back three pages=
Show waypoint= Back one page=
Hide coordinates= Forward one page=
Show coordinates= Forward three pages=
Change color of waypoint display= Last page=
Edit waypoint name= Search=
Waypoint active= Reset search and display everything=
Waypoint inactive= No matching items=
Finish editing= No matches.=
World position= Page=
Name= @1 of @2=
HUD text color= Filter=
# bags.lua
Bags=
Bag @1=
Small Bag=
Medium Bag=
Large Bag=

View File

@ -1,4 +1,5 @@
# textdomain: unified_inventory # textdomain: unified_inventory
Crafting=Üretim
Mixing=Karıştırma Mixing=Karıştırma
Cooking=Pişirme Cooking=Pişirme
Digging=Kazma Digging=Kazma
@ -7,32 +8,20 @@ Bag @1=@1. Çanta
Small Bag=Küçük Çanta Small Bag=Küçük Çanta
Medium Bag=Çanta Medium Bag=Çanta
Large Bag=Büyük Ç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 and = ve
Scroll categories left=
Scroll categories right=
Search=Ara
Reset search and display everything=
First page=İlk Sayfa First page=İlk Sayfa
Back three pages=3 Sayfa Gerile Back three pages=3 Sayfa Gerile
Back one page=Geri Back one page=Geri
Forward one page=İleri Forward one page=İleri
Forward three pages=3 Sayfa İlerile Forward three pages=3 Sayfa İlerile
Last page=Son Sayfa Last page=Son Sayfa
Search=Ara
No matching items=Eşleşme yok No matching items=Eşleşme yok
No matches.=Eşleşme yok No matches.=Eşleşme yok
Page=Sayfa Page=Sayfa
@1 of @2=@1 dan @2 @1 of @2=@1 dan @2
Filter=Süzgeç Filter=Süzgeç
Can use the creative inventory=Yaratıcı envanteri kullanabilir 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 Grid=Üretim tablosu
Crafting Guide=Kılavuz Crafting Guide=Kılavuz
Set home position=Set ev pozisyon Set home position=Set ev pozisyon
@ -44,29 +33,19 @@ Time of day set to 6am=Saat 06:00 olarak ayarlandı
You don't have the settime privilege!="settime" yetkiniz yok! You don't have the settime privilege!="settime" yetkiniz yok!
Set time to night=Geceye zaman ayarla Set time to night=Geceye zaman ayarla
Time of day set to 9pm=Saat 19:00 olarak ayarlandı Time of day set to 9pm=Saat 19:00 olarak ayarlandı
Clear inventory= msgid ""=Yaratıcı modu dışında iken bu tuş kullanılamaz.
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=
Inventory cleared!=Envanter temizlendi! Inventory cleared!=Envanter temizlendi!
Trash:=Çöp Trash:=Çöp
Refill:=Doldur Refill:=Doldur
Any item belonging to the @1 group=
Any item belonging to the groups @1=
Recipe @1 of @2=@1 dan @2 tarifi Recipe @1 of @2=@1 dan @2 tarifi
Usage @1 of @2=Kullanım @1/@2 Usage @1 of @2=Kullanım @1/@2
No recipes=Tarifi yok No recipes=Tarifi yok
No usages=Kullanım yok No usages=Kullanım yok
Result=Çıktı Result=Çıktı
Ingredient=Bileşen Ingredient=Bileşen
Show next recipe=
Show next usage=
Show previous recipe=
Show previous usage=
@1 (@2)=
Give me:=Ver bana: Give me:=Ver bana:
This recipe is too@@large to be displayed.=
To craft grid:=Üretim tablosuna kopyala To craft grid:=Üretim tablosuna kopyala
All=Tümü All=Tümü
Crafting=Üretim
White=Beyaz White=Beyaz
Yellow=Sarı Yellow=Sarı
Red=Kırmızı Red=Kırmızı
@ -76,10 +55,10 @@ Waypoints=Konum Noktaları
Select Waypoint #@1=#@1 konum noktası seç Select Waypoint #@1=#@1 konum noktası seç
Waypoint @1=@1 Konum Noktaları Waypoint @1=@1 Konum Noktaları
Set waypoint to current location=Bulunduğun noktayı işaretle Set waypoint to current location=Bulunduğun noktayı işaretle
Hide waypoint= invisible=görünmez
Show waypoint= visible=görünür
Hide coordinates= Make waypoint @1=Yol noktası @1
Show coordinates= @1 display of waypoint coordinates=Yol noktası koordinatlarının görüntülenmesini @1
Change color of waypoint display=Konum Gösterge Rengi Change color of waypoint display=Konum Gösterge Rengi
Edit waypoint name=Konum Noktasını Düzenle Edit waypoint name=Konum Noktasını Düzenle
Waypoint active=Konum Etkin Waypoint active=Konum Etkin
@ -88,12 +67,3 @@ Finish editing=Düzenleme bitti
World position=Dünya konumu World position=Dünya konumu
Name=İsim Name=İsim
HUD text color=Metin rengi 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,92 +0,0 @@
# textdomain: unified_inventory
Replaces the default inventory and adds a number of features, such as a crafting guide=Замінює стандартний інвентар та додає ряд особливостей, таких як книга рецептів
Mixing=Перемішати
Cooking=Виплавити
Digging=Викопати
Bags=Сумки
Bag @1=Сумка @1
Small Bag=Мала сумка
Medium Bag=Середня сумка
Large Bag=Велика сумка
All Items=Все
Misc. Items=Різне
Plant Life=Рослини
Building Materials=Будматеріали
Tools=Інструменти
Minerals and Metals=Руди й метали
Environment and Worldgen=Оточення та генерація світу
Lighting=Освітлення
and = та
Scroll categories left=Ліворуч
Scroll categories right=Праворуч
Search=Пошук
Reset search and display everything=Скинути пошук та відобразити усе
First page=Перша сторінка
Back three pages=3 сторінки назад
Back one page=Попередня сторінка
Forward one page=Наступна сторінка
Forward three pages=3 сторінки вперед
Last page=Остання сторінка
No matching items=Не знайдено предметів
No matches.=Немає результатів.
Page=Сторінка
@1 of @2=@1 з @2
Filter=Фільтр
Can use the creative inventory=Можна використовувати творчий інвентар
Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Відображає повний режим, якщо простий режим сконфігуровано глобально
Crafting Grid=Сітка майстрування
Crafting Guide=Книга рецептів
Set home position=Встановити позицію дому
Home position set to: @1=Тепер дім розташований по координатам: @1
You don't have the "home" privilege!=У вас немає привілею "home"!
Go home=Додому
Set time to day=День
Time of day set to 6am=Час встановлено на 6:00
You don't have the settime privilege!=Ви не можете встановлювати час (нема привілею "settime")
Set time to night=Ніч
Time of day set to 9pm=Час встановлено на 21:00
Clear inventory=Очистити інвентар
This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.=Цю кнопку було вимкнено в творчому режимі, щоб запобігти випадковому очищенню інвентаря.@nВикористовуйте слот смітника натомість.
Inventory cleared!=Інвентар очищено!
Trash:=Смітник:
Refill:=Заповнити:
Any item belonging to the @1 group=Будь-який елемент із групи @1
Any item belonging to the groups @1=Будь-який елемент із груп @1
Recipe @1 of @2=Рецепт @1 із @2
Usage @1 of @2=Використання @1 із @2
No recipes=Немає рецептів
No usages=Ніде не використовується
Result=Результат
Ingredient=Інгредієнт
Show next recipe=Наступний рецепт
Show next usage=Наступне використання
Show previous recipe=Попередній рецепт
Show previous usage=Попереднє використання
@1 (@2)=@1 (@2)
Give me:=Дай мені:
This recipe is too@@large to be displayed.=Цей рецепт надто великий, щоб його відобразити
To craft grid:=На сітку крафту:
All=Все
Crafting=Крафт
White=Білий
Yellow=Жовтий
Red=Червоний
Green=Зелений
Blue=Синій
Waypoints=Геомітки
Select Waypoint #@1=Вибрати геомітку №@1
Waypoint @1=Геомітка @1
Set waypoint to current location=Встановити тут
Hide waypoint=Сховати геомітку
Show waypoint=Показати геомітку
Hide coordinates=Сховати координати
Show coordinates=Показати координати
Change color of waypoint display=Змінити колір геомітки
Edit waypoint name=Перейменувати геомітку
Waypoint active=Геомітку показано
Waypoint inactive=Геомітку приховано
Finish editing=Закінчити редагування
World position=Світова позиція
Name=Назва
HUD text color=Колір тексту
Category:=Категорії:

View File

@ -1,4 +1,8 @@
# textdomain: unified_inventory # textdomain: unified_inventory
# traslation by: IFRFSX(BingFengFSX)
#Email: IFRFSX@Protonmail.com
Crafting=合成
Mixing=混合 Mixing=混合
Cooking=烹饪 Cooking=烹饪
Digging=挖出 Digging=挖出
@ -7,32 +11,20 @@ Bag @1=背包@1
Small Bag=小背包 Small Bag=小背包
Medium Bag=中背包 Medium Bag=中背包
Large Bag=大背包 Large Bag=大背包
All Items=所有物品
Misc. Items=杂项
Plant Life=植物
Building Materials=建材
Tools=工具
Minerals and Metals=矿物与金属
Environment and Worldgen=自然环境
Lighting=光源
and = 和 and = 和
Scroll categories left=向左滚动分类栏
Scroll categories right=向右滚动分类栏
Search=搜索
Reset search and display everything=重置搜索并显示所有物品
First page=第一页 First page=第一页
Back three pages=后退三页 Back three pages=后退三页
Back one page=后退一页 Back one page=后退一页
Forward one page=前进一页 Forward one page=前进一页
Forward three pages=前进三页 Forward three pages=前进三页
Last page=最后一页 Last page=最后一页
Search=搜索
No matching items=没有匹配物品 No matching items=没有匹配物品
No matches.=没有匹配 No matches.=没有匹配
Page=页面 Page=页面
@1 of @2=第@1页共@2页 @1 of @2=第@1页共@2页
Filter=过滤器 Filter=过滤器
Can use the creative inventory=可以使用创造背包 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 Grid=合成表
Crafting Guide=合成指南 Crafting Guide=合成指南
Set home position=设置家的位置 Set home position=设置家的位置
@ -44,29 +36,21 @@ Time of day set to 6am=时间设置到早晨6点
You don't have the settime privilege!=你没有“settime”权限 You don't have the settime privilege!=你没有“settime”权限
Set time to night=设置时间到晚上 Set time to night=设置时间到晚上
Time of day set to 9pm=时间设置到晚上9点 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!=清空背包 Inventory cleared!=清空背包
Clear inventory=清空背包
Trash:=丢弃: Trash:=丢弃:
Refill:=填满: Refill:=填满:
Any item belonging to the @1 group=属于@1组的任何项目
Any item belonging to the groups @1=属于组@1的任何项目
Recipe @1 of @2=第@1配方共@2个 Recipe @1 of @2=第@1配方共@2个
Usage @1 of @2=第@1用法共@2个 Usage @1 of @2=第@1用法共@2个
No recipes=没有配方 No recipes=没有配方
No usages=没有用法 No usages=没有用法
Result=结果 Result=结果
Ingredient=原料 Ingredient=原料
Show next recipe=显示下一个配方
Show next usage=显示下一个用法
Show previous recipe=显示前一个配方
Show previous usage=显示前一个用法
@1 (@2)=@1 (@2)
Give me:=给予: Give me:=给予:
This recipe is too@@large to be displayed.=该配方太@@大,不能显示。
To craft grid:=填充物品到合成表 To craft grid:=填充物品到合成表
All=全部 All=全部
Crafting=合成
White=白 White=白
Yellow=黄 Yellow=黄
Red=红 Red=红
@ -76,10 +60,10 @@ Waypoints=航路点
Select Waypoint #@1=查询航路点 #@1 Select Waypoint #@1=查询航路点 #@1
Waypoint @1=航路点 @1 Waypoint @1=航路点 @1
Set waypoint to current location=将航路点设置到当前位置 Set waypoint to current location=将航路点设置到当前位置
Hide waypoint=隐藏航路点 invisible=不可见的
Show waypoint=显示航路点 visible=可见的
Hide coordinates=隐藏坐标 Make waypoint @1=设置航路点 @1
Show coordinates=显示坐标 @1 display of waypoint coordinates=显示航路点@1坐标
Change color of waypoint display=改变航路点显示的颜色 Change color of waypoint display=改变航路点显示的颜色
Edit waypoint name=编辑航路点名称 Edit waypoint name=编辑航路点名称
Waypoint active=航路点已激活 Waypoint active=航路点已激活
@ -89,10 +73,7 @@ World position=世界位置
Name=名称 Name=名称
HUD text color=HUD文本颜色 HUD text color=HUD文本颜色
Reset search and display everything=重置搜索并显示所有物品
##### not used anymore ##### Any item belonging to the @1 group=属于@1组的任何项目
Any item belonging to the groups @1=属于组@1的任何项目
invisible=不可见的
visible=可见的
Make waypoint @1=设置航路点 @1
@1 display of waypoint coordinates=显示航路点@1坐标

View File

@ -1,4 +1,8 @@
# textdomain: unified_inventory # textdomain: unified_inventory
# traslation by: IFRFSX(BingFengFSX)
#Email: IFRFSX@Protonmail.com
Crafting=合成
Mixing=混合 Mixing=混合
Cooking=烹飪 Cooking=烹飪
Digging=挖出 Digging=挖出
@ -7,32 +11,20 @@ Bag @1=揹包@1
Small Bag=小揹包 Small Bag=小揹包
Medium Bag=中揹包 Medium Bag=中揹包
Large Bag=大揹包 Large Bag=大揹包
All Items=所有物品
Misc. Items=雜項
Plant Life=植物
Building Materials=建材
Tools=工具
Minerals and Metals=礦物與金屬
Environment and Worldgen=自然環境
Lighting=光源
and = 和 and = 和
Scroll categories left=向左滾動分類欄
Scroll categories right=向右滾動分類欄
Search=搜索
Reset search and display everything=重置搜索並顯示所有物品
First page=第一頁 First page=第一頁
Back three pages=後退三頁 Back three pages=後退三頁
Back one page=後退一頁 Back one page=後退一頁
Forward one page=前進一頁 Forward one page=前進一頁
Forward three pages=前進三頁 Forward three pages=前進三頁
Last page=最後一頁 Last page=最後一頁
Search=搜索
No matching items=沒有匹配物品 No matching items=沒有匹配物品
No matches.=沒有匹配 No matches.=沒有匹配
Page=頁面 Page=頁面
@1 of @2=第@1頁共@2頁 @1 of @2=第@1頁共@2頁
Filter=過濾器 Filter=過濾器
Can use the creative inventory=可以使用創造揹包 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 Grid=合成表
Crafting Guide=合成指南 Crafting Guide=合成指南
Set home position=設置家的位置 Set home position=設置家的位置
@ -44,29 +36,21 @@ Time of day set to 6am=時間設置到早晨6點
You don't have the settime privilege!=你沒有“settime”權限 You don't have the settime privilege!=你沒有“settime”權限
Set time to night=設置時間到晚上 Set time to night=設置時間到晚上
Time of day set to 9pm=時間設置到晚上9點 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!=清空揹包 Inventory cleared!=清空揹包
Clear inventory=清空揹包
Trash:=丟棄: Trash:=丟棄:
Refill:=填滿: Refill:=填滿:
Any item belonging to the @1 group=屬於@1組的任何項目
Any item belonging to the groups @1=屬於組@1的任何項目
Recipe @1 of @2=第@1配方共@2個 Recipe @1 of @2=第@1配方共@2個
Usage @1 of @2=第@1用法共@2個 Usage @1 of @2=第@1用法共@2個
No recipes=沒有配方 No recipes=沒有配方
No usages=沒有用法 No usages=沒有用法
Result=結果 Result=結果
Ingredient=原料 Ingredient=原料
Show next recipe=顯示下一個配方
Show next usage=顯示下一個用法
Show previous recipe=顯示上一個配方
Show previous usage=顯示上一個用法
@1 (@2)=@1 (@2)
Give me:=給予: Give me:=給予:
This recipe is too@@large to be displayed.=該配方太@@大,不能顯示。
To craft grid:=填充物品到合成表 To craft grid:=填充物品到合成表
All=全部 All=全部
Crafting=合成
White=白 White=白
Yellow=黃 Yellow=黃
Red=紅 Red=紅
@ -76,10 +60,10 @@ Waypoints=航路點
Select Waypoint #@1=查詢航路點 #@1 Select Waypoint #@1=查詢航路點 #@1
Waypoint @1=航路點 @1 Waypoint @1=航路點 @1
Set waypoint to current location=將航路點設置到當前位置 Set waypoint to current location=將航路點設置到當前位置
Hide waypoint=隱藏航路點 invisible=不可見的
Show waypoint=顯示航路點 visible=可見的
Hide coordinates=隱藏坐標 Make waypoint @1=設置航路點 @1
Show coordinates=顯示坐 @1 display of waypoint coordinates=顯示航路點@1座
Change color of waypoint display=改變航路點顯示的顏色 Change color of waypoint display=改變航路點顯示的顏色
Edit waypoint name=編輯航路點名稱 Edit waypoint name=編輯航路點名稱
Waypoint active=航路點已激活 Waypoint active=航路點已激活
@ -89,10 +73,7 @@ World position=世界位置
Name=名稱 Name=名稱
HUD text color=HUD文本顏色 HUD text color=HUD文本顏色
Reset search and display everything=重置搜索並顯示所有物品
##### not used anymore ##### Any item belonging to the @1 group=屬於@1組的任何項目
Any item belonging to the groups @1=屬於組@1的任何項目
invisible=不可見的
visible=可見的
Make waypoint @1=設置航路點 @1
@1 display of waypoint coordinates=顯示航路點@1座標

View File

@ -126,18 +126,25 @@ Example output:
} }
--]] --]]
function unified_inventory.find_usable_items(inv_items, craft_items) function unified_inventory.find_usable_items(inv_items, craft_items)
local get_group = minetest.get_item_group
local result = {} local result = {}
for craft_item in pairs(craft_items) do for craft_item in pairs(craft_items) do
-- may specify group:type1,type2 local group = craft_item:match("^group:(.+)")
local items = unified_inventory.get_matching_items(craft_item)
local found = {} local found = {}
for itemname, _ in pairs(items) do
if inv_items[itemname] then if group ~= nil then
found[itemname] = true for inv_item in pairs(inv_items) do
if get_group(inv_item, group) > 0 then
found[inv_item] = true
end
end
else
if inv_items[craft_item] ~= nil then
found[craft_item] = true
end end
end end
result[craft_item] = found result[craft_item] = found
end end

View File

@ -1,8 +1,7 @@
name = unified_inventory name = unified_inventory
depends = default
optional_depends = default, creative, sfinv, datastorage optional_depends = creative, sfinv, datastorage, farming
description = """ description = """
Unified Inventory replaces the default survival and creative 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. It adds a nicer interface and a number of features, such as a crafting guide.
""" """
min_minetest_version = 5.4.0

View File

@ -1,7 +1,6 @@
local S = minetest.get_translator("unified_inventory") local S = minetest.get_translator("unified_inventory")
local NS = function(s) return s end local NS = function(s) return s end
local F = minetest.formspec_escape local F = minetest.formspec_escape
local ui = unified_inventory
minetest.register_privilege("creative", { minetest.register_privilege("creative", {
description = S("Can use the creative inventory"), description = S("Can use the creative inventory"),
@ -13,9 +12,10 @@ minetest.register_privilege("ui_full", {
give_to_singleplayer = false, give_to_singleplayer = false,
}) })
local trash = minetest.create_detached_inventory("trash", { local trash = minetest.create_detached_inventory("trash", {
--allow_put = function(inv, listname, index, stack, player) --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() -- return stack:get_count()
-- else -- else
-- return 0 -- return 0
@ -29,19 +29,19 @@ local trash = minetest.create_detached_inventory("trash", {
}) })
trash:set_size("main", 1) trash:set_size("main", 1)
ui.register_button("craft", { unified_inventory.register_button("craft", {
type = "image", type = "image",
image = "ui_craft_icon.png", image = "ui_craft_icon.png",
tooltip = S("Crafting Grid") tooltip = S("Crafting Grid")
}) })
ui.register_button("craftguide", { unified_inventory.register_button("craftguide", {
type = "image", type = "image",
image = "ui_craftguide_icon.png", image = "ui_craftguide_icon.png",
tooltip = S("Crafting Guide") tooltip = S("Crafting Guide")
}) })
ui.register_button("home_gui_set", { unified_inventory.register_button("home_gui_set", {
type = "image", type = "image",
image = "ui_sethome_icon.png", image = "ui_sethome_icon.png",
tooltip = S("Set home position"), tooltip = S("Set home position"),
@ -49,8 +49,8 @@ ui.register_button("home_gui_set", {
action = function(player) action = function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {home=true}) then if minetest.check_player_privs(player_name, {home=true}) then
ui.set_home(player, player:get_pos()) unified_inventory.set_home(player, player:get_pos())
local home = ui.home_pos[player_name] local home = unified_inventory.home_pos[player_name]
if home ~= nil then if home ~= nil then
minetest.sound_play("dingdong", minetest.sound_play("dingdong",
{to_player=player_name, gain = 1.0}) {to_player=player_name, gain = 1.0})
@ -60,7 +60,7 @@ ui.register_button("home_gui_set", {
else else
minetest.chat_send_player(player_name, minetest.chat_send_player(player_name,
S("You don't have the \"home\" privilege!")) S("You don't have the \"home\" privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name]) unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
end end
end, end,
condition = function(player) condition = function(player)
@ -68,7 +68,7 @@ ui.register_button("home_gui_set", {
end, end,
}) })
ui.register_button("home_gui_go", { unified_inventory.register_button("home_gui_go", {
type = "image", type = "image",
image = "ui_gohome_icon.png", image = "ui_gohome_icon.png",
tooltip = S("Go home"), tooltip = S("Go home"),
@ -76,13 +76,13 @@ ui.register_button("home_gui_go", {
action = function(player) action = function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {home=true}) then if minetest.check_player_privs(player_name, {home=true}) then
if ui.go_home(player) then if unified_inventory.go_home(player) then
minetest.sound_play("teleport", {to_player = player_name}) minetest.sound_play("teleport", {to_player = player_name})
end end
else else
minetest.chat_send_player(player_name, minetest.chat_send_player(player_name,
S("You don't have the \"home\" privilege!")) S("You don't have the \"home\" privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name]) unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
end end
end, end,
condition = function(player) condition = function(player)
@ -90,7 +90,7 @@ ui.register_button("home_gui_go", {
end, end,
}) })
ui.register_button("misc_set_day", { unified_inventory.register_button("misc_set_day", {
type = "image", type = "image",
image = "ui_sun_icon.png", image = "ui_sun_icon.png",
tooltip = S("Set time to day"), tooltip = S("Set time to day"),
@ -98,7 +98,7 @@ ui.register_button("misc_set_day", {
action = function(player) action = function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {settime=true}) then 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}) {to_player=player_name, gain = 1.0})
minetest.set_timeofday((6000 % 24000) / 24000) minetest.set_timeofday((6000 % 24000) / 24000)
minetest.chat_send_player(player_name, minetest.chat_send_player(player_name,
@ -106,7 +106,7 @@ ui.register_button("misc_set_day", {
else else
minetest.chat_send_player(player_name, minetest.chat_send_player(player_name,
S("You don't have the settime privilege!")) S("You don't have the settime privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name]) unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
end end
end, end,
condition = function(player) condition = function(player)
@ -114,7 +114,7 @@ ui.register_button("misc_set_day", {
end, end,
}) })
ui.register_button("misc_set_night", { unified_inventory.register_button("misc_set_night", {
type = "image", type = "image",
image = "ui_moon_icon.png", image = "ui_moon_icon.png",
tooltip = S("Set time to night"), tooltip = S("Set time to night"),
@ -122,7 +122,7 @@ ui.register_button("misc_set_night", {
action = function(player) action = function(player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {settime=true}) then 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}) {to_player=player_name, gain = 1.0})
minetest.set_timeofday((21000 % 24000) / 24000) minetest.set_timeofday((21000 % 24000) / 24000)
minetest.chat_send_player(player_name, minetest.chat_send_player(player_name,
@ -130,7 +130,7 @@ ui.register_button("misc_set_night", {
else else
minetest.chat_send_player(player_name, minetest.chat_send_player(player_name,
S("You don't have the settime privilege!")) S("You don't have the settime privilege!"))
ui.set_inventory_formspec(player, ui.current_page[player_name]) unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
end end
end, end,
condition = function(player) condition = function(player)
@ -138,19 +138,19 @@ ui.register_button("misc_set_night", {
end, end,
}) })
ui.register_button("clear_inv", { unified_inventory.register_button("clear_inv", {
type = "image", type = "image",
image = "ui_trash_icon.png", image = "ui_trash_icon.png",
tooltip = S("Clear inventory"), tooltip = S("Clear inventory"),
action = function(player) action = function(player)
local player_name = player:get_player_name() 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, minetest.chat_send_player(player_name,
S("This button has been disabled outside" S("This button has been disabled outside"
.." of creative mode to prevent" .." of creative mode to prevent"
.." accidental inventory trashing." .." accidental inventory trashing."
.."\nUse the trash slot instead.")) .."\nUse the trash slot instead."))
ui.set_inventory_formspec(player, ui.current_page[player_name]) unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
return return
end end
player:get_inventory():set_list("main", {}) player:get_inventory():set_list("main", {})
@ -159,42 +159,35 @@ ui.register_button("clear_inv", {
{to_player=player_name, gain = 1.0}) {to_player=player_name, gain = 1.0})
end, end,
condition = function(player) condition = function(player)
return ui.is_creative(player:get_player_name()) return unified_inventory.is_creative(player:get_player_name())
end, end,
}) })
ui.register_page("craft", { unified_inventory.register_page("craft", {
get_formspec = function(player, perplayer_formspec) get_formspec = function(player, perplayer_formspec)
local formheaderx = perplayer_formspec.form_header_x local formspecy = perplayer_formspec.formspec_y
local formheadery = perplayer_formspec.form_header_y local formheadery = perplayer_formspec.form_header_y
local craftx = perplayer_formspec.craft_x
local crafty = perplayer_formspec.craft_y
local player_name = player:get_player_name() local player_name = player:get_player_name()
local formspec = { local formspec = "background[2,"..formspecy..";6,3;ui_crafting_form.png]"
perplayer_formspec.standard_inv_bg, formspec = formspec..string.gsub(unified_inventory.standard_inv_bg, "YYY", (formspecy + 3.4))
perplayer_formspec.craft_grid, formspec = formspec.."label[0,"..formheadery..";" ..F(S("Crafting")).."]"
"label["..formheaderx..","..formheadery..";" ..F(S("Crafting")).."]", formspec = formspec.."listcolors[#00000000;#00000000]"
"listcolors[#00000000;#00000000]", formspec = formspec.."list[current_player;craftpreview;6,"..formspecy..";1,1;]"
"listring[current_name;craft]", formspec = formspec.."list[current_player;craft;2,"..formspecy..";3,3;]"
"listring[current_player;main]" if unified_inventory.trash_enabled or unified_inventory.is_creative(player_name) or minetest.get_player_privs(player_name).give then
} formspec = formspec.."label[7,"..(formspecy + 1.5)..";" .. F(S("Trash:")) .. "]"
local n=#formspec+1 formspec = formspec.."background[7,"..(formspecy + 2)..";1,1;ui_single_slot.png]"
formspec = formspec.."list[detached:trash;main;7,"..(formspecy + 2)..";1,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
end end
formspec = formspec.."listring[current_name;craft]"
if ui.is_creative(player_name) then formspec = formspec.."listring[current_player;main]"
formspec[n] = ui.single_slot(craftx - 2.5, crafty + 2.5) if unified_inventory.is_creative(player_name) then
formspec[n+1] = string.format("label[%f,%f;%s]", craftx - 2.4, crafty + 2.3, F(S("Refill:"))) formspec = formspec.."label[0,"..(formspecy + 1.5)..";" .. F(S("Refill:")) .. "]"
formspec[n+2] = string.format("list[detached:%srefill;main;%f,%f;1,1;]", formspec = formspec.."list[detached:"..F(player_name).."refill;main;0,"..(formspecy +2)..";1,1;]"
F(player_name), craftx - 2.5 + ui.list_img_offset, crafty + 2.5 + ui.list_img_offset)
end end
return {formspec=table.concat(formspec)} return {formspec=formspec}
end, end,
}) })
@ -207,26 +200,24 @@ ui.register_page("craft", {
local function stack_image_button(x, y, w, h, buttonname_prefix, item) local function stack_image_button(x, y, w, h, buttonname_prefix, item)
local name = item:get_name() local name = item:get_name()
local description = item:get_meta():get_string("description") local count = item:get_count()
local show_is_group = false local show_is_group = false
local displayitem = item:to_string() local displayitem = name.." "..count
local selectitem = name local selectitem = name
if name:sub(1, 6) == "group:" then if name:sub(1, 6) == "group:" then
local group_name = name:sub(7) 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 show_is_group = not group_item.sole
displayitem = group_item.item or name displayitem = group_item.item or "unknown"
selectitem = group_item.sole and displayitem or name selectitem = group_item.sole and displayitem or name
end end
local label = show_is_group and "G" or "" local label = show_is_group and "G" or ""
-- Unique id to prevent tooltip being overridden local buttonname = F(buttonname_prefix..unified_inventory.mangle_for_formspec(selectitem))
local id = string.format("%i%i_", x*10, y*10)
local buttonname = F(id..buttonname_prefix..ui.mangle_for_formspec(selectitem))
local button = string.format("item_image_button[%f,%f;%f,%f;%s;%s;%s]", local button = string.format("item_image_button[%f,%f;%f,%f;%s;%s;%s]",
x, y, w, h, x, y, w, h,
F(displayitem), buttonname, label) F(displayitem), buttonname, label)
if show_is_group then if show_is_group then
local groupstring, andcount = ui.extract_groupnames(name) local groupstring, andcount = unified_inventory.extract_groupnames(name)
local grouptip local grouptip
if andcount == 1 then if andcount == 1 then
grouptip = S("Any item belonging to the @1 group", groupstring) grouptip = S("Any item belonging to the @1 group", groupstring)
@ -237,15 +228,10 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item)
if andcount >= 1 then if andcount >= 1 then
button = button .. string.format("tooltip[%s;%s]", buttonname, grouptip) button = button .. string.format("tooltip[%s;%s]", buttonname, grouptip)
end end
elseif description ~= "" then
button = button .. string.format("tooltip[%s;%s]", buttonname, F(description))
end end
return button return button
end 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 = { local recipe_text = {
recipe = NS("Recipe @1 of @2"), recipe = NS("Recipe @1 of @2"),
usage = NS("Usage @1 of @2"), usage = NS("Usage @1 of @2"),
@ -271,97 +257,80 @@ local other_dir = {
usage = "recipe", usage = "recipe",
} }
ui.register_page("craftguide", { unified_inventory.register_page("craftguide", {
get_formspec = function(player, perplayer_formspec) get_formspec = function(player, perplayer_formspec)
local craftguidex = perplayer_formspec.craft_guide_x local formspecy = perplayer_formspec.formspec_y
local craftguidey = perplayer_formspec.craft_guide_y local formheadery = perplayer_formspec.form_header_y
local craftguidearrowx = perplayer_formspec.craft_guide_arrow_x local craftresultx = perplayer_formspec.craft_result_x
local craftguideresultx = perplayer_formspec.craft_guide_result_x local craftresulty = perplayer_formspec.craft_result_y
local formheaderx = perplayer_formspec.form_header_x
local formheadery = perplayer_formspec.form_header_y
local give_x = perplayer_formspec.give_btn_x
local player_name = player:get_player_name() local player_name = player:get_player_name()
local player_privs = minetest.get_player_privs(player_name) local player_privs = minetest.get_player_privs(player_name)
local fs = {
local formspec = { string.gsub(unified_inventory.standard_inv_bg, "YYY", (formspecy + 3.4)),
perplayer_formspec.standard_inv_bg, "label[0,"..formheadery..";" .. F(S("Crafting Guide")) .. "]",
"label["..formheaderx..","..formheadery..";" .. F(S("Crafting Guide")) .. "]",
"listcolors[#00000000;#00000000]" "listcolors[#00000000;#00000000]"
} }
local item_name = unified_inventory.current_item[player_name]
local item_name = ui.current_item[player_name]
if not item_name then if not item_name then
return { formspec = table.concat(formspec) } return { formspec = table.concat(fs) }
end end
local n = 4
local item_def = minetest.registered_items[item_name]
local item_name_shown local item_name_shown
if item_def and item_def.description then if minetest.registered_items[item_name]
item_name_shown = S("@1 (@2)", item_def.description, 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 else
item_name_shown = item_name item_name_shown = item_name
end end
local dir = ui.current_craft_direction[player_name] local dir = unified_inventory.current_craft_direction[player_name]
local rdir = dir == "recipe" and "usage" or "recipe" local rdir = dir == "recipe" and "usage" or "recipe"
local crafts = ui.crafts_for[dir][item_name] local crafts = unified_inventory.crafts_for[dir][item_name]
local alternate = ui.alternate[player_name] local alternate = unified_inventory.alternate[player_name]
local alternates, craft local alternates, craft
if crafts and #crafts > 0 then if crafts and #crafts > 0 then
alternates = #crafts alternates = #crafts
craft = crafts[alternate] craft = crafts[alternate]
end end
local has_give = player_privs.give or ui.is_creative(player_name) local has_give = player_privs.give or unified_inventory.is_creative(player_name)
formspec[n] = string.format("image[%f,%f;%f,%f;ui_crafting_arrow.png]", fs[#fs + 1] = "background[0.5,"..(formspecy + 0.2)..";8,3;ui_craftguide_form.png]"
craftguidearrowx, craftguidey, ui.imgscale, ui.imgscale) fs[#fs + 1] = string.format("textarea[%f,%f;10,1;;%s: %s;]",
craftresultx, craftresulty, F(role_text[dir]), item_name_shown)
formspec[n+1] = string.format("textarea[%f,%f;10,1;;%s: %s;]", fs[#fs + 1] = stack_image_button(0, formspecy, 1.1, 1.1,
perplayer_formspec.craft_guide_resultstr_x, perplayer_formspec.craft_guide_resultstr_y, "item_button_" .. rdir .. "_", ItemStack(item_name))
F(role_text[dir]), item_name_shown)
n = n + 2
local giveme_form =
"label[" .. (give_x + 0.1) .. "," .. (craftguidey + 2.7) .. ";" .. F(S("Give me:")) .. "]" ..
"button[" .. (give_x) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_1;1]"
if item_def and item_def.type ~= "tool" then
giveme_form = giveme_form ..
"button[" .. (give_x + 0.8) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_10;10]" ..
"button[" .. (give_x + 1.6) .. "," .. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_99;99]"
end
if not craft then if not craft then
-- No craft recipes available for this item. -- 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])) fs[#fs + 1] = "label[5.5,"..(formspecy + 2.35)..";"
local no_pos = dir == "recipe" and (craftguidex+2.5) or craftguideresultx .. F(no_recipe_text[dir]) .. "]"
local item_pos = dir == "recipe" and craftguideresultx or (craftguidex+2.5) local no_pos = dir == "recipe" and 4.5 or 6.5
formspec[n+1] = "image["..no_pos..","..craftguidey..";1.2,1.2;ui_no.png]" local item_pos = dir == "recipe" and 6.5 or 4.5
formspec[n+2] = stack_image_button(item_pos, craftguidey, 1.2, 1.2, fs[#fs + 1] = "image["..no_pos..","..formspecy..";1.1,1.1;ui_no.png]"
fs[#fs + 1] = stack_image_button(item_pos, formspecy, 1.1, 1.1,
"item_button_" .. other_dir[dir] .. "_", ItemStack(item_name)) "item_button_" .. other_dir[dir] .. "_", ItemStack(item_name))
if has_give then if has_give then
formspec[n+3] = giveme_form fs[#fs + 1] = "label[0," .. (formspecy + 2.10) .. ";" .. F(S("Give me:")) .. "]"
.. "button[0, " .. (formspecy + 2.7) .. ";0.6,0.5;craftguide_giveme_1;1]"
.. "button[0.6," .. (formspecy + 2.7) .. ";0.7,0.5;craftguide_giveme_10;10]"
.. "button[1.3," .. (formspecy + 2.7) .. ";0.8,0.5;craftguide_giveme_99;99]"
end end
return { formspec = table.concat(formspec) } return { formspec = table.concat(fs) }
else
formspec[n] = stack_image_button(craftguideresultx, craftguidey, 1.2, 1.2,
"item_button_" .. rdir .. "_", ItemStack(craft.output))
n = n + 1
end end
local craft_type = ui.registered_craft_types[craft.type] or local craft_type = unified_inventory.registered_craft_types[craft.type] or
ui.craft_type_defaults(craft.type, {}) unified_inventory.craft_type_defaults(craft.type, {})
if craft_type.icon then if craft_type.icon then
formspec[n] = string.format("image[%f,%f;%f,%f;%s]", fs[#fs + 1] = string.format("image[%f,%f;%f,%f;%s]",
craftguidearrowx+0.35, craftguidey, 0.5, 0.5, craft_type.icon) 5.7, (formspecy + 0.05), 0.5, 0.5, craft_type.icon)
n = n + 1
end end
formspec[n] = string.format("label[%f,%f;%s]", craftguidearrowx + 0.15, craftguidey + 1.4, F(craft_type.description)) fs[#fs + 1] = "label[5.5,"..(formspecy + 1)..";" .. F(craft_type.description).."]"
n = n + 1 fs[#fs + 1] = stack_image_button(6.5, formspecy, 1.1, 1.1,
"item_button_usage_", ItemStack(craft.output))
local display_size = craft_type.dynamic_display_size local display_size = craft_type.dynamic_display_size
and craft_type.dynamic_display_size(craft) and craft_type.dynamic_display_size(craft)
@ -372,12 +341,11 @@ ui.register_page("craftguide", {
-- This keeps recipes aligned to the right, -- This keeps recipes aligned to the right,
-- so that they're close to the arrow. -- so that they're close to the arrow.
local xoffset = craftguidex+3.75 local xoffset = 5.5
local bspc = 1.25
-- Offset factor for crafting grids with side length > 4 -- Offset factor for crafting grids with side length > 4
local of = (3/math.max(3, math.max(display_size.width, display_size.height))) local of = (3/math.max(3, math.max(display_size.width, display_size.height)))
local od = 0 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 local mini_craft_size = 6
if display_size.width >= mini_craft_size then if display_size.width >= mini_craft_size then
od = math.max(1, display_size.width - 2) od = math.max(1, display_size.width - 2)
@ -386,12 +354,12 @@ ui.register_page("craftguide", {
-- Size modifier factor -- Size modifier factor
local sf = math.min(1, of * (1.05 + 0.05*od)) local sf = math.min(1, of * (1.05 + 0.05*od))
-- Button size -- Button size
local bsize = 1.2 * sf local bsize_h = 1.1 * sf
local bsize_w = bsize_h
if display_size.width >= mini_craft_size then -- it's not a normal 3x3 grid if display_size.width >= mini_craft_size then
bsize = 0.8 * sf bsize_w = 1.175 * sf
end 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 y = 1, display_size.height do
for x = 1, display_size.width do for x = 1, display_size.width do
local item local item
@ -401,53 +369,48 @@ ui.register_page("craftguide", {
-- Flipped x, used to build formspec buttons from right to left -- Flipped x, used to build formspec buttons from right to left
local fx = display_size.width - (x-1) local fx = display_size.width - (x-1)
-- x offset, y offset -- x offset, y offset
local xof = ((fx-1) * of + of) * bspc local xof = (fx-1) * of + of
local yof = ((y-1) * of + 1) * bspc local yof = (y-1) * of + 1
if item then if item then
formspec[n] = stack_image_button( fs[#fs + 1] = stack_image_button(
xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize, xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h,
"item_button_recipe_", "item_button_recipe_",
ItemStack(item)) ItemStack(item))
else else
-- Fake buttons just to make grid -- Fake buttons just to make grid
formspec[n] = string.format("image_button[%f,%f;%f,%f;ui_blank_image.png;;]", fs[#fs + 1] = string.format("image_button[%f,%f;%f,%f;ui_blank_image.png;;]",
xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize) xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h)
end end
n = n + 1
end end
end end
else else
-- Error -- Error
formspec[n] = string.format("label[2,%f;%s]", fs[#fs + 1] = string.format("label[2,%f;%s]",
craftguidey, F(S("This recipe is too@nlarge to be displayed."))) formspecy, F(S("This recipe is too@nlarge to be displayed.")))
n = n + 1
end end
if craft_type.uses_crafting_grid and display_size.width <= 3 then 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:")) .. "]" fs[#fs + 1] = "label[0," .. (formspecy + 0.9) .. ";" .. F(S("To craft grid:")) .. "]"
formspec[n+1] = "button[".. (give_x)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_1;1]" .. "button[0, " .. (formspecy + 1.5) .. ";0.6,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]" .. "button[0.6," .. (formspecy + 1.5) .. ";0.7,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")) .. "]" .. "button[1.3," .. (formspecy + 1.5) .. ";0.8,0.5;craftguide_craft_max;" .. F(S("All")) .. "]"
n = n + 4
end end
if has_give then if has_give then
formspec[n] = giveme_form fs[#fs + 1] = "label[0," .. (formspecy + 2.1) .. ";" .. F(S("Give me:")) .. "]"
n = n + 1 .. "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 end
if alternates and alternates > 1 then if alternates and alternates > 1 then
formspec[n] = string.format("label[%f,%f;%s]", fs[#fs + 1] = "label[5.5," .. (formspecy + 1.6) .. ";"
craftguidex+4, craftguidey + 2.3, F(S(recipe_text[dir], alternate, alternates))) .. 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;]", .. "image_button[5.5," .. (formspecy + 2) .. ";1,1;ui_left_icon.png;alternate_prev;]"
craftguidearrowx+0.2, craftguidey + 2.6) .. "image_button[6.5," .. (formspecy + 2) .. ";1,1;ui_right_icon.png;alternate;]"
formspec[n+2] = string.format("image_button[%f,%f;1.1,1.1;ui_right_icon.png;alternate;]", .. "tooltip[alternate_prev;" .. F(prev_alt_text[dir]) .. "]"
craftguidearrowx+1.35, craftguidey + 2.6) .. "tooltip[alternate;" .. F(next_alt_text[dir]) .. "]"
formspec[n+3] = "tooltip[alternate_prev;" .. F(prev_alt_text[dir]) .. "]"
formspec[n+4] = "tooltip[alternate;" .. F(next_alt_text[dir]) .. "]"
end end
return { formspec = table.concat(fs) }
return { formspec = table.concat(formspec) }
end, end,
}) })
@ -455,7 +418,7 @@ local function craftguide_giveme(player, formname, fields)
local player_name = player:get_player_name() local player_name = player:get_player_name()
local player_privs = minetest.get_player_privs(player_name) local player_privs = minetest.get_player_privs(player_name)
if not player_privs.give and if not player_privs.give and
not ui.is_creative(player_name) then not unified_inventory.is_creative(player_name) then
minetest.log("action", "[unified_inventory] Denied give action to player " .. minetest.log("action", "[unified_inventory] Denied give action to player " ..
player_name) player_name)
return return
@ -470,7 +433,7 @@ local function craftguide_giveme(player, formname, fields)
amount = tonumber(amount) or 0 amount = tonumber(amount) or 0
if amount == 0 then return end if amount == 0 then return end
local output = ui.current_item[player_name] local output = unified_inventory.current_item[player_name]
if (not output) or (output == "") then return end if (not output) or (output == "") then return end
local player_inv = player:get_inventory() local player_inv = player:get_inventory()
@ -491,29 +454,21 @@ local function craftguide_craft(player, formname, fields)
local player_name = player:get_player_name() local player_name = player:get_player_name()
local output = ui.current_item[player_name] or "" local output = unified_inventory.current_item[player_name] or ""
if output == "" then return end if output == "" then return end
local crafts = ui.crafts_for[ local crafts = unified_inventory.crafts_for[
ui.current_craft_direction[player_name]][output] or {} unified_inventory.current_craft_direction[player_name]][output] or {}
if #crafts == 0 then return end if #crafts == 0 then return end
local alternate = ui.alternate[player_name] local alternate = unified_inventory.alternate[player_name]
local craft = crafts[alternate] 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 if craft.width > 3 then return end
ui.craftguide_match_craft(player, "main", "craft", craft, amount) unified_inventory.craftguide_match_craft(player, "main", "craft", craft, amount)
ui.set_inventory_formspec(player, "craft") unified_inventory.set_inventory_formspec(player, "craft")
end end
minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.register_on_player_receive_fields(function(player, formname, fields)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -1,36 +1,11 @@
# Reduced formspec layout, optimized for smaller displays. #Enabling lite mode enables a smaller and simpler version of the Unified
# Note: This may also disable some features to free up visual space. #Inventory, optimized for small displays.
unified_inventory_lite (Lite mode) bool false unified_inventory_lite (Lite mode) bool false
# Provides craftable bag items to extend the inventory space. #If enabled, bags will be made available which can be used to extend
#inventory storage size.
unified_inventory_bags (Enable bags) bool true unified_inventory_bags (Enable bags) bool true
# Shows the trash slot to everyone. #If enabled, the trash slot can be used by those without both creative
# When disabled, only players with the privilege "creative" or "give" will #and the give privilege.
# have this slot shown in their inventory.
unified_inventory_trash (Enable trash) bool true 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 Normal file

Binary file not shown.

BIN
sounds/owl.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
textures/ui_bags_header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
textures/ui_bags_trash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
textures/ui_form_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
textures/ui_misc_form.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
textures/ui_xyz_on_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,7 +1,5 @@
local S = minetest.get_translator("unified_inventory") local S = minetest.get_translator("unified_inventory")
local F = minetest.formspec_escape local F = minetest.formspec_escape
local ui = unified_inventory
local COUNT = 5
local hud_colors = { local hud_colors = {
{"#FFFFFF", 0xFFFFFF, S("White")}, {"#FFFFFF", 0xFFFFFF, S("White")},
@ -11,231 +9,118 @@ local hud_colors = {
{"#2c4df1", 0x2c4df1, S("Blue")}, {"#2c4df1", 0x2c4df1, S("Blue")},
} }
-- Storage compatibility code local hud_colors_max = #hud_colors
--[[ -- Stores temporary player data (persists until player leaves)
Stores temporary player data (persists until player leaves)
[player_name] = {
[<waypoint index>] = {
edit = <edit current waypoint?>,
hud = <hud ID>,
},
[<waypoint index>] = { ... },
...
}
]]
local waypoints_temp = {} local waypoints_temp = {}
--[[ unified_inventory.register_page("waypoints", {
Datastorage format (per-player): get_formspec = function(player)
{
selected = <waypoint index>,
[<waypoint index>] = {
name = <name or nil>
world_pos = <coordinates vector>,
color = <"hud_colors" index>,
active = <hud show waypoint?>,
display_pos = <hud display coorinates?>,
},
[<waypoint index>] = { ... },
...
}
Player metadata format:
{
selected = <selected number>,
-- Cannot mix integer/string keys in JSON
data = {
[<waypoint index>] = { same as above },
...
}
}
]]
local function set_waypoint_data(player, waypoints)
local meta = player:get_meta()
if not next(waypoints.data or {}) then
-- Empty data. Do not save anything, or delete
meta:set_string("ui_waypoints", "")
else
meta:set_string("ui_waypoints", minetest.write_json(waypoints))
end
end
local function migrate_datastorage(player, waypoints)
-- Copy values from old table
local new_data = {
selected = waypoints.selected,
data = {}
}
for i = 1, COUNT do
new_data.data[i] = waypoints[i]
end
set_waypoint_data(player, new_data)
-- Delete values, but keep one entry so that it's saved by datastorage
for k, _ in pairs(waypoints) do
waypoints[k] = nil
end
waypoints[1] = 1
end
local have_datastorage = minetest.get_modpath("datastorage") ~= nil
local function get_waypoint_data(player)
local player_name = player:get_player_name()
-- Migration step
if have_datastorage then
local waypoints = datastorage.get(player_name, "waypoints")
if waypoints.selected then
migrate_datastorage(player, waypoints)
minetest.log("action", "[unified_inventory] " ..
"Migrated waypoints of player: " .. player_name)
end
end
-- Get directly from metadata
local waypoints = player:get_meta():get("ui_waypoints")
waypoints = waypoints and minetest.parse_json(waypoints) or {}
waypoints.data = waypoints.data or {}
return waypoints
end
ui.register_page("waypoints", {
get_formspec = function(player, perplayer_formspec)
local player_name = player:get_player_name() local player_name = player:get_player_name()
local wp_info_x = ui.style_full.form_header_x + 1.25
local wp_info_y = ui.style_full.form_header_y + 0.5
local wp_bottom_row = ui.style_full.std_inv_y - 1
local wp_buttons_rj = ui.style_full.std_inv_x + 10.1 - ui.style_full.btn_spc
local wp_edit_w = ui.style_full.btn_spc * 4 - 0.1
local waypoints = get_waypoint_data(player) -- build a "fake" temp entry if the server took too long
local sel = waypoints.selected or 1 -- during sign-on and returned an empty entry
if not waypoints_temp[player_name] then waypoints_temp[player_name] = {hud = 1} end
local formspec = { local waypoints = datastorage.get(player_name, "waypoints")
string.format("label[%f,%f;%s]", local formspec = string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4") ..
ui.style_full.form_header_x, ui.style_full.form_header_y, F(S("Waypoints"))), "image[0,0;1,1;ui_waypoints_icon.png]" ..
"image["..wp_info_x..","..wp_info_y..";1,1;ui_waypoints_icon.png]" "label[1,0;" .. F(S("Waypoints")) .. "]"
}
local n=3
if not perplayer_formspec.is_lite_mode then
formspec[n] = ui.style_full.standard_inv_bg
n = n + 1
end
-- Tabs buttons: -- Tabs buttons:
for i = 1, COUNT do for i = 1, 5, 1 do
local sw="select_waypoint"..i formspec = formspec ..
formspec[n] = string.format("image_button[%f,%f;%f,%f;%sui_%i_icon.png;%s;]", "image_button[0.0," .. 0.2 + i * 0.7 .. ";.8,.8;" ..
ui.style_full.main_button_x, wp_bottom_row - (5-i) * ui.style_full.btn_spc, (i == waypoints.selected and "ui_blue_icon_background.png^" or "") ..
ui.style_full.btn_size, ui.style_full.btn_size, "ui_" .. i .. "_icon.png;" ..
(i == sel) and "ui_blue_icon_background.png^" or "", "select_waypoint" .. i .. ";]" ..
i, sw) "tooltip[select_waypoint" .. i .. ";"
formspec[n+1] = "tooltip["..sw..";"..S("Select Waypoint #@1", i).."]" .. S("Select Waypoint #@1", i).."]"
n = n + 2
end end
local waypoint = waypoints.data[sel] or {} local i = waypoints.selected or 1
local temp = waypoints_temp[player_name][sel] or {} local waypoint = waypoints[i] or {}
local default_name = S("Waypoint @1", sel) local temp = waypoints_temp[player_name][i] or {}
local default_name = S("Waypoint @1", i)
-- Main buttons: -- Main buttons:
local btnlist = { formspec = formspec ..
-- 1. formspec name "image_button[4.5,3.7;.8,.8;"..
-- 2. button image "ui_waypoint_set_icon.png;"..
-- 3. translation text "set_waypoint"..i..";]"..
{ "tooltip[set_waypoint" .. i .. ";"
"toggle_waypoint", .. F(S("Set waypoint to current location")).."]"
waypoint.active and "ui_on_icon.png" or "ui_off_icon.png",
waypoint.active and S("Hide waypoint") or S("Show waypoint")
},
{
"rename_waypoint",
"ui_pencil_icon.png",
S("Edit waypoint name")
},
{
"set_waypoint",
"ui_waypoint_set_icon.png",
S("Set waypoint to current location")
},
{
"toggle_display_pos",
waypoint.display_pos and "ui_green_icon_background.png^ui_xyz_icon.png" or "ui_red_icon_background.png^ui_xyz_icon.png^(ui_no.png^[transformR90)",
waypoint.display_pos and S("Hide coordinates") or S("Show coordinates")
},
{
"toggle_color",
"ui_circular_arrows_icon.png",
S("Change color of waypoint display")
},
}
if minetest.get_player_privs(player_name).teleport then
table.insert(btnlist, {
"teleport_waypoint",
"ui_teleport.png",
S("Teleport to waypoint")
})
end
for i, def in pairs(btnlist) do formspec = formspec ..
formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s%i;]", "image_button[5.2,3.7;.8,.8;"..
wp_buttons_rj + ui.style_full.btn_spc * (i - #btnlist), wp_bottom_row, (waypoint.active and "ui_on_icon.png" or "ui_off_icon.png")..";"..
ui.style_full.btn_size, ui.style_full.btn_size, "toggle_waypoint"..i..";]"..
def[2], def[1], sel) "tooltip[toggle_waypoint" .. i .. ";"
formspec[n+1] = "tooltip["..def[1]..sel..";"..F(def[3]).."]" .. F(S("Make waypoint @1",
n = n + 2 waypoint.active and S("invisible") or S("visible"))).."]"
end
formspec = formspec ..
"image_button[5.9,3.7;.8,.8;"..
(waypoint.display_pos and "ui_green_icon_background.png" or "ui_red_icon_background.png").."^ui_xyz_icon.png;"..
"toggle_display_pos" .. i .. ";]"..
"tooltip[toggle_display_pos" .. i .. ";"
.. F(S("@1 display of waypoint coordinates",
waypoint.display_pos and S("Disable") or S("Enable"))) .."]"
formspec = formspec ..
"image_button[6.6,3.7;.8,.8;"..
"ui_circular_arrows_icon.png;"..
"toggle_color"..i..";]"..
"tooltip[toggle_color" .. i .. ";"
.. F(S("Change color of waypoint display")).."]"
formspec = formspec ..
"image_button[7.3,3.7;.8,.8;"..
"ui_pencil_icon.png;"..
"rename_waypoint"..i..";]"..
"tooltip[rename_waypoint" .. i .. ";"
.. F(S("Edit waypoint name")).."]"
-- Waypoint's info: -- Waypoint's info:
formspec[n] = ("label[%f,%f;%s]"):format( if waypoint.active then
wp_info_x, wp_info_y + 1.1, formspec = formspec .. "label[1,0.8;"..F(S("Waypoint active")).."]"
F(waypoint.active and S("Waypoint active") or S("Waypoint inactive")) else
) formspec = formspec .. "label[1,0.8;"..F(S("Waypoint inactive")).."]"
n = n + 1
if temp.edit then
formspec[n] = string.format("field[%f,%f;%f,%f;rename_box%i;;%s]",
wp_buttons_rj - wp_edit_w - 0.1, wp_bottom_row - ui.style_full.btn_spc,
wp_edit_w, ui.style_full.btn_size, sel, (waypoint.name or default_name))
formspec[n+1] = string.format("image_button[%f,%f;%f,%f;ui_ok_icon.png;confirm_rename%i;]",
wp_buttons_rj, wp_bottom_row - ui.style_full.btn_spc,
ui.style_full.btn_size, ui.style_full.btn_size, sel)
formspec[n+2] = "tooltip[confirm_rename"..sel..";"..F(S("Finish editing")).."]"
n = n + 3
end end
formspec[n] = string.format("label[%f,%f;%s: %s]", if temp.edit then
wp_info_x, wp_info_y+1.6, F(S("World position")), formspec = formspec ..
minetest.pos_to_string(waypoint.world_pos or vector.new())) "field[1.3,3.2;6,.8;rename_box" .. i .. ";;"
formspec[n+1] = string.format("label[%f,%f;%s: %s]", ..(waypoint.name or default_name).."]" ..
wp_info_x, wp_info_y+2.10, F(S("Name")), (waypoint.name or default_name)) "image_button[7.3,2.9;.8,.8;"..
formspec[n+2] = string.format("label[%f,%f;%s: %s]", "ui_ok_icon.png;"..
wp_info_x, wp_info_y+2.60, F(S("HUD text color")), hud_colors[waypoint.color or 1][3]) "confirm_rename"..i.. ";]"..
"tooltip[confirm_rename" .. i .. ";"
.. F(S("Finish editing")).."]"
end
return { formspec = formspec .. "label[1,1.3;"..F(S("World position"))..": " ..
formspec = table.concat(formspec), minetest.pos_to_string(waypoint.world_pos or vector.new()) .. "]" ..
draw_inventory = not perplayer_formspec.is_lite_mode, "label[1,1.8;"..F(S("Name"))..": ".. (waypoint.name or default_name) .. "]" ..
} "label[1,2.3;"..F(S("HUD text color"))..": " ..
hud_colors[waypoint.color or 1][3] .. "]"
return {formspec=formspec}
end, end,
}) })
ui.register_button("waypoints", { unified_inventory.register_button("waypoints", {
type = "image", type = "image",
image = "ui_waypoints_icon.png", image = "ui_waypoints_icon.png",
tooltip = S("Waypoints"), tooltip = S("Waypoints"),
hide_lite=true
}) })
local function update_hud(player, waypoints, temp, i) local function update_hud(player, waypoints, temp, i)
local waypoint = waypoints.data[i] local waypoint = waypoints[i]
if not waypoint then return end if not waypoint then return end
temp[i] = temp[i] or {} temp[i] = temp[i] or {}
temp = temp[i] temp = temp[i]
local pos = waypoint.world_pos or vector.new() local pos = waypoint.world_pos or vector.new()
local name local name
if waypoint.display_pos then if waypoint.display_pos then
@ -244,13 +129,10 @@ local function update_hud(player, waypoints, temp, i)
name = name..", "..waypoint.name name = name..", "..waypoint.name
end end
else else
name = waypoint.name or S("Waypoint @1", i) name = waypoint.name or "Waypoint "..i
end end
-- Perform HUD updates
if temp.hud then if temp.hud then
player:hud_remove(temp.hud) player:hud_remove(temp.hud)
temp.hud = nil
end end
if waypoint.active then if waypoint.active then
temp.hud = player:hud_add({ temp.hud = player:hud_add({
@ -260,6 +142,8 @@ local function update_hud(player, waypoints, temp, i)
text = "m", text = "m",
world_pos = pos world_pos = pos
}) })
else
temp.hud = nil
end end
end end
@ -271,11 +155,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local need_update_hud = false local need_update_hud = false
local hit = false local hit = false
local waypoints = get_waypoint_data(player) local waypoints = datastorage.get(player_name, "waypoints")
local temp = waypoints_temp[player_name] local temp = waypoints_temp[player_name]
for i = 1, COUNT do for i = 1, 5, 1 do
local waypoint = waypoints.data[i] or {}
if fields["select_waypoint"..i] then if fields["select_waypoint"..i] then
hit = true hit = true
waypoints.selected = i waypoints.selected = i
@ -284,15 +166,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields["toggle_waypoint"..i] then if fields["toggle_waypoint"..i] then
hit = true hit = true
waypoint.active = not (waypoint.active) waypoints[i] = waypoints[i] or {}
waypoints[i].active = not (waypoints[i].active)
need_update_hud = true need_update_hud = true
update_formspec = true update_formspec = true
end end
if fields["set_waypoint"..i] then if fields["set_waypoint"..i] then
hit = true hit = true
local pos = vector.round(player:get_pos()) local pos = player:get_pos()
waypoint.world_pos = pos pos.x = math.floor(pos.x)
pos.y = math.floor(pos.y)
pos.z = math.floor(pos.z)
waypoints[i] = waypoints[i] or {}
waypoints[i].world_pos = pos
need_update_hud = true need_update_hud = true
update_formspec = true update_formspec = true
end end
@ -306,66 +193,51 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields["toggle_display_pos"..i] then if fields["toggle_display_pos"..i] then
hit = true hit = true
waypoint.display_pos = not waypoint.display_pos waypoints[i] = waypoints[i] or {}
waypoints[i].display_pos = not waypoints[i].display_pos
need_update_hud = true need_update_hud = true
update_formspec = true update_formspec = true
end end
if fields["toggle_color"..i] then if fields["toggle_color"..i] then
hit = true hit = true
local color = waypoint.color or 0 waypoints[i] = waypoints[i] or {}
local color = waypoints[i].color or 1
color = color + 1 color = color + 1
if color > #hud_colors then if color > hud_colors_max then
color = 1 color = 1
end end
waypoint.color = color waypoints[i].color = color
need_update_hud = true need_update_hud = true
update_formspec = true update_formspec = true
end end
if fields["confirm_rename"..i] then if fields["confirm_rename"..i] then
hit = true hit = true
temp[i] = temp[i] or {} waypoints[i] = waypoints[i] or {}
temp[i].edit = false temp[i].edit = false
waypoint.name = fields["rename_box"..i] waypoints[i].name = fields["rename_box"..i]
need_update_hud = true need_update_hud = true
update_formspec = true update_formspec = true
end end
if fields["teleport_waypoint" .. i] and waypoint.world_pos then
if minetest.get_player_privs(player_name).teleport then
minetest.sound_play("teleport", {to_player = player_name})
player:set_pos(waypoint.world_pos)
end
end
if hit then
-- Save first
waypoints.data[i] = waypoint
set_waypoint_data(player, waypoints)
end
-- Update after
if need_update_hud then if need_update_hud then
update_hud(player, waypoints, temp, i) update_hud(player, waypoints, temp, i)
end end
if update_formspec then if update_formspec then
minetest.sound_play("ui_click", {to_player=player_name, gain = 0.1}) unified_inventory.set_inventory_formspec(player, "waypoints")
ui.set_inventory_formspec(player, "waypoints")
end end
if hit then return end if hit then return end
end end
end) end)
-- waypoints_temp must be initialized before the general unified_inventory
-- joinplayer callback is run for updating the inventory
table.insert(minetest.registered_on_joinplayers, 1, function(player)
local player_name = player:get_player_name()
local waypoints = get_waypoint_data(player)
waypoints_temp[player_name] = {} minetest.register_on_joinplayer(function(player)
for i = 1, COUNT do local player_name = player:get_player_name()
update_hud(player, waypoints, waypoints_temp[player_name], i) local waypoints = datastorage.get(player_name, "waypoints")
local temp = {}
waypoints_temp[player_name] = temp
for i = 1, 5 do
update_hud(player, waypoints, temp, i)
end end
end) end)