42 Commits

Author SHA1 Message Date
c884727ff3 Version MFF. 2018-09-08 23:00:32 +02:00
4bae2c7fa3 Russian translation 2014-12-30 14:30:29 +01:00
jp
9672ec599e Add French locale 2014-12-30 14:30:29 +01:00
4fce317e2e Fix crash when changing waypoint name 2014-09-07 15:08:52 -04:00
527812fa96 Make waypoints optional and use external datastorage mod
This also fixes waypoints not showing up on join.
2014-07-06 17:39:20 -04:00
0d777362f3 Update tooltips usage due to core changes. 2014-06-24 12:39:12 +02:00
f800f39083 More tooltips and translations. 2014-06-22 00:34:35 +02:00
810f342458 Add spanish translation. 2014-06-21 08:25:44 -03:00
002bcbb6d8 Add intllib support.
Some polish and german translations.
Start adding tooltips.
2014-06-21 12:44:31 +02:00
87f502a259 Show item usages in craft guide
When the craft guide is showing a craft, the output slot is now a button,
which causes the craft guide to show ways in which that output can be
used.  This mirrors the way input slots are buttons that show recipes
for the selected ingredient.  Usages of an item can be iterated through
in the same way as recipes for the item.  This incidentally offers some
ability to retrace one's steps through a crafting chain, without storing
actual history.
2014-06-13 11:30:09 -03:00
c33efe8631 Cleaner display of lack of recipes (redux)
When the current craft guide item has no recipes, show a "no" symbol
instead of an ingredient grid, alongside the "No recipes" message.
When no item is selected in the craft guide, leave the recipe space empty.
2014-06-13 09:28:40 -03:00
4c982dd667 Fix and enhance grid shapes in craft guide
Commit 043f608145 made shaped crafting
recipes display in a grid of the recipe's minimum bounding box,
but broke the use of a fixed 1x1 grid shape for cooking recipes.
This commit generalises the dynamic-grid-shape facility, putting the
craft type registration in charge.  This restores the correct shape for
cooking recipes.

Also change the logic for dynamic grid sizes for regular shaped and
shapeless crafting.  We'd like to always use a grid shape that is
reminiscent of a regular crafting grid, as a visual cue to the crafting
method.  But it's also nice to show smaller recipes in a smaller grid.
In the expectation that crafting grids will always be square, show the
recipe in the smallest square grid that will accommodate it.
2014-06-13 09:28:39 -03:00
a8c8ef0890 Correctly display multi-group ingredients
Extend the representative-item logic to handle ingredients specified
as the intersection of multiple groups.  Also add mangling of item
button content, because comma for a multi-group ingredient is getting
formspec-escaped and then not de-escaped.
2014-06-13 09:28:37 -03:00
dbf98cb694 Fix display of group ingredients
Commit 043f608145 broke a couple of things
in the course of its refactoring.  This patch restores the "G" flag that
signals group ingredients, the preference for "default:" items as group
representatives (where a representative isn't specifically registered),
and the built-in registration of default:cobble as representative for
group:stone (because it's the most commonly-used item in that group).
2014-06-13 06:28:38 -03:00
7f4f0fd225 Use plain substring search in craft guide
The user input was being erroneously treated as a lua regexp.
2014-06-13 04:50:07 -03:00
833a255ad4 Some fixes to item_names and waypoints. 2014-05-26 11:43:25 +02:00
b46f4217ae Item names hud element (based on 4aiman mod) 2014-05-26 05:41:40 +02:00
3003b19322 Add sorting inventories function. 2014-05-22 21:24:24 +02:00
44d967bbe5 did the same for sun/moon icons 2014-05-19 02:02:34 -04:00
82d204cb7a Added a small empty border around most icons
(and shrunk them accordingly)
2014-05-19 01:58:20 -04:00
6780ae4abd better "xyz off" image 2014-05-13 20:56:59 -04:00
3f8a7fb816 All new imagery, redone from scratch at 128px. 2014-05-13 20:48:10 -04:00
043f608145 Move around some group code and make the craftguide render well without a recipe
This also keeps recipes aligned to the right, close to the arrow.
It also calculates the craft's height.
2014-05-11 22:00:32 -04:00
ba956d6838 Add missing textures for waypoints 2014-05-05 09:59:59 +02:00
b9b2892f28 Add waypoints support (requires current minetest from git) 2014-05-05 09:39:03 +02:00
79320c109c Respect not_in_creative_inventory in group search 2014-05-02 12:21:10 +02:00
12ef7f6393 Remove stray debugging print
Previous commit left this in.
2014-05-02 12:20:13 +02:00
b492701915 Show group ingredients visually in craft guide
Where a recipe specifies an ingredient by group, show a typical group
item pictorially, with a label flag to indicate that it's a group rather
than the single item.  This is the inverse of the previous arrangement,
which identified the group by label and dipicted groupiness pictorially.
The new arrangement is easier to interpret, and if the labels are ignored
it actually shows a correct input to the crafting grid.
2014-05-02 12:19:17 +02:00
5d34b235dd Handle ingredient quantities in craft guide
Alloy cooking recipes have quantities for the ingredients, which need to
be shown.  The buttons on which the ingredients are shown don't natively
support showing an item count, so hack it up with the label facility.
Also, the button names, supporting clicking to see recipes recursively,
need to be based only on the item name part of the ingredient, dropping
the quantity part.
2014-05-02 12:14:48 +02:00
b3d83bc953 Support item-dependent refill behaviour
The refill slot was only putting as many items as possible in a
stack, which does nothing for tools.  Tools could benefit from repair,
recharging, or other behaviour depending on the type of tool.  Change the
default refill behaviour to repair mechanical wear as well as fully
stacking.  Because other kinds of refill will require knowledge of the
metadata format, they can't be directly handled here.  So add an on_refill
hook, that tool definitions can supply to plug in appropriate behaviour.
2014-04-30 10:45:45 +01:00
d1e554b73d Cleaner display of lack of recipes
When the current craft guide item has no recipes, show the item and a
"No recipes" message, but suppress all other recipe UI elements.
2014-04-30 01:10:46 +01:00
580a832fda Use appropriate grid shape for each craft type
New system of registration of craft types, recording for each a display
description and the appropriate grid shape.  Recipes of a registered type
are shown in the correct grid.  Recipes of unregistered craft types are
still displayed as before, using the default 3x3 grid.
2014-04-30 00:11:10 +01:00
48d28b1e5d Show non-identity digging results in craft guide 2014-04-29 22:14:08 +01:00
87cfad559b Don't overwrite registered crafts
The crafts_table was being initialised to contain only core-registered
crafts, but this would overwrite any non-core craft types that had
already been registered via unified_inventory.register_craft().  This was
especially likely because the crafts_table initialisation runs on a delay,
following all normal initialisation.  Instead, feed the core-registered
crafts into unified_inventory.register_craft().
2014-04-29 21:38:31 +01:00
37d87d6afc Only do paperflip sound when really changing page 2014-04-29 20:40:48 +01:00
b0e10d44f4 Tweak display of searching status
When the current search produces no results, give a specific message
rather than "Page 1 of 0".  Don't display the "Filter:" label if no
filtering is currently applied.
2014-04-29 20:08:04 +01:00
01297996a6 Preserve player's search string
Keep the current inventory search string when performing inventory
form actions other than searching.  This means the player's input is
not lost if the player breaks off from entering it to switch pages,
or if the player absent-mindedly ends text input with <return>.
2014-04-29 19:36:52 +01:00
20cf474886 Fix formspec injection issues 2014-04-29 17:53:43 +01:00
76a2337c59 Show bag number when displaying bag contents 2014-04-29 17:19:57 +01:00
5e52f3c49c Add .gitignore 2014-04-22 16:52:04 -04:00
910c9fad5b Update README 2014-04-22 16:52:04 -04:00
fa0142c2c0 Look for recipes under an item's aliases
get_all_craft_recipes() returns the recipes that were registered under the
specified name, so asking about an item's canonical name won't see recipes
registered under an alias, and vice versa.  Several mods register recipes
under aliases, so the craft guide was missing that handful of recipes.
To work around it, invert the aliases table and ask explicitly about
each alias.
2014-04-22 16:52:04 -04:00
100 changed files with 2358 additions and 596 deletions

2
.gitignore vendored Executable file
View File

@ -0,0 +1,2 @@
*~

31
README.md Normal file → Executable file
View File

@ -1,6 +1,31 @@
unified_inventory
Unified inventory
=================
Replacement for Minetest 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.
License
=======
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
Unified inventory code is licensed under the GNU LGPLv2+.
Licenses for textures:
VanessaE: (WTFPL)
* ui\_group.png
* ui_form_bg : credits to moretrees mod.
© 2013, Vanessa Ezekowitz <vanessaezekowitz@gmail.com>
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
RealBadAngel: (WTFPL)
* Bags icons
* ui_numbers
* waypoints icons, ui_group, ui_ok, circular_arrows, xyz_icons
Obani : (CC-BY)
* Ui formspecs textures
* Every other icon
Unified Inventory replaces the survival and creative inventory; it also functions as a crafting guide.

288
api.lua Normal file → Executable file
View File

@ -1,89 +1,307 @@
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
-- Create detached creative inventory after loading all mods
minetest.after(0.01, function()
local rev_aliases = {}
for source, target in pairs(minetest.registered_aliases) do
if not rev_aliases[target] then rev_aliases[target] = {} end
table.insert(rev_aliases[target], source)
end
unified_inventory.items_list = {}
for name, def in pairs(minetest.registered_items) do
if (not def.groups.not_in_creative_inventory or
def.groups.not_in_creative_inventory == 0) and
def.description and def.description ~= "" then
table.insert(unified_inventory.items_list, name)
local recipes = minetest.get_all_craft_recipes(name)
if recipes then
unified_inventory.crafts_table[name] = recipes
else
unified_inventory.crafts_table[name] = {}
local all_names = rev_aliases[name] or {}
table.insert(all_names, name)
for _, name in ipairs(all_names) do
local recipes = minetest.get_all_craft_recipes(name)
if recipes then
for _, recipe in ipairs(recipes) do
local unknowns
for _,chk in pairs(recipe.items) do
local groupchk = string.find(chk, "group:")
if groupchk then
for _,groupname in pairs(string.gsub(chk, "group:", ""):split(",")) do
if not unified_inventory.get_group_item(groupname).item then
unknowns = true
if minetest.setting_getbool("show_unknown_craftrecipes") then
minetest.log("error", "Recipe for item " .. recipe.output .. " contains unknown group " .. groupname)
end
break
end
end
elseif not minetest.registered_items[chk] then
unknowns = true
if minetest.setting_getbool("show_unknown_craftrecipes") then
minetest.log("error", "Recipe for item " .. recipe.output .. " contains unknown item " .. chk)
end
break
end
end
if not unknowns then
unified_inventory.register_craft(recipe)
end
end
end
end
end
end
table.sort(unified_inventory.items_list)
unified_inventory.items_list_size = #unified_inventory.items_list
print("Unified Inventory. inventory size: "..unified_inventory.items_list_size)
minetest.log("Unified Inventory. inventory size: "..unified_inventory.items_list_size)
for _, name in ipairs(unified_inventory.items_list) do
local def = minetest.registered_items[name]
-- Simple drops
if type(def.drop) == "string" then
local dstack = ItemStack(def.drop)
if not dstack:is_empty() and dstack:get_name() ~= name then
unified_inventory.register_craft({
type = "digging",
items = {name},
output = def.drop,
width = 0,
})
end
-- Complex drops. Yes, it's really complex!
elseif type(def.drop) == "table" then
--[[ Extract single items from the table and save them into dedicated tables
to register them later, in order to avoid duplicates. These tables counts
the total number of guaranteed drops and drops by chance (“maybes”) for each item.
For “maybes”, the final count is the theoretical maximum number of items, not
neccessarily the actual drop count. ]]
local drop_guaranteed = {}
local drop_maybe = {}
-- This is for catching an obscure corner case: If the top items table has
-- only items with rarity = 1, but max_items is set, then only the first
-- max_items will be part of the drop, any later entries are logically
-- impossible, so this variable is for keeping track of this
local max_items_left = def.drop.max_items
-- For checking whether we still encountered only guaranteed only so far;
-- for the first “maybe” item it will become false which will cause ALL
-- later items to be considered “maybes”.
-- A common idiom is:
-- { max_items 1, { items = {
-- { items={"example:1"}, rarity = 5 },
-- { items={"example:2"}, rarity = 1 }, }}}
-- example:2 must be considered a “maybe” because max_items is set and it
-- appears after a “maybe”
local max_start = true
-- Let's iterate through the items madness!
if def.drop.items then
for i=1,#def.drop.items do
if max_items_left ~= nil and max_items_left <= 0 then break end
local itit = def.drop.items[i]
for j=1,#itit.items do
local dstack = ItemStack(itit.items[j])
if not dstack:is_empty() and dstack:get_name() ~= name then
local dname = dstack:get_name()
local dcount = dstack:get_count()
-- Guaranteed drops AND we are not yet in “maybe mode”
if #itit.items == 1 and itit.rarity == 1 and max_start then
if drop_guaranteed[dname] == nil then
drop_guaranteed[dname] = 0
end
drop_guaranteed[dname] = drop_guaranteed[dname] + dcount
if max_items_left ~= nil then
max_items_left = max_items_left - 1
if max_items_left <= 0 then break end
end
-- Drop was a “maybe”
else
if max_items_left ~= nil then max_start = false end
if drop_maybe[dname] == nil then
drop_maybe[dname] = 0
end
drop_maybe[dname] = drop_maybe[dname] + dcount
end
end
end
end
end
for itemstring, count in pairs(drop_guaranteed) do
unified_inventory.register_craft({
type = "digging",
items = {name},
output = itemstring .. " " .. count,
width = 0,
})
end
for itemstring, count in pairs(drop_maybe) do
unified_inventory.register_craft({
type = "digging_chance",
items = {name},
output = itemstring .. " " .. count,
width = 0,
})
end
end
end
for _, recipes in pairs(unified_inventory.crafts_for.recipe) do
for _, recipe in ipairs(recipes) do
local ingredient_items = {}
for _, spec in ipairs(recipe.items) do
local matches_spec = unified_inventory.canonical_item_spec_matcher(spec)
for _, name in ipairs(unified_inventory.items_list) do
if matches_spec(name) then
ingredient_items[name] = true
end
end
end
for name, _ in pairs(ingredient_items) do
if unified_inventory.crafts_for.usage[name] == nil then
unified_inventory.crafts_for.usage[name] = {}
end
table.insert(unified_inventory.crafts_for.usage[name], recipe)
end
end
end
end)
-- load_home
local function load_home()
local input = io.open(unified_inventory.home_filename, "r")
if input then
while true do
local x = input:read("*n")
if x == nil then
break
end
local y = input:read("*n")
local z = input:read("*n")
local name = input:read("*l")
unified_inventory.home_pos[name:sub(2)] = {x = x, y = y, z = z}
end
io.close(input)
else
if not input then
unified_inventory.home_pos = {}
return
end
while true do
local x = input:read("*n")
if not x then break end
local y = input:read("*n")
local z = input:read("*n")
local name = input:read("*l")
unified_inventory.home_pos[name:sub(2)] = {x = x, y = y, z = z}
end
io.close(input)
end
load_home()
function unified_inventory.set_home(player, pos)
local player_name = player:get_player_name()
unified_inventory.home_pos[player_name] = pos
unified_inventory.home_pos[player_name] = vector.round(pos)
-- save the home data from the table to the file
local output = io.open(unified_inventory.home_filename, "w")
for k, v in pairs(unified_inventory.home_pos) do
if v ~= nil then
output:write(math.floor(v.x).." "
..math.floor(v.y).." "
..math.floor(v.z).." "
..k.."\n")
end
output:write(v.x.." "..v.y.." "..v.z.." "..k.."\n")
end
io.close(output)
end
function unified_inventory.go_home(player)
local pos = unified_inventory.home_pos[player:get_player_name()]
if pos ~= nil then
if pos then
player:setpos(pos)
end
end
-- register_craft
function unified_inventory.register_craft(options)
if options.output == nil then
if not options.output then
return
end
local itemstack = ItemStack(options.output)
if itemstack:is_empty() then
return
end
if unified_inventory.crafts_table[itemstack:get_name()] == nil then
unified_inventory.crafts_table[itemstack:get_name()] = {}
if options.type == "normal" and options.width == 0 then
options = { type = "shapeless", items = options.items, output = options.output, width = 0 }
end
table.insert(unified_inventory.crafts_table[itemstack:get_name()],options)
if not unified_inventory.crafts_for.recipe[itemstack:get_name()] then
unified_inventory.crafts_for.recipe[itemstack:get_name()] = {}
end
table.insert(unified_inventory.crafts_for.recipe[itemstack:get_name()],options)
end
local craft_type_defaults = {
width = 3,
height = 3,
uses_crafting_grid = false,
}
function unified_inventory.craft_type_defaults(name, options)
if not options.description then
options.description = name
end
setmetatable(options, {__index = craft_type_defaults})
return options
end
function unified_inventory.register_craft_type(name, options)
unified_inventory.registered_craft_types[name] =
unified_inventory.craft_type_defaults(name, options)
end
unified_inventory.register_craft_type("normal", {
description = F("Crafting"),
icon = "ui_craftgrid_icon.png",
width = 3,
height = 3,
get_shaped_craft_width = function (craft) return craft.width end,
dynamic_display_size = function (craft)
local w = craft.width
local h = math.ceil(table.maxn(craft.items) / craft.width)
local g = w < h and h or w
return { width = g, height = g }
end,
uses_crafting_grid = true,
})
unified_inventory.register_craft_type("shapeless", {
description = F("Mixing"),
icon = "ui_craftgrid_icon.png",
width = 3,
height = 3,
dynamic_display_size = function (craft)
local maxn = table.maxn(craft.items)
local g = 1
while g*g < maxn do g = g + 1 end
return { width = g, height = g }
end,
uses_crafting_grid = true,
})
unified_inventory.register_craft_type("cooking", {
description = F("Cooking"),
icon = "default_furnace_front.png",
width = 1,
height = 1,
})
unified_inventory.register_craft_type("digging", {
description = F("Digging"),
icon = "default_tool_steelpick.png",
width = 1,
height = 1,
})
unified_inventory.register_craft_type("digging_chance", {
description = "Digging (by chance)",
icon = "default_tool_steelpick.png^[transformFY.png",
width = 1,
height = 1,
})
function unified_inventory.register_page(name, def)
unified_inventory.pages[name] = def
end
function unified_inventory.register_button(name, def)
if not def.action then
def.action = function(player)
@ -94,9 +312,9 @@ function unified_inventory.register_button(name, def)
table.insert(unified_inventory.buttons, def)
end
function unified_inventory.is_creative(playername)
if minetest.check_player_privs(playername, {creative=true}) or
minetest.setting_getbool("creative_mode") then
return true
end
return minetest.check_player_privs(playername, {creative=true})
or minetest.setting_getbool("creative_mode")
end

245
bags.lua Normal file → Executable file
View File

@ -3,21 +3,23 @@
-- Copyright (c) 2012 cornernote, Brett O'Donnell <cornernote@gmail.com>
-- License: GPLv3
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
unified_inventory.register_page("bags", {
get_formspec = function(player)
local player_name = player:get_player_name()
local formspec = "background[0.06,0.99;7.92,7.52;ui_bags_main_form.png]"
formspec = formspec.."image[0,0;1,1;ui_bags_icon.png]"
formspec = formspec.."label[1,0;Bags]"
formspec = formspec.."button[0,2;2,0.5;bag1;Bag 1]"
formspec = formspec.."button[2,2;2,0.5;bag2;Bag 2]"
formspec = formspec.."button[4,2;2,0.5;bag3;Bag 3]"
formspec = formspec.."button[6,2;2,0.5;bag4;Bag 4]"
formspec = formspec.."label[0,0;"..F("Bags").."]"
formspec = formspec.."button[0,2;2,0.5;bag1;"..F("Bag 1").."]" .. "button[0,3;2,0.5;unequip_bag1;Unequip]"
formspec = formspec.."button[2,2;2,0.5;bag2;"..F("Bag 2").."]" .. "button[2,3;2,0.5;unequip_bag2;Unequip]"
formspec = formspec.."button[4,2;2,0.5;bag3;"..F("Bag 3").."]" .. "button[4,3;2,0.5;unequip_bag3;Unequip]"
formspec = formspec.."button[6,2;2,0.5;bag4;"..F("Bag 4").."]" .. "button[6,3;2,0.5;unequip_bag4;Unequip]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[detached:"..player_name.."_bags;bag1;0.5,1;1,1;]"
formspec = formspec.."list[detached:"..player_name.."_bags;bag2;2.5,1;1,1;]"
formspec = formspec.."list[detached:"..player_name.."_bags;bag3;4.5,1;1,1;]"
formspec = formspec.."list[detached:"..player_name.."_bags;bag4;6.5,1;1,1;]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag1;0.5,1;1,1;]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag2;2.5,1;1,1;]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag3;4.5,1;1,1;]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."_bags;bag4;6.5,1;1,1;]"
return {formspec=formspec}
end,
})
@ -25,16 +27,85 @@ unified_inventory.register_page("bags", {
unified_inventory.register_button("bags", {
type = "image",
image = "ui_bags_icon.png",
tooltip = S("Bags"),
hide_lite=true,
show_with = false, --Modif MFF (Crabman 30/06/2015)
})
for i = 1, 4 do
unified_inventory.register_page("bag"..i, {
unified_inventory.register_page("bag1", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag"..i, 1)
local stack = player:get_inventory():get_stack("bag1", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 1").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag"..i.."contents;0,1;8,3;]"
formspec = formspec.."list[current_player;bag1contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag1contents]"
formspec = formspec.."listring[current_player;main]"
local slots = stack:get_definition().groups.bagslots
if slots == 8 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_sm_form.png]"
elseif slots == 16 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_med_form.png]"
elseif slots == 24 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_lg_form.png]"
end
return {formspec=formspec}
end,
})
unified_inventory.register_page("bag2", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag2", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 2").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag2contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag2contents]"
formspec = formspec.."listring[current_player;main]"
local slots = stack:get_definition().groups.bagslots
if slots == 8 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_sm_form.png]"
elseif slots == 16 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_med_form.png]"
elseif slots == 24 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_lg_form.png]"
end
return {formspec=formspec}
end,
})
unified_inventory.register_page("bag3", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag3", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 3").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag3contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag3contents]"
formspec = formspec.."listring[current_player;main]"
local slots = stack:get_definition().groups.bagslots
if slots == 8 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_sm_form.png]"
elseif slots == 16 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_med_form.png]"
elseif slots == 24 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_lg_form.png]"
end
return {formspec=formspec}
end,
})
unified_inventory.register_page("bag4", {
get_formspec = function(player)
local stack = player:get_inventory():get_stack("bag4", 1)
local image = stack:get_definition().inventory_image
local formspec = "image[7,0;1,1;"..image.."]"
formspec = formspec.."label[0,0;"..F("Bag 4").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;bag4contents;0,1;8,3;]"
formspec = formspec.."listring[current_name;bag4contents]"
formspec = formspec.."listring[current_player;main]"
local slots = stack:get_definition().groups.bagslots
if slots == 8 then
formspec = formspec.."background[0.06,0.99;7.92,7.52;ui_bags_sm_form.png]"
@ -46,7 +117,6 @@ for i = 1, 4 do
return {formspec=formspec}
end,
})
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "" then
@ -60,6 +130,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
unified_inventory.set_inventory_formspec(player, "bag"..i)
return
elseif fields["unequip_bag" .. i] then
local stack = unified_inventory.extract_bag(player, i)
if not stack then
return
elseif stack == "overflow" then
minetest.chat_send_player(player:get_player_name(), "You bag is too heavy to be unequipped... Remove some items and retry")
return
elseif not player:get_inventory():room_for_item("main", stack) then
local pos = player:getpos()
pos.y = pos.y + 2
minetest.add_item(pos, stack)
return
end
player:get_inventory():add_item("main", stack)
end
end
end)
@ -68,12 +152,20 @@ minetest.register_on_joinplayer(function(player)
local player_inv = player:get_inventory()
local bags_inv = minetest.create_detached_inventory(player:get_player_name().."_bags",{
on_put = function(inv, listname, index, stack, player)
player:get_inventory():set_stack(listname, index, stack)
player:get_inventory():set_size(listname.."contents",
local pinv = player:get_inventory()
pinv:set_stack(listname, index, stack)
pinv:set_size(listname.."contents",
stack:get_definition().groups.bagslots)
-- Retrieve the serialized inventory if any
if stack:get_metadata() ~= "" then
for i, item in pairs(minetest.deserialize(stack:get_metadata())) do
pinv:set_stack(listname .. "contents", i, ItemStack(item))
end
end
end,
on_take = function(inv, listname, index, stack, player)
player:get_inventory():set_stack(listname, index, nil)
allow_take = function()
return 0
end,
allow_put = function(inv, listname, index, stack, player)
if stack:get_definition().groups.bagslots then
@ -82,13 +174,6 @@ minetest.register_on_joinplayer(function(player)
return 0
end
end,
allow_take = function(inv, listname, index, stack, player)
if player:get_inventory():is_empty(listname.."contents") then
return stack:get_count()
else
return 0
end
end,
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return 0
end,
@ -103,30 +188,82 @@ end)
-- register bag tools
minetest.register_tool("unified_inventory:bag_small", {
description = "Small Bag",
description = S("Small Bag"),
inventory_image = "bags_small.png",
groups = {bagslots=8},
})
minetest.register_tool("unified_inventory:bag_medium", {
description = "Medium Bag",
description = S("Medium Bag"),
inventory_image = "bags_medium.png",
groups = {bagslots=16},
})
minetest.register_tool("unified_inventory:bag_large", {
description = "Large Bag",
description = S("Large Bag"),
inventory_image = "bags_large.png",
groups = {bagslots=24},
})
local colours = {"orange", "blue", "green", "violet"}
for _, colour in pairs(colours) do
minetest.register_tool("unified_inventory:bag_small_" .. colour, {
description = S("Small Bag"),
inventory_image = "bags_small_" .. colour .. ".png",
groups = {bagslots=8},
})
minetest.register_tool("unified_inventory:bag_medium_" .. colour, {
description = S("Medium Bag"),
inventory_image = "bags_medium_" .. colour .. ".png",
groups = {bagslots=16},
})
minetest.register_tool("unified_inventory:bag_large_" .. colour, {
description = S("Large Bag"),
inventory_image = "bags_large_" .. colour .. ".png",
groups = {bagslots=24},
})
-- register bag crafts
minetest.register_craft({
output = "unified_inventory:bag_small_" .. colour,
recipe = {
{"dye:"..colour, "unified_inventory:bag_small"},
},
})
minetest.register_craft({
output = "unified_inventory:bag_medium_" .. colour,
recipe = {
{"", "", ""},
{"farming:cotton", "unified_inventory:bag_small_" .. colour, "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_small_" .. colour, "farming:cotton"},
},
})
minetest.register_craft({
output = "unified_inventory:bag_large_" .. colour,
recipe = {
{"", "", ""},
{"farming:cotton", "unified_inventory:bag_medium_" .. colour, "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_medium_" .. colour, "farming:cotton"},
},
})
end
--minetest.register_alias("unified_inventory:bag_small", "unified_inventory:bad_small_red")
--minetest.register_alias("unified_inventory:bag_medium", "unified_inventory:bad_medium_red")
--minetest.register_alias("unified_inventory:bag_large", "unified_inventory:bad_large_red")
-- register bag crafts
minetest.register_craft({
output = "unified_inventory:bag_small",
recipe = {
{"", "default:stick", ""},
{"group:wood", "group:wood", "group:wood"},
{"group:wood", "group:wood", "group:wood"},
{"", "farming:cotton", ""},
{"group:wool", "group:wool", "group:wool"},
{"group:wool", "group:wool", "group:wool"},
},
})
@ -134,8 +271,8 @@ minetest.register_craft({
output = "unified_inventory:bag_medium",
recipe = {
{"", "", ""},
{"default:stick", "unified_inventory:bag_small", "default:stick"},
{"default:stick", "unified_inventory:bag_small", "default:stick"},
{"farming:cotton", "unified_inventory:bag_small", "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_small", "farming:cotton"},
},
})
@ -143,8 +280,44 @@ minetest.register_craft({
output = "unified_inventory:bag_large",
recipe = {
{"", "", ""},
{"default:stick", "unified_inventory:bag_medium", "default:stick"},
{"default:stick", "unified_inventory:bag_medium", "default:stick"},
{"farming:cotton", "unified_inventory:bag_medium", "farming:cotton"},
{"farming:cotton", "unified_inventory:bag_medium", "farming:cotton"},
},
})
function unified_inventory.extract_bag(player, id)
if not player then
minetest.log("error", "[u_inv] Invalid player for bag extraction : nil")
return
end
if tonumber(id) == nil or id > 4 or id < 0 then
minetest.log("error", "Invalid id: " .. (id or 'nil'))
return
end
local stack = player:get_inventory():get_stack("bag"..id, 1)
if not stack:get_definition().groups.bagslots then
return
end
local pinv = player:get_inventory()
local inv = pinv:get_list("bag" .. id .. "contents")
local list = {}
for i, item in pairs(inv) do
list[i] = item:to_table()
end
if minetest.serialize(list):len() >= 4096 then
minetest.log("warning", "[U_Inv] Preventing metadata overflow with bag metadata")
return "overflow"
end
pinv:remove_item("bag" .. id, stack)
local dinv = minetest.get_inventory({type = "detached", name = minetest.formspec_escape(player:get_player_name()) .. "_bags"})
if dinv then
dinv:set_stack("bag" .. id, 1, nil)
end
pinv:set_list("bag" .. id .. "contents", {})
stack:set_metadata(minetest.serialize(list))
return stack
end

194
callbacks.lua Normal file → Executable file
View File

@ -1,31 +1,29 @@
local function default_refill(stack)
stack:set_count(stack:get_stack_max())
local itemdef = minetest.registered_items[stack:get_name()]
if itemdef
and (itemdef.wear_represents or "mechanical_wear") == "mechanical_wear"
and stack:get_wear() ~= 0 then
stack:set_wear(0)
end
return stack
end
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
unified_inventory.players[player_name] = {}
unified_inventory.current_index[player_name] = 1
unified_inventory.filtered_items_list[player_name] =
unified_inventory.items_list
unified_inventory.items_list
unified_inventory.activefilter[player_name] = ""
unified_inventory.apply_filter(player, "")
unified_inventory.active_search_direction[player_name] = "nochange"
unified_inventory.apply_filter(player, "", "nochange")
unified_inventory.current_searchbox[player_name] = ""
unified_inventory.alternate[player_name] = 1
unified_inventory.current_item[player_name] = nil
unified_inventory.current_craft_direction[player_name] = "recipe"
unified_inventory.set_inventory_formspec(player,
unified_inventory.default)
-- Crafting guide inventories
local inv = minetest.create_detached_inventory(player_name.."craftrecipe", {
allow_put = function(inv, listname, index, stack, player)
return 0
end,
allow_take = function(inv, listname, index, stack, player)
return 0
end,
allow_move = function(inv, from_list, from_index, to_list,
to_index, count, player)
return 0
end,
})
inv:set_size("output", 1)
unified_inventory.default)
-- Refill slot
local refill = minetest.create_detached_inventory(player_name.."refill", {
@ -39,7 +37,8 @@ minetest.register_on_joinplayer(function(player)
end,
on_put = function(inv, listname, index, stack, player)
local player_name = player:get_player_name()
stack:set_count(stack:get_stack_max())
local handle_refill = (minetest.registered_items[stack:get_name()] or {}).on_refill or default_refill
stack = handle_refill(stack)
inv:set_stack(listname, index, stack)
minetest.sound_play("electricity",
{to_player=player_name, gain = 1.0})
@ -49,10 +48,30 @@ minetest.register_on_joinplayer(function(player)
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
local player_name = player:get_player_name()
local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
if formname ~= "" then
return
end
local player_name = player:get_player_name()
if fields.hidebutton then --MFF crabman(29/11/2015) hide guide, textfield bug
if not unified_inventory.hidden_guide[player_name] then
unified_inventory.hidden_guide[player_name] = true
else
unified_inventory.hidden_guide[player_name] = false
end
unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
return
end
-- always take new search text, even if not searching on it yet
if fields.searchbox
and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
unified_inventory.current_searchbox[player_name] = fields.searchbox
unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
end
for i, def in pairs(unified_inventory.buttons) do
if fields[def.name] then
@ -65,40 +84,28 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
-- Inventory page controls
local start = math.floor(
unified_inventory.current_index[player_name] / 80 + 1)
unified_inventory.current_index[player_name] / ui_peruser.items_per_page + 1)
local start_i = start
local pagemax = math.floor(
(#unified_inventory.filtered_items_list[player_name] - 1)
/ (80) + 1)
/ (ui_peruser.items_per_page) + 1)
if fields.start_list then
minetest.sound_play("paperflip1",
{to_player=player_name, gain = 1.0})
start_i = 1
end
if fields.rewind1 then
minetest.sound_play("paperflip1",
{to_player=player_name, gain = 1.0})
start_i = start_i - 1
end
if fields.forward1 then
minetest.sound_play("paperflip1",
{to_player=player_name, gain = 1.0})
start_i = start_i + 1
end
if fields.rewind3 then
minetest.sound_play("paperflip1",
{to_player=player_name, gain = 1.0})
start_i = start_i - 3
end
if fields.forward3 then
minetest.sound_play("paperflip1",
{to_player=player_name, gain = 1.0})
start_i = start_i + 3
end
if fields.end_list then
minetest.sound_play("paperflip1",
{to_player=player_name, gain = 1.0})
start_i = pagemax
end
if start_i < 1 then
@ -107,78 +114,111 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if start_i > pagemax then
start_i = pagemax
end
if not (start_i == start) then
unified_inventory.current_index[player_name] = (start_i - 1) * 80 + 1
if start_i ~= start then
minetest.sound_play("paperflip1",
{to_player=player_name, gain = 1.0})
unified_inventory.current_index[player_name] = (start_i - 1) * ui_peruser.items_per_page + 1
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
end
local clicked_item = nil
local clicked_item
for name, value in pairs(fields) do
if string.sub(name, 1, 12) == "item_button_" then
clicked_item = string.sub(name, 13)
local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$")
clicked_item = unified_inventory.demangle_for_formspec(mangled_item)
if string.sub(clicked_item, 1, 6) == "group:" then
minetest.sound_play("click", {to_player=player_name, gain = 0.1})
unified_inventory.apply_filter(player, clicked_item, new_dir)
unified_inventory.current_searchbox[player_name] = clicked_item
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
return
end
if new_dir == "recipe"
or new_dir == "usage" then
unified_inventory.current_craft_direction[player_name] = new_dir
end
break
elseif string.sub(name, 1, 11) == "item_group_" then
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
unified_inventory.apply_filter(player, "group:"..string.sub(name, 12))
return
end
end
if clicked_item then
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
local page = unified_inventory.current_page[player_name]
if not unified_inventory.is_creative(player_name) then
local player_creative = unified_inventory.is_creative(player_name)
if not player_creative then
page = "craftguide"
end
if page == "craftguide" then
unified_inventory.current_item[player_name] = clicked_item
unified_inventory.alternate[player_name] = 1
unified_inventory.set_inventory_formspec(player,
"craftguide")
else
if unified_inventory.is_creative(player_name) then
local inv = player:get_inventory()
local stack = ItemStack(clicked_item)
stack:set_count(stack:get_stack_max())
if inv:room_for_item("main", stack) then
inv:add_item("main", stack)
end
unified_inventory.set_inventory_formspec(player, "craftguide")
elseif player_creative then
local inv = player:get_inventory()
local stack = ItemStack(clicked_item)
stack:set_count(stack:get_stack_max())
if inv:room_for_item("main", stack) then
inv:add_item("main", stack)
end
end
end
if fields.searchbutton then
unified_inventory.apply_filter(player, fields.searchbox)
if fields.searchbutton or fields.key_enter_field == "searchbox" then
unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange")
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
minetest.sound_play("paperflip2",
{to_player=player_name, gain = 1.0})
end
-- alternate button
if fields.alternate then
elseif fields.searchresetbutton then
unified_inventory.apply_filter(player, "", "nochange")
unified_inventory.current_searchbox[player_name] = ""
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
local item_name = unified_inventory.current_item[player_name]
if item_name then
local alternates = 0
local alternate = unified_inventory.alternate[player_name]
local crafts = unified_inventory.crafts_table[item_name]
if crafts ~= nil then
alternates = #crafts
end
if alternates > 1 then
alternate = alternate + 1
if alternate > alternates then
alternate = 1
end
unified_inventory.alternate[player_name] = alternate
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
end
end
-- alternate buttons
if not (fields.alternate or fields.alternate_prev) then
return
end
minetest.sound_play("click",
{to_player=player_name, gain = 0.1})
local item_name = unified_inventory.current_item[player_name]
if not item_name then
return
end
local crafts = unified_inventory.crafts_for[unified_inventory.current_craft_direction[player_name]][item_name]
if not crafts then
return
end
local alternates = #crafts
if alternates <= 1 then
return
end
local alternate
if fields.alternate then
alternate = unified_inventory.alternate[player_name] + 1
if alternate > alternates then
alternate = 1
end
elseif fields.alternate_prev then
alternate = unified_inventory.alternate[player_name] - 1
if alternate < 1 then
alternate = alternates
end
end
unified_inventory.alternate[player_name] = alternate
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
end)
if minetest.delete_detached_inventory then
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
minetest.delete_detached_inventory(player_name.."_bags")
minetest.delete_detached_inventory(player_name.."craftrecipe")
minetest.delete_detached_inventory(player_name.."refill")
end)
end

View File

@ -1,83 +0,0 @@
datastorage={}
datastorage["!registered_players"]={}
datastorage.save_data = function(table_pointer)
local data = minetest.serialize( datastorage[table_pointer] )
local path = minetest.get_worldpath().."/datastorage_"..table_pointer..".data"
local file = io.open( path, "w" )
if( file ) then
file:write( data )
file:close()
return true
else return nil
end
end
datastorage.load_data = function(table_pointer)
local path = minetest.get_worldpath().."/datastorage_"..table_pointer..".data"
local file = io.open( path, "r" )
if( file ) then
local data = file:read("*all")
datastorage[table_pointer] = minetest.deserialize( data )
file:close()
return true
else return nil
end
end
datastorage.get_container = function (player, key)
local player_name = player:get_player_name()
local container = datastorage[player_name]
if container[key] == nil then
container[key] = {}
end
datastorage.save_data(player_name)
return container[key]
end
-- forced save of all player's data
datastorage.save_container = function (player)
local player_name = player:get_player_name()
datastorage.save_data(player_name)
end
-- Init
if datastorage.load_data("!registered_players") == nil then
datastorage["!registered_players"]={}
datastorage.save_data("!registered_players")
end
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
local registered = nil
for __,tab in ipairs(datastorage["!registered_players"]) do
if tab["player_name"] == player_name then registered = true break end
end
if registered == nil then
local new={}
new["player_name"]=player_name
table.insert(datastorage["!registered_players"],new)
datastorage[player_name]={}
datastorage.save_data("!registered_players")
datastorage.save_data(player_name)
else
datastorage.load_data(player_name)
end
end
)
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
datastorage.save_data(player_name)
datastorage[player_name] = nil
end
)
minetest.register_on_shutdown(function()
for __,tab in ipairs(datastorage["!registered_players"]) do
if datastorage[tab["player_name"]] == nil then break end
datastorage.save_data(tab["player_name"])
end
end
)

4
depends.txt Normal file → Executable file
View File

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

1
description.txt Normal file
View File

@ -0,0 +1 @@
Unified Inventory replaces the default survival and creative inventory. It adds a nicer interface and a number of features, such as a crafting guide.

138
group.lua Executable file
View File

@ -0,0 +1,138 @@
local S = unified_inventory.gettext
function unified_inventory.canonical_item_spec_matcher(spec)
local specname = ItemStack(spec):get_name()
if specname:sub(1, 6) == "group:" then
local group_names = specname:sub(7):split(",")
return function (itemname)
local itemdef = minetest.registered_items[itemname]
for _, group_name in ipairs(group_names) do
if (itemdef.groups[group_name] or 0) == 0 then
return false
end
end
return true
end
else
return function (itemname) return itemname == specname end
end
end
function unified_inventory.item_matches_spec(item, spec)
local itemname = ItemStack(item):get_name()
return unified_inventory.canonical_item_spec_matcher(spec)(itemname)
end
function unified_inventory.extract_groupnames(groupname)
local specname = ItemStack(groupname):get_name()
if specname:sub(1, 6) == "group:" then
local group_names = specname:sub(7):split(",")
if #group_names == 1 then
return group_names[1], 1
end
local s = ""
for g=1,#group_names do
if g > 1 then
-- List connector
s = s .. S(" and ")
end
s = s .. group_names[g]
end
return s, #group_names
else
return nil, 0
end
end
unified_inventory.registered_group_items = {
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
stone = "default:cobble",
wood = "default:wood",
book = "default:book",
sand = "default:sand",
leaves = "default:leaves",
tree = "default:tree",
vessel = "vessels:glass_bottle",
wool = "wool:white",
ingot = "default:steel_ingot",
}
function unified_inventory.register_group_item(groupname, itemname)
unified_inventory.registered_group_items[groupname] = itemname
end
-- This is used when displaying craft recipes, where an ingredient is
-- specified by group rather than as a specific item. A single-item group
-- is represented by that item, with the single-item status signalled
-- in the "sole" field. If the group contains no items at all, the item
-- field will be nil.
--
-- Within a multiple-item group, we prefer to use an item that has the
-- same specific name as the group, and if there are more than one of
-- those items we prefer the one registered for the group by a mod.
-- Among equally-preferred items, we just pick the one with the
-- lexicographically earliest name.
--
-- The parameter to this function isn't just a single group name.
-- It may be a comma-separated list of group names. This is really a
-- "group:..." ingredient specification, minus the "group:" prefix.
local function compute_group_item(group_name_list)
local group_names = group_name_list:split(",")
local candidate_items = {}
for itemname, itemdef in pairs(minetest.registered_items) do
if (itemdef.groups.not_in_creative_inventory or 0) == 0 then
local all = true
for _, group_name in ipairs(group_names) do
if (itemdef.groups[group_name] or 0) == 0 then
all = false
end
end
if all then table.insert(candidate_items, itemname) end
end
end
local num_candidates = #candidate_items
if num_candidates == 0 then
return {sole = true}
elseif num_candidates == 1 then
return {item = candidate_items[1], sole = true}
end
local is_group = {}
local registered_rep = {}
for _, group_name in ipairs(group_names) do
is_group[group_name] = true
local rep = unified_inventory.registered_group_items[group_name]
if rep then registered_rep[rep] = true end
end
local bestitem = ""
local bestpref = 0
for _, item in ipairs(candidate_items) do
local pref
if registered_rep[item] then
pref = 4
elseif string.sub(item, 1, 8) == "default:" and is_group[string.sub(item, 9)] then
pref = 3
elseif is_group[item:gsub("^[^:]*:", "")] then
pref = 2
else
pref = 1
end
if pref > bestpref or (pref == bestpref and item < bestitem) then
bestitem = item
bestpref = pref
end
end
return {item = bestitem, sole = false}
end
local group_item_cache = {}
function unified_inventory.get_group_item(group_name)
if not group_item_cache[group_name] then
group_item_cache[group_name] = compute_group_item(group_name)
end
return group_item_cache[group_name]
end

66
image_credits.txt Executable file
View File

@ -0,0 +1,66 @@
bags_small.png:
http://www.clker.com/clipart-moneybag-empty.html
bags_medium.png:
http://www.clker.com/clipart-backpack-1.html
bags_large.png / ui_bags_icon.png:
http://www.clker.com/clipart-backpack-green-brown.html
ui_craftguide_icon.png / ui_craft_icon.png
http://commons.wikimedia.org/wiki/File:Advancedsettings.png
ui_doubleleft_icon.png
http://commons.wikimedia.org/wiki/File:Media-seek-backward.svg
ui_doubleright_icon.png
http://commons.wikimedia.org/wiki/File:Media-seek-forward.svg
ui_left_icon.png / ui_right_icon.png
http://commons.wikimedia.org/wiki/File:Media-playback-start.svg
ui_skip_backward_icon.png
http://commons.wikimedia.org/wiki/File:Media-skip-backward.svg
ui_skip_forward_icon.png
http://commons.wikimedia.org/wiki/File:Media-skip-forward.svg
ui_gohome_icon.png / ui_home_icon.png / ui_sethome_icon.png
http://commons.wikimedia.org/wiki/File:Home_256x256.png
ui_moon_icon.png
http://commons.wikimedia.org/wiki/File:FullMoon2010.jpg
ui_sun_icon.png
http://commons.wikimedia.org/wiki/File:2012-10-13_15-29-35-sun.jpg
ui_trash_icon.png
http://www.clker.com/clipart-29090.html
http://www.clker.com/clipart-trash.html
ui_search_icon.png
http://www.clker.com/clipart-24887.html
ui_off_icon.png / ui_on_icon.png
http://www.clker.com/clipart-on-off-switches.html
ui_waypoints_icon.png
http://www.clker.com/clipart-map-pin-red.html
ui_circular_arrows_icon.png
http://www.clker.com/clipart-circular-arrow-pattern.html
ui_pencil_icon.pnc
http://www.clker.com/clipart-2256.html
ui_waypoint_set_icon.png
http://www.clker.com/clipart-larger-flag.html
ui_xyz_off_icon.png
http://commons.wikimedia.org/wiki/File:No_sign.svg
ui_ok_icon.png
http://commons.wikimedia.org/wiki/File:Yes_check.svg
inventory_plus_worldedit_gui.png
http://commons.wikimedia.org/wiki/File:Erioll_world_2.svg

79
init.lua Normal file → Executable file
View File

@ -2,43 +2,72 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
local worldpath = minetest.get_worldpath()
local mygettext = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
-- Data tables definitions
unified_inventory = {}
unified_inventory.activefilter = {}
unified_inventory.alternate = {}
unified_inventory.current_page = {}
unified_inventory.current_index = {}
unified_inventory.current_item = {}
unified_inventory.crafts_table = {}
unified_inventory.crafts_table_count = 0
unified_inventory.players = {}
unified_inventory.items_list_size = 0
unified_inventory.items_list = {}
unified_inventory.filtered_items_list_size = {}
unified_inventory.filtered_items_list = {}
unified_inventory.pages = {}
unified_inventory.buttons = {}
unified_inventory = {
activefilter = {},
active_search_direction = {},
alternate = {},
current_page = {},
current_searchbox = {},
current_index = {},
current_item = {},
current_craft_direction = {},
registered_craft_types = {},
crafts_for = {usage = {}, recipe = {} },
players = {},
items_list_size = 0,
items_list = {},
filtered_items_list_size = {},
filtered_items_list = {},
pages = {},
buttons = {},
hidden_guide = {}, --MFF crabman(29/11/2015) hide guide, textfield bug
-- Homepos stuff
unified_inventory.home_pos = {}
unified_inventory.home_filename =
worldpath.."/unified_inventory_home.home"
-- Homepos stuff
home_pos = {},
home_filename = worldpath.."/unified_inventory_home.home",
-- Default inventory page
unified_inventory.default = "craft"
-- Default inventory page
default = "craft",
-- intllib
gettext = mygettext,
fgettext = function(s) return minetest.formspec_escape(mygettext(s)) end,
-- "Lite" mode
lite_mode = minetest.setting_getbool("unified_inventory_lite"),
pagecols = 8,
pagerows = 10,
page_y = 0,
formspec_y = 1,
main_button_x = 0,
main_button_y = 9,
craft_result_x = 0.3,
craft_result_y = 0.5,
form_header_y = 0
}
-- Disable default creative inventory
if creative_inventory then
function creative_inventory.set_creative_formspec(player, start_i, pagenum)
local creative = rawget(_G, "creative") or rawget(_G, "creative_inventory")
if creative then
function creative.set_creative_formspec(player, start_i, pagenum)
return
end
end
dofile(modpath.."/datastorage.lua")
dofile(modpath.."/group.lua")
dofile(modpath.."/api.lua")
dofile(modpath.."/internal.lua")
dofile(modpath.."/callbacks.lua")
dofile(modpath.."/register.lua")
dofile(modpath.."/bags.lua")
dofile(modpath.."/waypoints.lua")
dofile(modpath.."/item_names.lua")
if minetest.get_modpath("datastorage") then
dofile(modpath.."/waypoints.lua")
end

387
internal.lua Normal file → Executable file
View File

@ -1,139 +1,321 @@
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
-- This pair of encoding functions is used where variable text must go in
-- button names, where the text might contain formspec metacharacters.
-- We can escape button names for the formspec, to avoid screwing up
-- form structure overall, but they then don't get de-escaped, and so
-- the input we get back from the button contains the formspec escaping.
-- This is a game engine bug, and in the anticipation that it might be
-- fixed some day we don't want to rely on it. So for safety we apply
-- an encoding that avoids all formspec metacharacters.
function unified_inventory.mangle_for_formspec(str)
return string.gsub(str, "([^A-Za-z0-9])", function (c) return string.format("_%d_", string.byte(c)) end)
end
function unified_inventory.demangle_for_formspec(str)
return string.gsub(str, "_([0-9]+)_", function (v) return string.char(v) end)
end
function unified_inventory.get_per_player_formspec(player_name)
local lite = unified_inventory.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true})
local ui = {}
ui.pagecols = unified_inventory.pagecols
ui.pagerows = unified_inventory.pagerows
ui.page_y = unified_inventory.page_y
ui.formspec_y = unified_inventory.formspec_y
ui.main_button_x = unified_inventory.main_button_x
ui.main_button_y = unified_inventory.main_button_y
ui.craft_result_x = unified_inventory.craft_result_x
ui.craft_result_y = unified_inventory.craft_result_y
ui.form_header_y = unified_inventory.form_header_y
if lite then
ui.pagecols = 4
ui.pagerows = 6
ui.page_y = 0.25
ui.formspec_y = 0.47
ui.main_button_x = 8.2
ui.main_button_y = 6.5
ui.craft_result_x = 2.8
ui.craft_result_y = 3.4
ui.form_header_y = -0.1
end
ui.items_per_page = ui.pagecols * ui.pagerows
return ui, lite
end
function unified_inventory.get_formspec(player, page)
if not player then
return ""
end
local player_name = player:get_player_name()
local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
unified_inventory.current_page[player_name] = page
local pagedef = unified_inventory.pages[page]
local formspec = "size[14,10]"
local fsdata = nil
local formspec = {
"size[14,10]",
"background[-0.19,-0.25;14.4,10.75;ui_form_bg.png]" -- Background
}
local n = 3
if draw_lite_mode then
formspec[1] = "size[11,7.7]"
formspec[2] = "background[-0.19,-0.2;11.4,8.4;ui_form_bg.png]"
end
if unified_inventory.is_creative(player_name)
and page == "craft" then
formspec[n] = "background[0,"..(ui_peruser.formspec_y + 2)..";1,1;ui_single_slot.png]"
n = n+1
end
-- Background
formspec = formspec .. "background[-0.19,-0.25;14.4,10.75;ui_form_bg.png]"
-- Current page
if unified_inventory.pages[page] then
fsdata = pagedef.get_formspec(player)
formspec = formspec .. fsdata.formspec
else
if not unified_inventory.pages[page] then
return "" -- Invalid page name
end
local perplayer_formspec = unified_inventory.get_per_player_formspec(player_name)
local fsdata = pagedef.get_formspec(player, perplayer_formspec)
formspec[n] = fsdata.formspec
n = n+1
local privs = minetest.get_player_privs(player_name) --Modif MFF (Crabman 13/10/2015) not show if player has not privs requiered
local button_row = 0
local button_col = 0
-- Main buttons
local filtered_inv_buttons = {}
for i, def in pairs(unified_inventory.buttons) do
if def.type == "image" then
formspec = formspec.."image_button["
..(0.65 * (i - 1))..",9;0.8,0.8;"
..minetest.formspec_escape(def.image)..";"
..minetest.formspec_escape(def.name)..";]"
if not (draw_lite_mode and def.hide_lite) and (not def.show_with or (privs[def.show_with] and privs[def.show_with] == true)) then --Modif MFF (Crabman 13/10/2015) not show if player has not privs requiered
table.insert(filtered_inv_buttons, def)
end
end
local i = 1 --Modif MFF (Crabman 13/10/2015) 12 buttons max by row
for _, def in pairs(filtered_inv_buttons) do --Modif MFF (Crabman 13/10/2015)
if draw_lite_mode and i > 4 then
button_row = 1
button_col = 1
elseif not draw_lite_mode and i > 12 then --Modif MFF (Crabman 13/10/2015)
button_row = 1
i = 1
end
if def.type == "image" then
formspec[n] = "image_button["
formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4)
formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;"
formspec[n+3] = minetest.formspec_escape(def.image)..";"
formspec[n+4] = minetest.formspec_escape(def.name)..";]"
formspec[n+5] = "tooltip["..minetest.formspec_escape(def.name)
formspec[n+6] = ";"..(def.tooltip or "").."]"
n = n+7
end
i = i + 1 --Modif MFF (Crabman 13/10/2015)
end
if fsdata.draw_inventory ~= false then
-- Player inventory
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec .. "list[current_player;main;0,4.5;8,4;]"
formspec[n] = "listcolors[#00000000;#00000000]"
formspec[n+1] = "list[current_player;main;0,"..(ui_peruser.formspec_y + 3.5)..";8,4;]"
n = n+2
end
if fsdata.draw_item_list == false then
return formspec
return table.concat(formspec, "")
end
if not unified_inventory.hidden_guide[player_name] then --MFF crabman(29/11/2015) hide guide, textfield bug
formspec[n] = "image_button[13.2,0.1;.8,.8;ui_on_icon.png;hidebutton;]"
.. "tooltip[hidebutton;" ..F("Hide guide") .. "]"
n = n+1
else
formspec[n] = "image_button[13.2,0.1;.8,.8;ui_off_icon.png;hidebutton;]"
.. "tooltip[hidebutton;" ..F("Show guide") .. "]"
return table.concat(formspec, "")
end
-- Controls to flip items pages
local start_x = 9.2
formspec = formspec .. "image_button["..(start_x + 0.6 * 0)..",9;.8,.8;ui_skip_backward_icon.png;start_list;]"
formspec = formspec .. "image_button["..(start_x + 0.6 * 1)..",9;.8,.8;ui_doubleleft_icon.png;rewind3;]"
formspec = formspec .. "image_button["..(start_x + 0.6 * 2)..",9;.8,.8;ui_left_icon.png;rewind1;]"
formspec = formspec .. "image_button["..(start_x + 0.6 * 3)..",9;.8,.8;ui_right_icon.png;forward1;]"
formspec = formspec .. "image_button["..(start_x + 0.6 * 4)..",9;.8,.8;ui_doubleright_icon.png;forward3;]"
formspec = formspec .. "image_button["..(start_x + 0.6 * 5)..",9;.8,.8;ui_skip_forward_icon.png;end_list;]"
if not draw_lite_mode then
formspec[n] =
"image_button[" .. (start_x + 0.6 * 0)
.. ",9;.8,.8;ui_skip_backward_icon.png;start_list;]"
.. "tooltip[start_list;" .. F("First page") .. "]"
.. "image_button[" .. (start_x + 0.6 * 1)
.. ",9;.8,.8;ui_doubleleft_icon.png;rewind3;]"
.. "tooltip[rewind3;" .. F("Back three pages") .. "]"
.. "image_button[" .. (start_x + 0.6 * 2)
.. ",9;.8,.8;ui_left_icon.png;rewind1;]"
.. "tooltip[rewind1;" .. F("Back one page") .. "]"
.. "image_button[" .. (start_x + 0.6 * 3)
.. ",9;.8,.8;ui_right_icon.png;forward1;]"
.. "tooltip[forward1;" .. F("Forward one page") .. "]"
.. "image_button[" .. (start_x + 0.6 * 4)
.. ",9;.8,.8;ui_doubleright_icon.png;forward3;]"
.. "tooltip[forward3;" .. F("Forward three pages") .. "]"
.. "image_button[" .. (start_x + 0.6 * 5)
.. ",9;.8,.8;ui_skip_forward_icon.png;end_list;]"
.. "tooltip[end_list;" .. F("Last page") .. "]"
else
formspec[n] =
"image_button[" .. (8.2 + 0.65 * 0)
.. ",5.8;.8,.8;ui_skip_backward_icon.png;start_list;]"
.. "tooltip[start_list;" .. F("First page") .. "]"
.. "image_button[" .. (8.2 + 0.65 * 1)
.. ",5.8;.8,.8;ui_left_icon.png;rewind1;]"
.. "tooltip[rewind1;" .. F("Back one page") .. "]"
.. "image_button[" .. (8.2 + 0.65 * 2)
.. ",5.8;.8,.8;ui_right_icon.png;forward1;]"
.. "tooltip[forward1;" .. F("Forward one page") .. "]"
.. "image_button[" .. (8.2 + 0.65 * 3)
.. ",5.8;.8,.8;ui_skip_forward_icon.png;end_list;]"
.. "tooltip[end_list;" .. F("Last page") .. "]"
end
n = n+1
-- Search box
formspec = formspec .. "field[9.5,8.325;3,1;searchbox;;]"
formspec = formspec .. "image_button[12.2,8.1;.8,.8;ui_search_icon.png;searchbutton;]"
formspec[n] = "field_close_on_enter[searchbox;false]"
n = n+1
if not draw_lite_mode then
formspec[n] = "field[9.5,8.325;3,1;searchbox;;"
.. minetest.formspec_escape(unified_inventory.current_searchbox[player_name]) .. "]"
formspec[n+1] = "image_button[12.2,8.1;.8,.8;ui_search_icon.png;searchbutton;]"
.. "tooltip[searchbutton;" ..F("Search") .. "]"
formspec[n+2] = "image_button[12.9,8.1;.8,.8;ui_reset_icon.png;searchresetbutton;]"
.. "tooltip[searchbutton;" ..F("Search") .. "]"
.. "tooltip[searchresetbutton;" ..F("Reset search and display everything") .. "]"
else
formspec[n] = "field[8.5,5.225;2.2,1;searchbox;;"
.. minetest.formspec_escape(unified_inventory.current_searchbox[player_name]) .. "]"
formspec[n+1] = "image_button[10.3,5;.8,.8;ui_search_icon.png;searchbutton;]"
.. "tooltip[searchbutton;" ..F("Search") .. "]"
formspec[n+2] = "image_button[11,5;.8,.8;ui_reset_icon.png;searchresetbutton;]"
.. "tooltip[searchbutton;" ..F("Search") .. "]"
.. "tooltip[searchresetbutton;" ..F("Reset search and display everything") .. "]"
end
n = n+3
local no_matches = "No matching items"
if draw_lite_mode then
no_matches = "No matches."
end
-- Items list
local list_index = unified_inventory.current_index[player_name]
local page = math.floor(list_index / (80) + 1)
local pagemax = math.floor(
(#unified_inventory.filtered_items_list[player_name] - 1)
/ (80) + 1)
local item = {}
for y = 0, 9 do
for x = 0, 7 do
local name = unified_inventory.filtered_items_list[player_name][list_index]
if minetest.registered_items[name] then
formspec = formspec.."item_image_button["
..(8.2 + x * 0.7)..","
..(1 + y * 0.7)..";.81,.81;"
..name..";item_button_"
..name..";]"
list_index = list_index + 1
if #unified_inventory.filtered_items_list[player_name] == 0 then
formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";" .. F(no_matches) .. "]"
else
local dir = unified_inventory.active_search_direction[player_name]
local list_index = unified_inventory.current_index[player_name]
local page = math.floor(list_index / (ui_peruser.items_per_page) + 1)
local pagemax = math.floor(
(#unified_inventory.filtered_items_list[player_name] - 1)
/ (ui_peruser.items_per_page) + 1)
local item = {}
for y = 0, ui_peruser.pagerows - 1 do
for x = 0, ui_peruser.pagecols - 1 do
local name = unified_inventory.filtered_items_list[player_name][list_index]
if minetest.registered_items[name] then
-- Clicked on current item: Flip crafting direction
if name == unified_inventory.current_item[player_name] then
local cdir = unified_inventory.current_craft_direction[player_name]
if cdir == "recipe" then
dir = "usage"
elseif cdir == "usage" then
dir = "recipe"
end
else
-- Default: use active search direction by default
dir = unified_inventory.active_search_direction[player_name]
end
formspec[n] = "item_image_button["
..(8.2 + x * 0.7)..","
..(ui_peruser.formspec_y + ui_peruser.page_y + y * 0.7)..";.81,.81;"
..name..";item_button_"..dir.."_"
..unified_inventory.mangle_for_formspec(name)..";]"
n = n+1
list_index = list_index + 1
end
end
end
formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";"..F("Page") .. ": "
.. S("%s of %s"):format(page,pagemax).."]"
end
n= n+1
if unified_inventory.activefilter[player_name] ~= "" then
formspec[n] = "label[8.2,"..(ui_peruser.form_header_y + 0.4)..";" .. F("Filter") .. ":]"
formspec[n+1] = "label[9.1,"..(ui_peruser.form_header_y + 0.4)..";"..minetest.formspec_escape(unified_inventory.activefilter[player_name]).."]"
end
formspec = formspec.."label[8.2,0;Page:]"
formspec = formspec.."label[9,0;"..page.." of "..pagemax.."]"
formspec = formspec.."label[8.2,0.4;Filter:]"
formspec = formspec.."label[9,0.4;"..unified_inventory.activefilter[player_name].."]"
return formspec
return table.concat(formspec, "")
end
function unified_inventory.set_inventory_formspec(player, page)
if player then
local formspec = unified_inventory.get_formspec(player, page)
player:set_inventory_formspec(formspec)
player:set_inventory_formspec(unified_inventory.get_formspec(player, page))
end
end
--apply filter to the inventory list (create filtered copy of full one)
function unified_inventory.apply_filter(player, filter)
local player_name = player:get_player_name()
local size = 0
local lfilter = string.lower(filter)
if not pcall(function() ("technic:test"):find(lfilter) end) then
-- Filter is invalid
lfilter = ""
function unified_inventory.apply_filter(player, filter, search_dir)
if not player then
return false
end
unified_inventory.filtered_items_list[player_name]={}
local player_name = player:get_player_name()
local lfilter = string.lower(filter)
local ffilter
if lfilter:sub(1, 6) == "group:" then
local groups = lfilter:sub(7):split(",")
for name, def in pairs(minetest.registered_items) do
if def.groups then
local all = true
for _, group in ipairs(groups) do
if not (def.groups[group] and (def.groups[group] > 0)) then
all = false
break
end
end
if all then
table.insert(unified_inventory.filtered_items_list[player_name], name)
size = size + 1
ffilter = function(name, def)
for _, group in ipairs(groups) do
if not def.groups[group]
or def.groups[group] <= 0 then
return false
end
end
return true
end
else
for name, def in pairs(minetest.registered_items) do
if (not def.groups.not_in_creative_inventory or
def.groups.not_in_creative_inventory == 0)
and def.description and def.description ~= "" then
local lname = string.lower(name)
local ldesc = string.lower(def.description)
if string.find(lname, lfilter) or string.find(ldesc, lfilter) then
table.insert(unified_inventory.filtered_items_list[player_name], name)
size = size + 1
end
end
ffilter = function(name, def)
local lname = string.lower(name)
local ldesc = string.lower(def.description)
return string.find(lname, lfilter, 1, true) or string.find(ldesc, lfilter, 1, true)
end
end
unified_inventory.filtered_items_list[player_name]={}
for name, def in pairs(minetest.registered_items) do
if (not def.groups.not_in_creative_inventory
or def.groups.not_in_creative_inventory == 0)
and def.description
and def.description ~= ""
and ffilter(name, def)
and (unified_inventory.is_creative(player_name)
or unified_inventory.crafts_for.recipe[def.name]) then
table.insert(unified_inventory.filtered_items_list[player_name], name)
end
end
table.sort(unified_inventory.filtered_items_list[player_name])
unified_inventory.filtered_items_list_size[player_name] = size
unified_inventory.filtered_items_list_size[player_name] = #unified_inventory.filtered_items_list[player_name]
unified_inventory.current_index[player_name] = 1
unified_inventory.activefilter[player_name] = filter
unified_inventory.active_search_direction[player_name] = search_dir
unified_inventory.set_inventory_formspec(player,
unified_inventory.current_page[player_name])
unified_inventory.current_page[player_name])
end
function unified_inventory.items_in_group(groups)
@ -147,3 +329,48 @@ function unified_inventory.items_in_group(groups)
end
return items
end
function unified_inventory.sort_inventory(inv)
local inlist = inv:get_list("main")
local typecnt = {}
local typekeys = {}
for _, st in ipairs(inlist) do
if not st:is_empty() then
local n = st:get_name()
local w = st:get_wear()
local m = st:get_metadata()
local k = string.format("%s %05d %s", n, w, m)
if not typecnt[k] then
typecnt[k] = {
name = n,
wear = w,
metadata = m,
stack_max = st:get_stack_max(),
count = 0,
}
table.insert(typekeys, k)
end
typecnt[k].count = typecnt[k].count + st:get_count()
end
end
table.sort(typekeys)
local outlist = {}
for _, k in ipairs(typekeys) do
local tc = typecnt[k]
while tc.count > 0 do
local c = math.min(tc.count, tc.stack_max)
table.insert(outlist, ItemStack({
name = tc.name,
wear = tc.wear,
metadata = tc.metadata,
count = c,
}))
tc.count = tc.count - c
end
end
if #outlist > #inlist then return end
while #outlist < #inlist do
table.insert(outlist, ItemStack(nil))
end
inv:set_list("main", outlist)
end

56
item_names.lua Executable file
View File

@ -0,0 +1,56 @@
-- Based on 4itemnames mod by 4aiman
local wield = {}
local huds = {}
local dtimes = {}
local dlimit = 3 -- HUD element will be hidden after this many seconds
local air_hud_mod = minetest.get_modpath("4air")
local hud_mod = minetest.get_modpath("hud")
local hudbars_mod = minetest.get_modpath("hudbars")
local function set_hud(player)
local player_name = player:get_player_name()
local off = {x=0, y=-70}
if air_hud_mod or hud_mod then
off.y = off.y - 20
elseif hudbars_mod then
off.y = off.y + 5
end
huds[player_name] = player:hud_add({
hud_elem_type = "text",
position = {x=0.5, y=1},
offset = off,
alignment = {x=0, y=0},
number = 0xFFFFFF ,
text = "",
})
end
minetest.register_on_joinplayer(function(player)
minetest.after(0, set_hud, player)
end)
minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do
local player_name = player:get_player_name()
local wstack = player:get_wielded_item():get_name()
if dtimes[player_name] and dtimes[player_name] < dlimit then
dtimes[player_name] = dtimes[player_name] + dtime
if dtimes[player_name] > dlimit and huds[player_name] then
player:hud_change(huds[player_name], 'text', "")
end
end
if wstack ~= wield[player_name] then
wield[player_name] = wstack
dtimes[player_name] = 0
if huds[player_name] then
local def = minetest.registered_items[wstack]
local desc = def and def.description or ""
player:hud_change(huds[player_name], 'text', desc)
end
end
end
end)

101
locale/de.txt Executable file
View File

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

72
locale/es.txt Executable file
View File

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

72
locale/fr.txt Executable file
View File

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

71
locale/pl.txt Executable file
View File

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

76
locale/ru.txt Executable file
View File

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

107
locale/template.txt Executable file
View File

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

72
locale/tr.txt Executable file
View File

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

1
mod.conf Normal file
View File

@ -0,0 +1 @@
name = unified_inventory

526
register.lua Normal file → Executable file
View File

@ -1,9 +1,17 @@
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
minetest.register_privilege("creative", {
description = "Can use the creative inventory",
description = S("Can use the creative inventory"),
give_to_singleplayer = false,
})
minetest.register_privilege("ui_full", {
description = S("Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally"),
give_to_singleplayer = false,
})
local trash = minetest.create_detached_inventory("trash", {
--allow_put = function(inv, listname, index, stack, player)
-- if unified_inventory.is_creative(player:get_player_name()) then
@ -23,43 +31,76 @@ trash:set_size("main", 1)
unified_inventory.register_button("craft", {
type = "image",
image = "ui_craft_icon.png",
tooltip = S("Crafting Grid"),
show_with = false, --Modif MFF (Crabman 30/06/2015)
})
unified_inventory.register_button("craftguide", {
type = "image",
image = "ui_craftguide_icon.png",
tooltip = S("Crafting Guide"),
show_with = false, --Modif MFF (Crabman 30/06/2015)
})
--[[
unified_inventory.register_button("home_gui_set", {
type = "image",
image = "ui_sethome_icon.png",
tooltip = S("Set home position"),
hide_lite=true,
show_with = "interact", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
unified_inventory.set_home(player, player:getpos())
local home = unified_inventory.home_pos[player_name]
if home ~= nil then
minetest.sound_play("dingdong",
{to_player=player_name, gain = 1.0})
minetest.chat_send_player(player_name,
"Home position set to: "
..minetest.pos_to_string(home))
end
end,
if home.sethome(player:get_player_name()) == true then --modif MFF
minetest.sound_play("dingdong",
{to_player=player:get_player_name(), gain = 1.0})
end
end,
})
unified_inventory.register_button("home_gui_go", {
type = "image",
image = "ui_gohome_icon.png",
tooltip = S("Go home"),
hide_lite=true,
show_with = "interact", --Modif MFF (Crabman 30/06/2015)
action = function(player)
minetest.sound_play("teleport",
if home.tohome(player:get_player_name()) == true then --modif MFF
minetest.sound_play("teleport",
{to_player=player:get_player_name(), gain = 1.0})
unified_inventory.go_home(player)
end
end,
})
--]]
if minetest.get_modpath("news") then
unified_inventory.register_button("news", {
type = "image",
image = "ui_news_icon.png",
tooltip = S("News"),
hide_lite = true,
show_with = "interact",
action = function(player)
core.chatcommands["news"].func(player:get_player_name())
end,
})
end
unified_inventory.register_button("home_gui_set", { --new h2omes
type = "image",
image = "ui_gohome_icon.png",
tooltip = S("My Homes"),
hide_lite=true,
show_with = "home", --Modif MFF (Crabman 30/06/2015)
action = function(player)
h2omes.show_formspec_home(player:get_player_name())
end,
})
unified_inventory.register_button("misc_set_day", {
type = "image",
image = "ui_sun_icon.png",
tooltip = S("Set time to day"),
hide_lite=true,
show_with = "settime", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {settime=true}) then
@ -67,11 +108,10 @@ unified_inventory.register_button("misc_set_day", {
{to_player=player_name, gain = 1.0})
minetest.set_timeofday((6000 % 24000) / 24000)
minetest.chat_send_player(player_name,
"Time of day set to 6am")
S("Time of day set to 6am"))
else
minetest.chat_send_player(player_name,
"You don't have the"
.." settime priviledge!")
S("You don't have the settime privilege!"))
end
end,
})
@ -79,6 +119,9 @@ unified_inventory.register_button("misc_set_day", {
unified_inventory.register_button("misc_set_night", {
type = "image",
image = "ui_moon_icon.png",
tooltip = S("Set time to night"),
hide_lite=true,
show_with = "settime", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, {settime=true}) then
@ -86,11 +129,10 @@ unified_inventory.register_button("misc_set_night", {
{to_player=player_name, gain = 1.0})
minetest.set_timeofday((21000 % 24000) / 24000)
minetest.chat_send_player(player_name,
"Time of day set to 9pm")
S("Time of day set to 9pm"))
else
minetest.chat_send_player(player_name,
"You don't have the"
.." settime priviledge!")
S("You don't have the settime privilege!"))
end
end,
})
@ -98,142 +140,351 @@ unified_inventory.register_button("misc_set_night", {
unified_inventory.register_button("clear_inv", {
type = "image",
image = "ui_trash_icon.png",
tooltip = S("Clear inventory"),
show_with = "creative", --Modif MFF (Crabman 30/06/2015)
action = function(player)
local player_name = player:get_player_name()
if not unified_inventory.is_creative(player_name) then
minetest.chat_send_player(player_name,
"This button has been disabled outside"
S("This button has been disabled outside"
.." of creative mode to prevent"
.." accidental inventory trashing."
.." Use the trash slot instead.")
.."\nUse the trash slot instead."))
return
end
player:get_inventory():set_list("main", {})
minetest.chat_send_player(player_name, 'Inventory Cleared!')
minetest.chat_send_player(player_name, S('Inventory cleared!'))
minetest.sound_play("trash_all",
{to_player=player_name, gain = 1.0})
end,
})
unified_inventory.register_page("craft", {
get_formspec = function(player, formspec)
get_formspec = function(player, perplayer_formspec)
local formspecy = perplayer_formspec.formspec_y
local formheadery = perplayer_formspec.form_header_y
local player_name = player:get_player_name()
local formspec = "background[0,1;8,3;ui_crafting_form.png]"
formspec = formspec.."background[0,4.5;8,4;ui_main_inventory.png]"
formspec = formspec.."image[0,0;1,1;ui_craft_icon.png]"
formspec = formspec.."label[1,0;Crafting]"
local formspec = "background[2,"..formspecy..";6,3;ui_crafting_form.png]"
formspec = formspec.."background[0,"..(formspecy + 3.5)..";8,4;ui_main_inventory.png]"
formspec = formspec.."label[0,"..formheadery..";" ..F("Crafting").."]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[current_player;craftpreview;6,1;1,1;]"
formspec = formspec.."list[current_player;craft;2,1;3,3;]"
formspec = formspec.."label[7,2.5;Trash:]"
formspec = formspec.."list[detached:trash;main;7,3;1,1;]"
formspec = formspec.."list[current_player;craftpreview;6,"..formspecy..";1,1;]"
formspec = formspec.."list[current_player;craft;2,"..formspecy..";3,3;]"
formspec = formspec.."label[7,"..(formspecy + 1.5)..";" .. F("Trash:") .. "]"
formspec = formspec.."list[detached:trash;main;7,"..(formspecy + 2)..";1,1;]"
formspec = formspec.."listring[current_name;craft]"
formspec = formspec.."listring[current_player;main]"
if unified_inventory.is_creative(player_name) then
formspec = formspec.."label[0,2.5;Refill:]"
formspec = formspec.."list[detached:"..player_name.."refill;main;0,3;1,1;]"
formspec = formspec.."label[0,"..(formspecy + 1.5)..";" .. F("Refill:") .. "]"
formspec = formspec.."list[detached:"..minetest.formspec_escape(player_name).."refill;main;0,"..(formspecy +2)..";1,1;]"
end
return {formspec=formspec}
end,
})
-- stack_image_button(): generate a form button displaying a stack of items
--
-- The specified item may be a group. In that case, the group will be
-- represented by some item in the group, along with a flag indicating
-- that it's a group. If the group contains only one item, it will be
-- treated as if that item had been specified directly.
local function stack_image_button(x, y, w, h, buttonname_prefix, item)
local name = item:get_name()
local count = item:get_count()
local show_is_group = false
local displayitem = name.." "..count
local selectitem = name
if name:sub(1, 6) == "group:" then
local group_name = name:sub(7)
local group_item = unified_inventory.get_group_item(group_name)
show_is_group = not group_item.sole
displayitem = group_item.item or "unknown"
selectitem = group_item.sole and displayitem or name
end
local label = show_is_group and "G" or ""
local buttonname = minetest.formspec_escape(buttonname_prefix..unified_inventory.mangle_for_formspec(selectitem))
local button = string.format("item_image_button[%f,%f;%f,%f;%s;%s;%s]",
x, y, w, h,
minetest.formspec_escape(displayitem), buttonname, label)
if show_is_group then
local groupstring, andcount = unified_inventory.extract_groupnames(name)
local grouptip
if andcount == 1 then
grouptip = string.format(S("Any item belonging to the %s group"), groupstring)
elseif andcount > 1 then
grouptip = string.format(S("Any item belonging to the groups %s"), groupstring)
end
grouptip = minetest.formspec_escape(grouptip)
if andcount >= 1 then
button = button .. string.format("tooltip[%s;%s]", buttonname, grouptip)
end
end
return button
end
local recipe_text = {
recipe = "Recipe %d of %d",
usage = "Usage %d of %d",
}
local no_recipe_text = {
recipe = "No recipes",
usage = "No usages",
}
local role_text = {
recipe = "Result",
usage = "Ingredient",
}
local next_alt_text = {
recipe = "Show next recipe",
usage = "Show next usage",
}
local prev_alt_text = {
recipe = "Show previous recipe",
usage = "Show previous usage",
}
local other_dir = {
recipe = "usage",
usage = "recipe",
}
unified_inventory.register_page("craftguide", {
get_formspec = function(player)
get_formspec = function(player, perplayer_formspec)
local formspecy = perplayer_formspec.formspec_y
local formheadery = perplayer_formspec.form_header_y
local craftresultx = perplayer_formspec.craft_result_x
local craftresulty = perplayer_formspec.craft_result_y
local player_name = player:get_player_name()
local formspec = "background[0,1;8,3;ui_craftguide_form.png]"
formspec = formspec.."background[0,4.5;8,4;ui_main_inventory.png]"
formspec = formspec.."image[0,0;1,1;ui_craftguide_icon.png]"
formspec = formspec.."label[1,0;Crafting Guide]"
local player_privs = minetest.get_player_privs(player_name)
local formspec = ""
formspec = formspec.."background[0,"..(formspecy + 3.5)..";8,4;ui_main_inventory.png]"
formspec = formspec.."label[0,"..formheadery..";" .. F("Crafting Guide") .. "]"
formspec = formspec.."listcolors[#00000000;#00000000]"
formspec = formspec.."list[detached:"..player_name.."craftrecipe;output;6,1;1,1;]"
formspec = formspec.."label[6,3.35;Method:]"
local item_name = unified_inventory.current_item[player_name]
local craft = nil
if item_name then
formspec = formspec.."textarea[1.3,0.6;10,1;;Result: "..item_name..";]"
local alternates = 0
local alternate = unified_inventory.alternate[player_name]
local crafts = unified_inventory.crafts_table[item_name]
if crafts ~= nil and #crafts > 0 then
alternates = #crafts
craft = crafts[alternate]
local method = craft.type
local allow_auto_craft = ((method == "normal") or (method == "shapeless"))
if craft.type == "normal" then
method = "crafting"
elseif craft.type == "shapeless" then
method = "shapeless crafting"
elseif craft.type == "alloy" then
method = "alloy cooking"
end
formspec = formspec.."label[6,3.75;"..method.."]"
if allow_auto_craft then
formspec = formspec.."label[6,1.95;Copy to craft grid:]"
.."button[6,2.5;0.6,0.5;craftguide_craft_1;1]"
.."button[6.6,2.5;0.6,0.5;craftguide_craft_10;10]"
.."button[7.2,2.5;0.6,0.5;craftguide_craft_max;All]"
end
end
if alternates > 1 then
formspec = formspec.."label[0,2.6;Recipe "
..tostring(alternate).." of "
..tostring(alternates).."]"
.."button[0,3.15;2,1;alternate;Alternate]"
end
if not item_name then return {formspec=formspec} end
local dir = unified_inventory.current_craft_direction[player_name]
local rdir
if dir == "recipe" then rdir = "usage" end
if dir == "usage" then rdir = "recipe" end
local crafts = unified_inventory.crafts_for[dir][item_name]
local alternate = unified_inventory.alternate[player_name]
local alternates, craft
if crafts ~= nil and #crafts > 0 then
alternates = #crafts
craft = crafts[alternate]
end
local craftinv = minetest.get_inventory({
type = "detached",
name = player_name.."craftrecipe"
})
-- fake buttons just to make 3x3 grid
for y = 1, 3 do
for x = 1, 3 do
formspec = formspec.."image_button["
..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;ui_blank_image.png;;]"
end
end
formspec = formspec.."background[0.5,"..(formspecy + 0.2)..";8,3;ui_craftguide_form.png]"
formspec = formspec.."textarea["..craftresultx..","..craftresulty
..";10,1;;"..minetest.formspec_escape(F(role_text[dir])..": "..item_name)..";]"
formspec = formspec..stack_image_button(0, formspecy, 1.1, 1.1, "item_button_"
.. rdir .. "_", ItemStack(item_name))
if not craft then
craftinv:set_stack("output", 1, nil)
return {formspec=formspec}
end
craftinv:set_stack("output", 1, craft.output)
local width = craft.width
if width == 0 then
-- Shapeless recipe
width = 3
end
local i = 1
for y = 1, 3 do
for x = 1, width do
local item = craft.items[i]
if item then
if string.sub(item, 1, 6) == "group:" then
local group = string.sub(item, 7)
formspec = formspec.."image_button["
..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;"
.."ui_group.png;"
.."item_group_"..minetest.formspec_escape(group)..";"
..minetest.formspec_escape(group).."]"
else
formspec = formspec.."item_image_button["
..(1.0 + x)..","..(0.0 + y)..";1.1,1.1;"
..minetest.formspec_escape(item)..";"
.."item_button_"
..minetest.formspec_escape(item)..";]"
end
formspec = formspec.."label[5.5,"..(formspecy + 2.35)..";"
..minetest.formspec_escape(F(no_recipe_text[dir])).."]"
local no_pos = dir == "recipe" and 4.5 or 6.5
local item_pos = dir == "recipe" and 6.5 or 4.5
formspec = formspec.."image["..no_pos..","..formspecy..";1.1,1.1;ui_no.png]"
formspec = formspec..stack_image_button(item_pos, formspecy, 1.1, 1.1, "item_button_"
..other_dir[dir].."_", ItemStack(item_name))
if player_privs.give == true then
formspec = formspec.."label[0,"..(formspecy + 2.10)..";" .. F("Give me:") .. "]"
.."button[0, "..(formspecy + 2.7)..";0.6,0.5;craftguide_giveme_1;1]"
.."button[0.6,"..(formspecy + 2.7)..";0.7,0.5;craftguide_giveme_10;10]"
.."button[1.3,"..(formspecy + 2.7)..";0.8,0.5;craftguide_giveme_99;99]"
end
return {formspec = formspec}
end
local craft_type = unified_inventory.registered_craft_types[craft.type] or
unified_inventory.craft_type_defaults(craft.type, {})
if craft_type.icon then
formspec = formspec..string.format(" image[%f,%f;%f,%f;%s]",5.7,(formspecy + 0.05),0.5,0.5,craft_type.icon)
end
formspec = formspec.."label[5.5,"..(formspecy + 1)..";" .. minetest.formspec_escape(craft_type.description).."]"
formspec = formspec..stack_image_button(6.5, formspecy, 1.1, 1.1, "item_button_usage_", ItemStack(craft.output))
local display_size = craft_type.dynamic_display_size and craft_type.dynamic_display_size(craft) or { width = craft_type.width, height = craft_type.height }
local craft_width = craft_type.get_shaped_craft_width and craft_type.get_shaped_craft_width(craft) or display_size.width
-- This keeps recipes aligned to the right,
-- so that they're close to the arrow.
local xoffset = 5.5
-- Offset factor for crafting grids with side length > 4
local of = (3/math.max(3, math.max(display_size.width, display_size.height)))
local od = 0
-- Minimum grid size at which size optimazation measures kick in
local mini_craft_size = 6
if display_size.width >= mini_craft_size then
od = math.max(1, display_size.width - 2)
xoffset = xoffset - 0.1
end
-- Size modifier factor
local sf = math.min(1, of * (1.05 + 0.05*od))
-- Button size
local bsize_h = 1.1 * sf
local bsize_w = bsize_h
if display_size.width >= mini_craft_size then
bsize_w = 1.175 * sf
end
if (bsize_h > 0.35 and display_size.width) then
for y = 1, display_size.height do
for x = 1, display_size.width do
local item
if craft and x <= craft_width then
item = craft.items[(y-1) * craft_width + x]
end
-- Flipped x, used to build formspec buttons from right to left
local fx = display_size.width - (x-1)
-- x offset, y offset
local xof = (fx-1) * of + of
local yof = (y-1) * of + 1
if item then
formspec = formspec..stack_image_button(
xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h,
"item_button_recipe_",
ItemStack(item))
else
-- Fake buttons just to make grid
formspec = formspec.."image_button["
..tostring(xoffset - xof)..","..tostring(formspecy - 1 + yof)
..";"..bsize_w..","..bsize_h..";ui_blank_image.png;;]"
end
i = i + 1
end
end
return {formspec=formspec}
else
-- Error
formspec = formspec.."label["
..tostring(2)..","..tostring(formspecy)
..";"..minetest.formspec_escape(S("This recipe is too\nlarge to be displayed.")).."]"
end
if craft_type.uses_crafting_grid and display_size.width <= 3 then
formspec = formspec.."label[0,"..(formspecy + 0.9)..";" .. F("To craft grid:") .. "]"
.."button[0, "..(formspecy + 1.5)..";0.6,0.5;craftguide_craft_1;1]"
.."button[0.6,"..(formspecy + 1.5)..";0.7,0.5;craftguide_craft_10;10]"
.."button[1.3,"..(formspecy + 1.5)..";0.8,0.5;craftguide_craft_max;" .. F("All") .. "]"
end
if player_privs.give then
formspec = formspec.."label[0,"..(formspecy + 2.1)..";" .. F("Give me:") .. "]"
.."button[0, "..(formspecy + 2.7)..";0.6,0.5;craftguide_giveme_1;1]"
.."button[0.6,"..(formspecy + 2.7)..";0.7,0.5;craftguide_giveme_10;10]"
.."button[1.3,"..(formspecy + 2.7)..";0.8,0.5;craftguide_giveme_99;99]"
end
if alternates and alternates > 1 then
formspec = formspec.."label[5.5,"..(formspecy + 1.6)..";"
..string.format(F(recipe_text[dir]), alternate, alternates).."]"
.."image_button[5.5,"..(formspecy + 2)..";1,1;ui_left_icon.png;alternate_prev;]"
.."image_button[6.5,"..(formspecy + 2)..";1,1;ui_right_icon.png;alternate;]"
.."tooltip[alternate_prev;"..F(prev_alt_text[dir]).."]"
.."tooltip[alternate;"..F(next_alt_text[dir]).."]"
end
return {formspec = formspec}
end,
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
local function craftguide_giveme(player, formname, fields)
local amount
for k, v in pairs(fields) do
amount = k:match("craftguide_giveme_(.*)")
if amount then break end
end
if not amount then return end
amount = tonumber(amount)
if amount == 0 then return end
local player_name = player:get_player_name()
local output = unified_inventory.current_item[player_name]
if (not output) or (output == "") then return end
local player_inv = player:get_inventory()
player_inv:add_item("main", {name = output, count = amount})
end
-- tells if an item can be moved and returns an index if so
local function item_fits(player_inv, craft_item, needed_item)
local need_group = string.sub(needed_item, 1, 6) == "group:"
if need_group then
need_group = string.sub(needed_item, 7)
end
if craft_item
and not craft_item:is_empty() then
local ciname = craft_item:get_name()
-- abort if the item there isn't usable
if ciname ~= needed_item
and not need_group then
return
end
-- abort if no item fits onto it
if craft_item:get_count() >= craft_item:get_definition().stack_max then
return
end
-- use the item there if it's in the right group and a group item is needed
if need_group then
if minetest.get_item_group(ciname, need_group) == 0 then
return
end
needed_item = ciname
need_group = false
end
end
if need_group then
-- search an item of the specific group
for i,item in pairs(player_inv:get_list("main")) do
if not item:is_empty()
and minetest.get_item_group(item:get_name(), need_group) > 0 then
return i
end
end
-- no index found
return
end
-- search an item with a the name needed_item
for i,item in pairs(player_inv:get_list("main")) do
if not item:is_empty()
and item:get_name() == needed_item then
return i
end
end
-- no index found
end
-- modifies the player inventory and returns the changed craft_item if possible
local function move_item(player_inv, craft_item, needed_item)
local stackid = item_fits(player_inv, craft_item, needed_item)
if not stackid then
return
end
local wanted_stack = player_inv:get_stack("main", stackid)
local taken_item = wanted_stack:take_item()
player_inv:set_stack("main", stackid, wanted_stack)
if not craft_item
or craft_item:is_empty() then
return taken_item
end
craft_item:add_item(taken_item)
return craft_item
end
local function craftguide_craft(player, formname, fields)
local amount
for k, v in pairs(fields) do
amount = k:match("craftguide_craft_(.*)")
@ -241,17 +492,13 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
if not amount then return end
local player_name = player:get_player_name()
local recipe_inv = minetest.get_inventory({
type="detached",
name=player_name.."craftrecipe",
})
local output = unified_inventory.current_item[player_name]
if (not output) or (output == "") then return end
local player_inv = player:get_inventory()
local crafts = unified_inventory.crafts_table[output]
local crafts = unified_inventory.crafts_for[unified_inventory.current_craft_direction[player_name]][output]
if (not crafts) or (#crafts == 0) then return end
local alternate = unified_inventory.alternate[player_name]
@ -269,11 +516,13 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
width = 3
end
amount = tonumber(amount) or 99
--[[
if amount == "max" then
amount = 99 -- Arbitrary; need better way to do this.
else
amount = tonumber(amount)
end
end--]]
for iter = 1, amount do
local index = 1
@ -283,17 +532,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if needed_item then
local craft_index = ((y - 1) * 3) + x
local craft_item = craft_list[craft_index]
if (not craft_item) or (craft_item:is_empty()) or (craft_item:get_name() == needed_item) then
itemname = craft_item and craft_item:get_name() or needed_item
local needed_stack = ItemStack(needed_item)
if player_inv:contains_item("main", needed_stack) then
local count = (craft_item and craft_item:get_count() or 0) + 1
if count <= needed_stack:get_definition().stack_max then
local stack = ItemStack({name=needed_item, count=count})
craft_list[craft_index] = stack
player_inv:remove_item("main", needed_stack)
end
end
local newitem = move_item(player_inv, craft_item, needed_item)
if newitem then
craft_list[craft_index] = newitem
end
end
index = index + 1
@ -304,4 +545,17 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
player_inv:set_list("craft", craft_list)
unified_inventory.set_inventory_formspec(player, "craft")
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
for k, v in pairs(fields) do
if k:match("craftguide_craft_") then
craftguide_craft(player, formname, fields)
return
end
if k:match("craftguide_giveme_") then
craftguide_giveme(player, formname, fields)
return
end
end
end)

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
sounds/birds.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/click.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/dingdong.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/electricity.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/owl.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/paperflip1.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/paperflip2.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/teleport.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/trash.ogg Normal file → Executable file

Binary file not shown.

BIN
sounds/trash_all.ogg Normal file → Executable file

Binary file not shown.

BIN
textures/bags_large.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 572 B

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
textures/bags_medium.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 B

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
textures/bags_small.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 572 B

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 358 B

BIN
textures/ui_2_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 727 B

BIN
textures/ui_bags_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
textures/ui_bags_lg_form.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 378 B

BIN
textures/ui_bags_main_form.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 503 B

BIN
textures/ui_bags_med_form.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 367 B

BIN
textures/ui_bags_sm_form.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 355 B

BIN
textures/ui_blank_image.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

BIN
textures/ui_circular_arrows_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 234 B

BIN
textures/ui_group.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 689 B

BIN
textures/ui_main_inventory.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 321 B

BIN
textures/ui_misc_form.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 408 B

BIN
textures/ui_moon_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
textures/ui_news_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

BIN
textures/ui_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 234 B

BIN
textures/ui_reset_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 696 B

BIN
textures/ui_single_slot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
textures/ui_waypoint_set_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
textures/ui_waypoints_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
textures/ui_xyz_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 753 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
textures/ui_xyz_on_icon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 817 B

After

Width:  |  Height:  |  Size: 1.4 KiB

282
waypoints.lua Normal file → Executable file
View File

@ -1,72 +1,110 @@
unified_inventory.hud_colors = {
{"#FFFFFF", 0xFFFFFF, "White"},
{"#DBBB00", 0xf1d32c, "Yellow"},
{"#DD0000", 0xDD0000, "Red"},
{"#2cf136", 0x2cf136, "Green"},
{"#2c4df1", 0x2c4df1, "Blue"},
}
unified_inventory.hud_colors_max = #unified_inventory.hud_colors
local S = unified_inventory.gettext
local F = unified_inventory.fgettext
local hud_colors = {
{"#FFFFFF", 0xFFFFFF, S("White")},
{"#DBBB00", 0xf1d32c, S("Yellow")},
{"#DD0000", 0xDD0000, S("Red")},
{"#2cf136", 0x2cf136, S("Green")},
{"#2c4df1", 0x2c4df1, S("Blue")},
}
local hud_colors_max = #hud_colors
-- Stores temporary player data (persists until player leaves)
local waypoints_temp = {}
unified_inventory.register_page("waypoints", {
get_formspec = function(player)
local waypoints = datastorage.get_container (player, "waypoints")
local formspec = "background[0,4.5;8,4;ui_main_inventory.png]"..
"image[0,0;1,1;ui_waypoints_icon.png]"..
"label[1,0;Waypoints]"
local player_name = player:get_player_name()
-- build a "fake" temp entry if the server took too long
-- during sign-on and returned an empty entry
if not waypoints_temp[player_name] then waypoints_temp[player_name] = {hud = 1} end
local waypoints = datastorage.get(player_name, "waypoints")
local formspec = "background[0,4.5;8,4;ui_main_inventory.png]" ..
"image[0,0;1,1;ui_waypoints_icon.png]" ..
"label[1,0;" .. F("Waypoints") .. "]"
-- Tabs buttons:
local i
for i = 1, 5, 1 do
if i == waypoints.selected then
formspec = formspec ..
"image_button[0.0,".. 0.2 + i*0.7 ..";.8,.8;ui_blue_icon_background.png^ui_"..
i .."_icon.png;select_waypoint".. i .. ";]"
else
formspec = formspec ..
"image_button[0.0,".. 0.2 + i*0.7 ..";.8,.8;ui_"..
i .."_icon.png;select_waypoint".. i .. ";]"
end
formspec = formspec ..
"image_button[0.0," .. 0.2 + i * 0.7 .. ";.8,.8;" ..
(i == waypoints.selected and "ui_blue_icon_background.png^" or "") ..
"ui_" .. i .. "_icon.png;" ..
"select_waypoint" .. i .. ";]" ..
"tooltip[select_waypoint" .. i .. ";"
.. (S("Select Waypoint #%d"):format(i)).."]"
end
i = waypoints.selected
local i = waypoints.selected or 1
local waypoint = waypoints[i] or {}
local temp = waypoints_temp[player_name][i] or {}
local default_name = string.format(S("Waypoint %d"), i)
-- Main buttons:
formspec = formspec ..
"image_button[4.5,3.7;.8,.8;ui_waypoint_set_icon.png;set_waypoint".. i .. ";]"
formspec = formspec ..
"image_button[4.5,3.7;.8,.8;"..
"ui_waypoint_set_icon.png;"..
"set_waypoint"..i..";]"..
"tooltip[set_waypoint" .. i .. ";"
.. F("Set waypoint to current location").."]"
if waypoints[i].active then
formspec = formspec ..
"image_button[5.2,3.7;.8,.8;ui_on_icon.png;toggle_waypoint".. i .. ";]"
else
formspec = formspec ..
"image_button[5.2,3.7;.8,.8;ui_off_icon.png;toggle_waypoint".. i .. ";]"
end
formspec = formspec ..
"image_button[5.2,3.7;.8,.8;"..
(waypoint.active and "ui_on_icon.png" or "ui_off_icon.png")..";"..
"toggle_waypoint"..i..";]"..
"tooltip[toggle_waypoint" .. i .. ";"
.. F("Make waypoint "
..(waypoint.active and "invisible" or "visible")).."]"
if waypoints[i].display_pos then
formspec = formspec ..
"image_button[5.9,3.7;.8,.8;ui_green_icon_background.png^ui_xyz_icon.png;toggle_display_pos".. i .. ";]"
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((waypoint.display_pos and "Disable" or "Enable")
.." display of waypoint coordinates").."]"
formspec = formspec ..
"image_button[6.6,3.7;.8,.8;"..
"ui_circular_arrows_icon.png;"..
"toggle_color"..i..";]"..
"tooltip[toggle_color" .. i .. ";"
.. F("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("Edit waypoint name").."]"
-- Waypoint's info:
if waypoint.active then
formspec = formspec .. "label[1,0.8;"..F("Waypoint active").."]"
else
formspec = formspec ..
"image_button[5.9,3.7;.8,.8;ui_red_icon_background.png^ui_xyz_icon.png;toggle_display_pos".. i .. ";]"
formspec = formspec .. "label[1,0.8;"..F("Waypoint inactive").."]"
end
formspec = formspec ..
"image_button[6.6,3.7;.8,.8;ui_circular_arrows_icon.png;toggle_color".. i .. ";]"..
"image_button[7.3,3.7;.8,.8;ui_pencil_icon.png;rename_waypoint".. i .. ";]"
-- Waypoint's info:
if waypoints[i].active then
formspec = formspec .. "label[1,0.8;Waypoint active]"
else
formspec = formspec .. "label[1,0.8;Waypoint inactive]"
if temp.edit then
formspec = formspec ..
"field[1.3,3.2;6,.8;rename_box" .. i .. ";;"
..(waypoint.name or default_name).."]" ..
"image_button[7.3,2.9;.8,.8;"..
"ui_ok_icon.png;"..
"confirm_rename"..i.. ";]"..
"tooltip[confirm_rename" .. i .. ";"
.. F("Finish editing").."]"
end
formspec = formspec .. "label[1,1.3;World position: " ..
minetest.pos_to_string(waypoints[i].world_pos) .. "]" ..
"label[1,1.8;Name: ]".. waypoints[i].name .. "]" ..
"label[1,2.3;Hud text color: " ..
unified_inventory.hud_colors[waypoints[i].color][3] .. "]"
formspec = formspec .. "label[1,1.3;"..F("World position")..": " ..
minetest.pos_to_string(waypoint.world_pos or vector.new()) .. "]" ..
"label[1,1.8;"..F("Name")..": ".. (waypoint.name or default_name) .. "]" ..
"label[1,2.3;"..F("HUD text color")..": " ..
hud_colors[waypoint.color or 1][3] .. "]"
return {formspec=formspec}
end,
})
@ -74,135 +112,137 @@ unified_inventory.register_page("waypoints", {
unified_inventory.register_button("waypoints", {
type = "image",
image = "ui_waypoints_icon.png",
tooltip = S("Waypoints"),
hide_lite=true,
show_with = false, --Modif MFF (Crabman 30/06/2015)
})
unified_inventory.update_hud = function (player, waypoint)
local function update_hud(player, waypoints, temp, i)
local waypoint = waypoints[i]
if not waypoint then return end
temp[i] = temp[i] or {}
temp = temp[i]
local pos = waypoint.world_pos or vector.new()
local name
if waypoint.display_pos then
name = "("..
waypoint.world_pos.x .. "," ..
waypoint.world_pos.y .. "," ..
waypoint.world_pos.z .. ")"
if waypoint.name ~= "" then
name = name .. ", " ..
waypoint.name
name = minetest.pos_to_string(pos)
if waypoint.name then
name = name..", "..waypoint.name
end
else
name = waypoint.name
name = waypoint.name or "Waypoint "..i
end
if temp.hud then
player:hud_remove(temp.hud)
end
if waypoint.active then
player:hud_remove(waypoint.hud)
waypoint.hud = player:hud_add({
temp.hud = player:hud_add({
hud_elem_type = "waypoint",
number = unified_inventory.hud_colors[waypoint.color][2] ,
number = hud_colors[waypoint.color or 1][2] ,
name = name,
text = "m",
world_pos = waypoint.world_pos
world_pos = pos
})
else
if waypoint.hud ~= nil then
player:hud_remove(waypoint.hud)
waypoint.hud = nil
end
else
temp.hud = nil
end
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "" then
return
end
if formname ~= "" then return end
local player_name = player:get_player_name()
local update_formspec = false
local update_hud = false
local waypoints = datastorage.get_container (player, "waypoints")
for i = 1, 5, 1 do
local need_update_hud = false
local hit = false
local waypoints = datastorage.get(player_name, "waypoints")
local temp = waypoints_temp[player_name]
for i = 1, 5, 1 do
if fields["select_waypoint"..i] then
hit = true
waypoints.selected = i
update_formspec = true
end
if fields["toggle_waypoint"..i] then
hit = true
waypoints[i] = waypoints[i] or {}
waypoints[i].active = not (waypoints[i].active)
update_hud = true
need_update_hud = true
update_formspec = true
end
if fields["set_waypoint"..i] then
hit = true
local pos = player:getpos()
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
update_hud = true
need_update_hud = true
update_formspec = true
end
if fields["rename_waypoint"..i] then
waypoints[i].edit = true
hit = true
temp[i] = temp[i] or {}
temp[i].edit = true
update_formspec = true
end
if fields["toggle_display_pos"..i] then
hit = true
waypoints[i] = waypoints[i] or {}
waypoints[i].display_pos = not waypoints[i].display_pos
update_hud = true
need_update_hud = true
update_formspec = true
end
if fields["toggle_color"..i] then
local color = waypoints[i].color
hit = true
waypoints[i] = waypoints[i] or {}
local color = waypoints[i].color or 1
color = color + 1
if color > unified_inventory.hud_colors_max then
if color > hud_colors_max then
color = 1
end
waypoints[i].color = color
update_hud = true
need_update_hud = true
update_formspec = true
end
if fields["confirm_rename"..i] then
waypoints[i].edit = false
waypoints[i].name = fields["rename_box"..i]
update_hud = true
hit = true
waypoints[i] = waypoints[i] or {}
temp[i].edit = false
waypoints[i].name = fields["rename_box"..i]
need_update_hud = true
update_formspec = true
end
if update_hud then
unified_inventory.update_hud (player, waypoints[i])
if need_update_hud then
update_hud(player, waypoints, temp, i)
end
if update_formspec then
unified_inventory.set_inventory_formspec(player, "waypoints")
end
if hit then return end
end
end)
minetest.register_on_joinplayer(function(player)
local waypoints = datastorage.get_container (player, "waypoints")
-- Create new waypoints data
if waypoints[1] == nil then
for i = 1, 5, 1 do
waypoints[i] = {
edit = false,
active = false,
display_pos = true,
color = 2,
name = "Waypoint ".. i,
world_pos = {x = 0, y = 0, z = 0},
}
end
datastorage.save_container(player)
local player_name = player:get_player_name()
local waypoints = datastorage.get(player_name, "waypoints")
local temp = {}
waypoints_temp[player_name] = temp
for i = 1, 5 do
update_hud(player, waypoints, temp, i)
end
-- Initialize waypoints
minetest.after(0.5, function()
waypoints.selected = 1
for i = 1, 5, 1 do
waypoints[i].edit = false
unified_inventory.update_hud (player, waypoints[i])
end
end)
end)
minetest.register_on_leaveplayer(function(player)
waypoints_temp[player:get_player_name()] = nil
end)