i3 insted of smart inventory is used - forced minetest 5.4
|
@ -11,7 +11,7 @@ DST="$PROJ"/mods/ # Game mods dir
|
|||
|
||||
|
||||
#copy files
|
||||
MOD_PATH=("player/skinsdb" "gui/smart_inventory" "mobs/mobs_mobkit/petz/petz") #temporary not used: "minetest_game"
|
||||
MOD_PATH=("player/skinsdb" "mobs/mobs_mobkit/petz/petz") #temporary not used: "minetest_game"
|
||||
|
||||
for MOD_INDEX in ${!MOD_PATH[*]}
|
||||
do
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
name = A Planet Alive
|
||||
min_minetest_version = 5.3
|
||||
min_minetest_version = 5.4
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
allow_defined_top = true
|
||||
|
||||
ignore = {
|
||||
"get_debug_grid",
|
||||
}
|
||||
|
||||
read_globals = {
|
||||
"minetest",
|
||||
"default",
|
||||
"armor",
|
||||
"skins",
|
||||
"awards",
|
||||
"vector",
|
||||
"string",
|
||||
"table",
|
||||
"ItemStack",
|
||||
}
|
||||
|
||||
globals = {
|
||||
"i3",
|
||||
"core",
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
## API
|
||||
|
||||
### Custom tabs
|
||||
|
||||
#### `i3.new_tab(def)`
|
||||
|
||||
Custom tabs can be added to the `i3` inventory as follow (example):
|
||||
|
||||
```Lua
|
||||
i3.new_tab {
|
||||
name = "stuff",
|
||||
description = "Stuff",
|
||||
image = "image.png", -- Optional, adds an image next to the tab description
|
||||
|
||||
-- Determine if the tab is visible by a player, `false` or `nil` hide the tab
|
||||
access = function(player, data)
|
||||
local name = player:get_player_name()
|
||||
if name == "singleplayer" then
|
||||
return false
|
||||
end
|
||||
end,
|
||||
|
||||
formspec = function(player, data, fs)
|
||||
fs("label[3,1;This is just a test]")
|
||||
end,
|
||||
|
||||
fields = function(player, data, fields)
|
||||
|
||||
end,
|
||||
|
||||
-- Determine if the recipe panels must be hidden or not (must return a boolean)
|
||||
hide_panels = function(player, data)
|
||||
local name = player:get_player_name()
|
||||
return core.is_creative_enabled(name)
|
||||
end,
|
||||
}
|
||||
```
|
||||
|
||||
- `player` is an `ObjectRef` to the user.
|
||||
- `data` are the user data.
|
||||
- `fs` is the formspec table which is callable with a metamethod. Each call adds a new entry.
|
||||
|
||||
#### `i3.set_fs(player[, extra_formspec])`
|
||||
|
||||
Updates the current formspec. `extra_formspec` adds an additional formspec string.
|
||||
|
||||
#### `i3.delete_tab(tabname)`
|
||||
|
||||
Deletes a tab by name.
|
||||
|
||||
#### `i3.set_tab(player[, tabname])`
|
||||
|
||||
Sets the current tab by name. `player` is an `ObjectRef` to the user.
|
||||
`tabname` can be omitted to get an empty tab.
|
||||
|
||||
#### `i3.override_tab(tabname, def)`
|
||||
|
||||
Overrides a tab by name. `def` is the tab definition like seen in `i3.set_tab`.
|
||||
|
||||
#### `i3.get_tabs()`
|
||||
|
||||
Returns the list of registered tabs.
|
||||
|
||||
---
|
||||
|
||||
### Custom recipes
|
||||
|
||||
Custom recipes are nonconventional crafts outside the main crafting grid.
|
||||
They can be registered in-game dynamically and have a size beyond 3x3 items.
|
||||
|
||||
**Note:** the registration format differs from the default registration format in everything.
|
||||
The width is automatically calculated depending where you place the commas. Look at the examples attentively.
|
||||
|
||||
#### Registering a custom crafting type (example)
|
||||
|
||||
```Lua
|
||||
i3.register_craft_type("digging", {
|
||||
description = "Digging",
|
||||
icon = "default_tool_steelpick.png",
|
||||
})
|
||||
```
|
||||
|
||||
#### Registering a custom crafting recipe (examples)
|
||||
|
||||
```Lua
|
||||
i3.register_craft({
|
||||
type = "digging",
|
||||
result = "default:cobble 2",
|
||||
items = {"default:stone"},
|
||||
})
|
||||
```
|
||||
|
||||
```Lua
|
||||
i3.register_craft({
|
||||
result = "default:cobble 16",
|
||||
items = {
|
||||
"default:stone, default:stone, default:stone",
|
||||
"default:stone, , default:stone",
|
||||
"default:stone, default:stone, default:stone",
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Recipes can be registered in a Minecraft-like way:
|
||||
|
||||
```Lua
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"X X",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
```
|
||||
|
||||
Multiples recipes can also be registered:
|
||||
|
||||
```Lua
|
||||
i3.register_craft({
|
||||
{
|
||||
result = "default:mese",
|
||||
items = {
|
||||
"default:mese_crystal, default:mese_crystal",
|
||||
"default:mese_crystal, default:mese_crystal",
|
||||
}
|
||||
},
|
||||
|
||||
big = {
|
||||
result = "default:mese 4",
|
||||
items = {
|
||||
"default:mese_crystal, default:mese_crystal",
|
||||
"default:mese_crystal, default:mese_crystal",
|
||||
"default:mese_crystal, default:mese_crystal",
|
||||
"default:mese_crystal, default:mese_crystal",
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Recipes can be registered from a given URL containing a JSON file (HTTP support is required¹):
|
||||
|
||||
```Lua
|
||||
i3.register_craft({
|
||||
url = "https://raw.githubusercontent.com/minetest-mods/i3/main/test_online_recipe.json"
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Recipe filters
|
||||
|
||||
Recipe filters can be used to filter the recipes shown to players. Progressive
|
||||
mode is implemented as a recipe filter.
|
||||
|
||||
#### `i3.add_recipe_filter(name, function(recipes, player))`
|
||||
|
||||
Adds a recipe filter with the given `name`. The filter function returns the
|
||||
recipes to be displayed, given the available recipes and an `ObjectRef` to the
|
||||
user. Each recipe is a table of the form returned by
|
||||
`minetest.get_craft_recipe`.
|
||||
|
||||
Example function to hide recipes for items from a mod called "secretstuff":
|
||||
|
||||
```lua
|
||||
i3.add_recipe_filter("Hide secretstuff", function(recipes)
|
||||
local filtered = {}
|
||||
for _, recipe in ipairs(recipes) do
|
||||
if recipe.output:sub(1,12) ~= "secretstuff:" then
|
||||
filtered[#filtered + 1] = recipe
|
||||
end
|
||||
end
|
||||
|
||||
return filtered
|
||||
end)
|
||||
```
|
||||
|
||||
#### `i3.set_recipe_filter(name, function(recipe, player))`
|
||||
|
||||
Removes all recipe filters and adds a new one.
|
||||
|
||||
#### `i3.delete_recipe_filter(name)`
|
||||
|
||||
Removes the recipe filter with the given `name`.
|
||||
|
||||
#### `i3.get_recipe_filters()`
|
||||
|
||||
Returns a map of recipe filters, indexed by name.
|
||||
|
||||
---
|
||||
|
||||
### Search filters
|
||||
|
||||
Search filters are used to perform specific searches inside the search field.
|
||||
These filters are cumulative to perform a specific search.
|
||||
They can be used like so: `<optional_name> +<filter name>=<value1>,<value2>,<...>`
|
||||
|
||||
Example usages:
|
||||
|
||||
- `+groups=cracky,crumbly`: search for groups `cracky` and `crumbly` in all items.
|
||||
- `wood +groups=flammable +types=node`: search for group `flammable` amongst items which contain
|
||||
`wood` in their names AND have a `node` drawtype.
|
||||
|
||||
Notes:
|
||||
- If `optional_name` is omitted, the search filter will apply to all items, without pre-filtering.
|
||||
- The `+groups` and `+types` filters are currently implemented by default.
|
||||
|
||||
#### `i3.add_search_filter(name, function(item, values))`
|
||||
|
||||
Adds a search filter with the given `name`. `values` is a table of all possible values.
|
||||
The search function must return a boolean value (whether the given item should be listed or not).
|
||||
|
||||
Example function sorting items by drawtype:
|
||||
|
||||
```lua
|
||||
i3.add_search_filter("types", function(item, drawtypes)
|
||||
local t = {}
|
||||
|
||||
for i, dt in ipairs(drawtypes) do
|
||||
t[i] = (dt == "node" and reg_nodes[item] and 1) or
|
||||
(dt == "item" and reg_craftitems[item] and 1) or
|
||||
(dt == "tool" and reg_tools[item] and 1) or nil
|
||||
end
|
||||
|
||||
return #t > 0
|
||||
end)
|
||||
```
|
||||
|
||||
#### `i3.remove_search_filter(name)`
|
||||
|
||||
Removes the search filter with the given `name`.
|
||||
|
||||
#### `i3.get_search_filters()`
|
||||
|
||||
Returns a map of search filters, indexed by name.
|
||||
|
||||
---
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
#### `i3.group_stereotypes`
|
||||
|
||||
This is the table indexing the item groups by stereotypes.
|
||||
You can add a stereotype like so:
|
||||
|
||||
```Lua
|
||||
i3.group_stereotypes.radioactive = "mod:item"
|
||||
```
|
||||
|
||||
#### `i3.export_url`
|
||||
|
||||
If set, the mod will export all the cached recipes and usages in a JSON format
|
||||
to the given URL (HTTP support is required¹).
|
||||
|
||||
---
|
||||
|
||||
**¹** Add `i3` to the `secure.http_mods` or `secure.trusted_mods` setting in `minetest.conf`.
|
|
@ -0,0 +1,60 @@
|
|||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020-2021 Jean-Patrick Guerrero and contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
Licenses of media (textures)
|
||||
----------------------------
|
||||
|
||||
paramat (CC BY-SA 3.0):
|
||||
i3_arrow.png - derived from a texture by BlockMen (CC BY-SA 3.0)
|
||||
i3_hotbar.png
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
|
@ -0,0 +1,50 @@
|
|||
# i3
|
||||
|
||||
[![ContentDB](https://content.minetest.net/packages/jp/i3/shields/title/)](https://content.minetest.net/packages/jp/i3/) [![ContentDB](https://content.minetest.net/packages/jp/i3/shields/downloads/)](https://content.minetest.net/packages/jp/i3/)
|
||||
|
||||
#### **`i3`** is a next-generation inventory for Minetest.
|
||||
|
||||
This inventory offers a slick, modern UI made with the latest technologies of the Minetest engine.
|
||||
**`i3`** provides a rich [**API**](https://github.com/minetest-mods/i3/blob/master/API.md) for mod developers who want to extend it.
|
||||
|
||||
This mod requires **Minetest 5.4+**
|
||||
|
||||
#### List of features:
|
||||
- Crafting Guide (only in survival mode)
|
||||
- Progressive Mode¹
|
||||
- Quick Crafting
|
||||
- Backpacks
|
||||
- 3D Player Model Preview
|
||||
- Inventory Sorting (alphabetical + item stack compression)
|
||||
- Item Bookmarks
|
||||
|
||||
**¹** *This mode is a Terraria-like system that shows recipes you can craft from items you ever had in your inventory.
|
||||
To enable it: `i3_progressive_mode = true` in `minetest.conf`.*
|
||||
|
||||
|
||||
#### This mod officially supports the following mods:
|
||||
- [**`3d_armor`**](https://content.minetest.net/packages/stu/3d_armor/)
|
||||
- [**`skinsdb`**](https://content.minetest.net/packages/bell07/skinsdb/)
|
||||
- [**`awards`**](https://content.minetest.net/packages/rubenwardy/awards/)
|
||||
|
||||
#### Recommendations
|
||||
|
||||
To use this mod in the best conditions, it's recommended to follow these recommendations:
|
||||
|
||||
- Use LuaJIT
|
||||
- Use a HiDPI widescreen display
|
||||
- Use the default Freetype font style
|
||||
|
||||
#### Notes
|
||||
|
||||
`i3` uses a larger inventory than the usual inventories in Minetest games.
|
||||
Thus, most chests will be unadapted to this inventory size.
|
||||
The `i3` inventory is 9 slots wide by default (without backpack), such as in Minecraft.
|
||||
|
||||
Report any bug on the [**Bug Tracker**](https://github.com/minetest-mods/i3/issues).
|
||||
|
||||
Love this mod? Donations are appreciated: https://www.paypal.me/jpg84240
|
||||
|
||||
Demo video: https://www.youtube.com/watch?v=25nCAaqeacU
|
||||
|
||||
![Preview](https://user-images.githubusercontent.com/7883281/109045805-4f450600-76d4-11eb-90f7-b99ab939246a.png)
|
|
@ -0,0 +1,85 @@
|
|||
# textdomain: i3
|
||||
|
||||
### init.lua ###
|
||||
|
||||
@1 added in your inventory=@1 ajouté à votre inventaire
|
||||
@1 new recipe(s) discovered!=@1 nouvelle(s) recette(s) découverte(s)!
|
||||
@1 of chance to drop=@1 de chance de tomber
|
||||
@1 spawned=@1 spawné
|
||||
Achievements: @1 of @2 (@3)=Succès : @1 sur @2 (@3)
|
||||
Any black dye=N'importe quel colorant noir
|
||||
Any black flower=N'importe quelle fleur noire
|
||||
Any blue dye=N'importe quel colorant bleu
|
||||
Any blue flower=N'importe quelle fleur bleue
|
||||
Any brown dye=N'importe quel colorant marron
|
||||
Any carpet=N'importe quel tapis
|
||||
Any coal=N'importe quel charbon
|
||||
Any cyan dye=N'importe quel colorant bleu turquoise
|
||||
Any dark green dye=N'importe quel colorant vert foncé
|
||||
Any dark grey dye=N'importe quel colorant gris foncé
|
||||
Any dye=N'importe quel colorant
|
||||
Any flower=N'importe quelle fleur
|
||||
Any glass=N'importe quel verre
|
||||
Any green dye=N'importe quel colorant vert
|
||||
Any green flower=N'importe quelle fleur verte
|
||||
Any grey dye=N'importe quel colorant gris
|
||||
Any item belonging to the groups: @1=Tout item appartenant aux groupes : @1
|
||||
Any leaves=N'importe quelles feuilles d'arbre
|
||||
Any magenta dye=N'importe quel colorant mauve
|
||||
Any mushroom=N'importe quel champignon
|
||||
Any orange dye=N'importe quel colorant orange
|
||||
Any orange flower=N'importe quelle fleur orange
|
||||
Any pink dye=N'importe quel colorant rose
|
||||
Any red dye=N'importe quel colorant rouge
|
||||
Any red flower=N'importe quelle fleur rouge
|
||||
Any sand=N'importe quel sable
|
||||
Any stick=N'importe quel bâton
|
||||
Any stone=N'importe quelle roche
|
||||
Any tree=N'importe quel tronc d'arbre
|
||||
Any vessel=N'importe quel couvert
|
||||
Any violet dye=N'importe quel colorant violet
|
||||
Any violet flower=N'importe quelle fleur violette
|
||||
Any white dye=N'importe quel colorant blanc
|
||||
Any white flower=N'importe quelle fleur blanche
|
||||
Any wood planks=N'importe quelles planches de bois
|
||||
Any wool=N'importe quelle laine
|
||||
Any yellow dye=N'importe quel colorant jaune
|
||||
Any yellow flower=N'importe quelle fleur jaune
|
||||
Armor=Armure
|
||||
Bag=Sac
|
||||
Bookmarks=Favoris
|
||||
Burning time: @1=Temps de combustion : @1
|
||||
Cannot mark this item. Bookmark limit reached.=
|
||||
Collect items to reveal more recipes=Collecter des items pour révéler des recettes
|
||||
Compress items=Compresser les items
|
||||
Cooking=Cuisson
|
||||
Cooking time: @1=Temps de cuisson : @1
|
||||
Craft (x@1)=Fabriquer (x@1)
|
||||
Digging=Minage
|
||||
Digging (by chance)=Minage (par chance)
|
||||
Heal=Guérison
|
||||
Inventory=Inventaire
|
||||
Items=Items
|
||||
Level=Niveau
|
||||
Mark this item=Ajouter aux favoris
|
||||
No item to show=Aucun item à montrer
|
||||
No recipes=Aucune recette
|
||||
No usages=Aucun usage
|
||||
Only drop if using one of these tools: @1=Tombe seulement en utilisant un de ces outils : @1
|
||||
Only drop if using this tool: @1=Tombe seulement en utilisant cet outil : @1
|
||||
Quick crafting=Fabrication rapide
|
||||
Recipe @1 of @2=Recette @1 sur @2
|
||||
Repairable by step of @1=Réparable par étape de @1
|
||||
Replaced by @1 on burning=Remplacé par @1 à la combustion
|
||||
Replaced by @1 on crafting=Remplacé par @1 à la fabrication
|
||||
Replaced by @1 on smelting=Remplacé par @1 à la cuisson
|
||||
Shapeless=Sans forme particulière
|
||||
Skins=Skins
|
||||
Sort items (A-Z)=Trier les items (A-Z)
|
||||
Sort items (Z-A)=Trier les items (Z-A)
|
||||
The inventory is extended by @1 slots=L'inventaire est étendu de @1 slots
|
||||
Trash all items=Détruire tous les items
|
||||
Unknown Item (@1)=Item inconnu (@1)
|
||||
Unmark this item=Enlever des favoris
|
||||
Usage @1 of @2=Usage @1 sur @2
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
# textdomain: i3
|
||||
|
||||
### init.lua ###
|
||||
|
||||
@1 added in your inventory=
|
||||
@1 new recipe(s) discovered!=
|
||||
@1 of chance to drop=
|
||||
@1 spawned=
|
||||
Achievements: @1 of @2 (@3)=
|
||||
Any black dye=
|
||||
Any black flower=
|
||||
Any blue dye=
|
||||
Any blue flower=
|
||||
Any brown dye=
|
||||
Any carpet=
|
||||
Any coal=
|
||||
Any cyan dye=
|
||||
Any dark green dye=
|
||||
Any dark grey dye=
|
||||
Any dye=
|
||||
Any flower=
|
||||
Any glass=
|
||||
Any green dye=
|
||||
Any green flower=
|
||||
Any grey dye=
|
||||
Any item belonging to the groups: @1=
|
||||
Any leaves=
|
||||
Any magenta dye=
|
||||
Any mushroom=
|
||||
Any orange dye=
|
||||
Any orange flower=
|
||||
Any pink dye=
|
||||
Any red dye=
|
||||
Any red flower=
|
||||
Any sand=
|
||||
Any stick=
|
||||
Any stone=
|
||||
Any tree=
|
||||
Any vessel=
|
||||
Any violet dye=
|
||||
Any violet flower=
|
||||
Any white dye=
|
||||
Any white flower=
|
||||
Any wood planks=
|
||||
Any wool=
|
||||
Any yellow dye=
|
||||
Any yellow flower=
|
||||
Armor=
|
||||
Bag=
|
||||
Bookmarks=
|
||||
Burning time: @1=
|
||||
Cannot mark this item. Bookmark limit reached.=
|
||||
Collect items to reveal more recipes=
|
||||
Compress items=
|
||||
Cooking=
|
||||
Cooking time: @1=
|
||||
Craft (x@1)=
|
||||
Digging=
|
||||
Digging (by chance)=
|
||||
Heal=
|
||||
Inventory=
|
||||
Items=
|
||||
Level=
|
||||
Mark this item=
|
||||
No item to show=
|
||||
No recipes=
|
||||
No usages=
|
||||
Only drop if using one of these tools: @1=
|
||||
Only drop if using this tool: @1=
|
||||
Quick crafting=
|
||||
Recipe @1 of @2=
|
||||
Repairable by step of @1=
|
||||
Replaced by @1 on burning=
|
||||
Replaced by @1 on crafting=
|
||||
Replaced by @1 on smelting=
|
||||
Shapeless=
|
||||
Skins=
|
||||
Sort items (A-Z)=
|
||||
Sort items (Z-A)=
|
||||
The inventory is extended by @1 slots=
|
||||
Trash all items=
|
||||
Unknown Item (@1)=
|
||||
Unmark this item=
|
||||
Usage @1 of @2=
|
|
@ -0,0 +1,3 @@
|
|||
name = i3
|
||||
description = Tiling inventory for Minetest
|
||||
optional_depends = 3d_armor, skinsdb, awards
|
|
@ -0,0 +1,2 @@
|
|||
# The progressive mode shows recipes you can craft from items you ever had in your inventory.
|
||||
i3_progressive_mode (Learn crafting recipes progressively) bool false
|
|
@ -0,0 +1,159 @@
|
|||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"X X",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#X",
|
||||
"X X",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X##",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X##",
|
||||
" ## ",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X##X",
|
||||
" ## ",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X##X#",
|
||||
" ## ",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X##X#X",
|
||||
" ## ",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X##X#X",
|
||||
" ## ",
|
||||
"#X#X#",
|
||||
"#X#X#",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
||||
|
||||
i3.register_craft({
|
||||
grid = {
|
||||
"X #",
|
||||
" ## ",
|
||||
"X#X#",
|
||||
"#X#X#",
|
||||
"X X##X#X",
|
||||
" ## ",
|
||||
"#X#X#",
|
||||
"#X#X#",
|
||||
"X #",
|
||||
},
|
||||
key = {
|
||||
['#'] = "default:wood",
|
||||
['X'] = "default:glass",
|
||||
},
|
||||
result = "default:mese 3",
|
||||
})
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"items": [
|
||||
"default:stone, default:stone, default:stone",
|
||||
"default:stone, , default:stone",
|
||||
"default:stone, default:stone, default:stone"
|
||||
],
|
||||
"result": "default:cobble 16"
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
i3.new_tab {
|
||||
name = "test1",
|
||||
description = "Test 1 Test 1",
|
||||
image = "i3_heart.png",
|
||||
|
||||
formspec = function(player, data, fs)
|
||||
fs("label[3,1;Test 1]")
|
||||
end,
|
||||
}
|
||||
|
||||
i3.new_tab {
|
||||
name = "test2",
|
||||
description = "Test 2",
|
||||
image = "i3_mesepick.png",
|
||||
|
||||
formspec = function(player, data, fs)
|
||||
fs("label[3,1;Test 2]")
|
||||
end,
|
||||
}
|
||||
|
||||
i3.new_tab {
|
||||
name = "test3",
|
||||
description = "Test 3",
|
||||
|
||||
access = function(player, data)
|
||||
local name = player:get_player_name()
|
||||
if name == "singleplayer" then
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
formspec = function(player, data, fs)
|
||||
fs("label[3,1;Test 3]")
|
||||
end,
|
||||
|
||||
fields = function(player, data, fields)
|
||||
i3.set_fs(player, "label[3,2;Test extra_fs]")
|
||||
end,
|
||||
}
|
||||
|
||||
i3.override_tab("test2", {
|
||||
name = "test2",
|
||||
description = "Test override",
|
||||
image = "i3_mesepick.png",
|
||||
|
||||
formspec = function(player, data, fs)
|
||||
fs("label[3,1;Override!]")
|
||||
end,
|
||||
})
|
After Width: | Height: | Size: 469 B |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 950 B |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 1.8 KiB |
|
@ -1,99 +0,0 @@
|
|||
# API definition to working together with smart_inventory
|
||||
|
||||
## Pages framework
|
||||
|
||||
### Register page
|
||||
To get own page in smart_inventory the next register method should be used
|
||||
```
|
||||
smart_inventory.register_page({
|
||||
name = string,
|
||||
icon = string,
|
||||
label = string,
|
||||
tooltip = string,
|
||||
smartfs_callback = function,
|
||||
sequence = number,
|
||||
on_button_click = function,
|
||||
is_visible_func = function,
|
||||
})
|
||||
```
|
||||
- name - unique short name, used for identification
|
||||
- icon - Image displayed on page button. Optional
|
||||
- label - Label displayed on page button. Optional
|
||||
- tooltip - Text displayed at mouseover on the page button. Optional
|
||||
- smartfs_callback(state) - smartfs callback function See [smartfs documentation](https://github.com/minetest-mods/smartfs/blob/master/docs) and existing pages implementations for reference.
|
||||
- sequence - The buttons are sorted by this number (crafting=10, creative=15, player=20)
|
||||
- on_button_click(state) - function called each page button click
|
||||
- is_visible_func(state) - function for dynamic page enabelling. Should return bool value.
|
||||
|
||||
### Get the definition for registered smart_inventory page
|
||||
```smart_inventory.get_registered_page(pagename)```
|
||||
|
||||
### Get smartfs state for players inventory
|
||||
```smart_inventory.get_player_state(playername)```
|
||||
Get the root smartfs state for players inventory. Note: In workbench mode the function return nil if the player does not have the form open
|
||||
|
||||
### Get smartfs state for a registered page in players inventory
|
||||
```smart_inventory.get_page_state(pagename, playername)```
|
||||
|
||||
## Filter framework
|
||||
Smart_inventory uses a filter-framework for dynamic grouping in creative and crafting page. The filter framework allow to register additional classify filters for beter dynamic grouping results.
|
||||
Maybe the framework will be moved to own mod in the feature if needed. Please note the smart_inventory caches all results at init time so static groups only allowed. The groups will not be re-checked at runtime.
|
||||
|
||||
### Register new filter
|
||||
```
|
||||
smart_inventory.filter.register_filter({
|
||||
name = string,
|
||||
check_item_by_def = function,
|
||||
get_description = function,
|
||||
get_keyword = function,
|
||||
is_valid = function,
|
||||
})
|
||||
```
|
||||
- name - unique filter name
|
||||
- check_item_by_def(fltobj, itemdef) - function to check the item classify by item definition. Item definition is the reference to minetest.registered_items[item] entry
|
||||
next return values allowed:
|
||||
- true -> direct (belongs to) assignment to the classify group named by filtername
|
||||
- string -> dimension, steps splitted by ":" (`a:b:c:d results in filtername, filtername:a, filtername:a:b, filtername:a:b:c, filtername:a:b:c:d`)
|
||||
- key/value table -> multiple groups assignment. Values could be dimensions as above (`{a,b} results in filtername, filtername:a, filtername:b`)
|
||||
- nil -> no group assingment by this filter
|
||||
- get_description(fltobj, group) - optional - get human readable description for the dimension string (`filtername:a:b:c`)
|
||||
- get_keyword(fltobj, group) - get string that should be used for searches or nil if the group should not used in for searches
|
||||
- is_valid(fltobj, groupname) - Check if the groupname is valid. By default all groups are valid
|
||||
|
||||
|
||||
### Filter Object methods
|
||||
|
||||
smart_inventory.filter.get(name) get filter object by registered name. Returns filter object fltobj
|
||||
- fltobj:check_item_by_name(itemname) classify by itemname (wrapper for check_item_by_def)
|
||||
- fltobj:check_item_by_def(def) classify by item definition
|
||||
- fltobj:get_description(group) get group description
|
||||
- fltobj:get_keyword(group) get string that should be used for searches
|
||||
|
||||
## Cache framework
|
||||
cache.register_on_cache_filled(function, parameter) - hook to call additional initializations after the cache is filled
|
||||
|
||||
|
||||
## Crecipes framework
|
||||
The should be used trough cache.register_on_cache_filled to be sure all items are already known
|
||||
crecipes.add_recipes_from_list(recipeslist) - Add Custom-Type Recipes to the smart inventory database
|
||||
|
||||
## Example usage for cache and crecipe
|
||||
```
|
||||
if minetest.global_exists("smart_inventory") then
|
||||
-- add grinder recipes to smart inventory database
|
||||
local crecipes = smart_inventory.crecipes
|
||||
local cache = smart_inventory.cache
|
||||
local function fill_citem_recipes()
|
||||
local recipelist = {}
|
||||
for _, e in ipairs(crushingfurnace_receipes) do
|
||||
table.insert(recipelist, {
|
||||
output = e[2],
|
||||
items = {e[1]},
|
||||
type = "grinding"
|
||||
})
|
||||
end
|
||||
crecipes.add_recipes_from_list(recipelist)
|
||||
end
|
||||
cache.register_on_cache_filled(fill_citem_recipes)
|
||||
end
|
||||
```
|
|
@ -1,165 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
|
@ -1,77 +0,0 @@
|
|||
# smart_inventory
|
||||
|
||||
## Overview
|
||||
A fast Minetest inventory with focus on a great number of items and big screens. The special feature of this inventory is the dynamic classification filters that allow fast searching and browsing trough available items and show relevant invormations only to the user.
|
||||
|
||||
The mod is organized in multiple pages, each page does have own focus and follow own vision.
|
||||
|
||||
## Crafting page
|
||||
![Screenshot](https://github.com/bell07/minetest-smart_inventory/blob/master/screenshot_crafting.png)
|
||||
The vision is to not affect the gameplay trough crafting helpers. The dynamic search helper display currently relevant craft recipes only based on inventory content by default.
|
||||
- Contains the usual player-, and crafting inventory
|
||||
- Additional view of "craftable items" based on players inventory content
|
||||
- Dynamic grouping of craftable items for better overview
|
||||
- Lookup field to get all recipes with item in it - with filter for revealed items if the doc system is used
|
||||
- Search field - with filter for revealed items if the doc system is used
|
||||
- Compress - use the stack max size in inventory
|
||||
- Sweep - move content of crafting inventory back to the main inventory
|
||||
|
||||
### Optional support for other mods
|
||||
doc_items - if the doc system is found the crafting page shows only items craftable by known (revealed) items.
|
||||
A lookup button is available on already known items to jump to the documntation entry
|
||||
|
||||
|
||||
## Creative page
|
||||
![Screenshot](https://github.com/bell07/minetest-smart_inventory/blob/master/screenshot_creative.png)
|
||||
The vision is to get items fast searchable and gettable
|
||||
- 3 dynamic filters + text search field for fast items search
|
||||
- Sort out "mass"-groups to a special "Shaped" group
|
||||
- just click to the item to get it in inventory
|
||||
- cleanup of inventory trough "Trash" field
|
||||
- clean whole inventory trough "Trash all" button
|
||||
- save and restore inventory content in 3x save slots
|
||||
|
||||
## Player page
|
||||
![Screenshot](https://github.com/bell07/minetest-smart_inventory/blob/master/screenshot_player.png)
|
||||
The vision is to get all skins and player customizations visual exposed.
|
||||
|
||||
### 3d_armor / clothing
|
||||
In creative mode all useable armor and clothing items available. The players inventory is not used in this mode. In survival only the armor and clothing from players inventory
|
||||
is shown.
|
||||
|
||||
### skins
|
||||
tested only with my fork https://github.com/bell07/minetest-skinsdb
|
||||
But it should be work with any fork that uses skins.skins[] and have *_preview.png files
|
||||
|
||||
## Doc page
|
||||
![Screenshot](https://github.com/bell07/minetest-smart_inventory/blob/master/screenshot_doc.png)
|
||||
The vision is to get all ingame documentation available in a fast way. So navigation from crafting page is possible directly to the doc_item entry
|
||||
The doc and doc_items mods required to get the page
|
||||
|
||||
|
||||
## Dependencies:
|
||||
Screen size at least 1024x768 / big screen. On my mobile with "full HD" it does not work.
|
||||
Minetest stable 0.4.15 or newer
|
||||
default mod (some graphics are used from this mod)
|
||||
|
||||
|
||||
|
||||
## Settings
|
||||
```
|
||||
#If enabled, the mod will show alternative human readable filterstrings if available.
|
||||
smart_inventory_friendly_group_names (Show “friendly” filter grouping names) bool true
|
||||
|
||||
#List of groups defined for special handling of "Shaped nodes" (Comma separated).
|
||||
#Items in this groups ignores the "not_in_inventory" group and are moved to separate "Shaped" category
|
||||
smart_inventory_shaped_groups (List of groups to be handled as separate) string carpet,door,fence,stair,slab,wall,micro,panel,slope,dye
|
||||
|
||||
#If enabled, the the mod does not replace other inventory mods.
|
||||
#The functionality is provided in a workbench.
|
||||
smart_inventory_workbench_mode (Use workbench instead of players inventory) bool false
|
||||
```
|
||||
|
||||
License: [LGPL-3](https://github.com/bell07/minetest-smart_inventory/blob/master/LICENSE)
|
||||
Textures:
|
||||
- Workbench: WTFPL (credits: to xdecor project)
|
||||
- Buttons: WTFPL (credits to Stix (Minetest-forum))
|
||||
- Arrow buttons: WTFPL (credits to daretmavi)
|
|
@ -1,6 +0,0 @@
|
|||
creative?
|
||||
sfinv?
|
||||
3d_armor?
|
||||
skinsdb?
|
||||
doc_items?
|
||||
unifieddyes?
|
|
@ -1,73 +0,0 @@
|
|||
smart_inventory.doc_items_mod = minetest.get_modpath("doc_items")
|
||||
|
||||
local doc_addon = {}
|
||||
|
||||
local doc_item_entries = {}
|
||||
|
||||
function doc_addon.is_revealed_item(itemname, playername)
|
||||
if not smart_inventory.doc_items_mod then
|
||||
return true
|
||||
end
|
||||
|
||||
doc_addon.get_category_list()
|
||||
itemname = minetest.registered_aliases[itemname] or itemname
|
||||
local doc_entry = doc_item_entries[itemname]
|
||||
if doc_entry then
|
||||
return doc.entry_revealed(playername, doc_entry.cid, doc_entry.eid)
|
||||
else
|
||||
-- unknown item
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function doc_addon.show(itemname, playername)
|
||||
if not smart_inventory.doc_items_mod then
|
||||
return
|
||||
end
|
||||
|
||||
doc_addon.get_category_list()
|
||||
itemname = minetest.registered_aliases[itemname] or itemname
|
||||
local doc_entry = doc_item_entries[itemname]
|
||||
if doc_entry then
|
||||
doc.mark_entry_as_viewed(playername, doc_entry.cid, doc_entry.eid)
|
||||
local state = smart_inventory.get_page_state("doc", playername)
|
||||
local codebox = state:get("code")
|
||||
codebox.edata = doc_entry
|
||||
doc.data.players[playername].galidx = 1
|
||||
codebox:submit() --update the page
|
||||
state.location.parentState:get("doc_button"):submit() -- switch to the tab
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Get sorted category list
|
||||
local doc_category_list = nil
|
||||
|
||||
function doc_addon.get_category_list()
|
||||
-- build on first usage
|
||||
if not doc_category_list and smart_inventory.doc_items_mod then
|
||||
doc_category_list = {}
|
||||
for _, category_name in ipairs(doc.data.category_order) do
|
||||
local category = doc.data.categories[category_name]
|
||||
if category then
|
||||
local entries_data = {}
|
||||
for _, eid in ipairs(doc.get_sorted_entry_names(category_name)) do
|
||||
local entry = doc.data.categories[category_name].entries[eid]
|
||||
if entry.data.itemstring and
|
||||
minetest.registered_items[entry.data.itemstring] and
|
||||
(entry.data.def == minetest.registered_items[entry.data.itemstring] or entry.data.def.door) then
|
||||
local edata = {cid = category_name, cid_data = category, eid = eid, data = entry}
|
||||
table.insert(entries_data, edata)
|
||||
doc_item_entries[entry.data.itemstring] = edata
|
||||
end
|
||||
end
|
||||
table.insert(doc_category_list, {cid = category_name, data = category, entries = entries_data})
|
||||
end
|
||||
end
|
||||
end
|
||||
return doc_category_list
|
||||
end
|
||||
|
||||
-------------------------
|
||||
return doc_addon
|
|
@ -1,31 +0,0 @@
|
|||
smart_inventory = {}
|
||||
smart_inventory.modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
local modpath = smart_inventory.modpath
|
||||
|
||||
-- load libs
|
||||
smart_inventory.txt = dofile(modpath.."/libs/simple_po_reader.lua")
|
||||
smart_inventory.smartfs = dofile(modpath.."/libs/smartfs.lua")
|
||||
smart_inventory.smartfs_elements = dofile(modpath.."/libs/smartfs-elements.lua")
|
||||
|
||||
smart_inventory.doc_addon = dofile(modpath.."/doc_addon.lua")
|
||||
|
||||
smart_inventory.filter = dofile(modpath.."/libs/filter.lua")
|
||||
smart_inventory.cache = dofile(modpath.."/libs/cache.lua")
|
||||
smart_inventory.crecipes = dofile(modpath.."/libs/crecipes.lua")
|
||||
smart_inventory.maininv = dofile(modpath.."/libs/maininv.lua")
|
||||
|
||||
smart_inventory.ui_tools = dofile(modpath.."/ui_tools.lua")
|
||||
-- register pages
|
||||
dofile(modpath.."/inventory_framework.lua")
|
||||
dofile(modpath.."/pages/crafting.lua")
|
||||
dofile(modpath.."/pages/creative.lua")
|
||||
dofile(modpath.."/pages/player.lua")
|
||||
dofile(modpath.."/pages/doc.lua")
|
||||
dofile(modpath.."/pages/awards.lua")
|
||||
|
||||
-- Cleanup inventories
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local player_name = player:get_player_name()
|
||||
minetest.remove_detached_inventory(player_name.."_crafting_inv")
|
||||
minetest.remove_detached_inventory(player_name.."_trash_inv")
|
||||
end)
|
|
@ -1,139 +0,0 @@
|
|||
local smartfs = smart_inventory.smartfs
|
||||
local maininv = smart_inventory.maininv
|
||||
local modpath = smart_inventory.modpath
|
||||
|
||||
-- smartfs callback
|
||||
local inventory_form = smartfs.create("smart_inventory:main", function(state)
|
||||
|
||||
-- enhanced object to the main inventory functions
|
||||
state.param.invobj = maininv.get(state.location.player)
|
||||
|
||||
-- Set language code
|
||||
local player_info = minetest.get_player_information(state.location.player)
|
||||
if player_info and player_info.lang_code ~= "" then
|
||||
state.lang_code = player_info.lang_code
|
||||
end
|
||||
|
||||
-- tabbed view controller
|
||||
local tab_controller = {
|
||||
_tabs = {},
|
||||
active_name = nil,
|
||||
set_active = function(self, tabname)
|
||||
for name, def in pairs(self._tabs) do
|
||||
if name == tabname then
|
||||
def.button:setBackground("halo.png")
|
||||
def.view:setVisible(true)
|
||||
else
|
||||
def.button:setBackground(nil)
|
||||
def.view:setVisible(false)
|
||||
end
|
||||
end
|
||||
self.active_name = tabname
|
||||
end,
|
||||
tab_add = function(self, name, def)
|
||||
def.viewstate:size(20,10) --size of tab view
|
||||
self._tabs[name] = def
|
||||
end,
|
||||
get_active_name = function(self)
|
||||
return self.active_name
|
||||
end,
|
||||
}
|
||||
|
||||
--set screen size
|
||||
state:size(20,12)
|
||||
state:label(1,0.2,"header","Smart Inventory")
|
||||
state:image(0,0,1,1,"header_logo", "logo.png")
|
||||
state:image_button(19,0,1,1,"exit", "","smart_inventory_exit_button.png", true):setTooltip("Close the inventory")
|
||||
local button_x = 0.1
|
||||
table.sort(smart_inventory.registered_pages, function(a,b)
|
||||
if not a.sequence then
|
||||
return false
|
||||
elseif not b.sequence then
|
||||
return true
|
||||
elseif a.sequence > b.sequence then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end)
|
||||
for _, def in ipairs(smart_inventory.registered_pages) do
|
||||
assert(def.smartfs_callback, "Callback function needed")
|
||||
assert(def.name, "Name is needed")
|
||||
if not def.is_visible_func or def.is_visible_func(state) then
|
||||
local tabdef = {}
|
||||
local label
|
||||
if not def.label then
|
||||
label = ""
|
||||
else
|
||||
label = def.label
|
||||
end
|
||||
tabdef.button = state:button(button_x,11.2,1,1,def.name.."_button",label)
|
||||
if def.icon then
|
||||
tabdef.button:setImage(def.icon)
|
||||
end
|
||||
tabdef.button:setTooltip(def.tooltip)
|
||||
tabdef.button:onClick(function(self)
|
||||
tab_controller:set_active(def.name)
|
||||
if def.on_button_click then
|
||||
def.on_button_click(tabdef.viewstate)
|
||||
end
|
||||
end)
|
||||
tabdef.view = state:container(0,1,def.name.."_container")
|
||||
tabdef.viewstate = tabdef.view:getContainerState()
|
||||
def.smartfs_callback(tabdef.viewstate)
|
||||
tab_controller:tab_add(def.name, tabdef)
|
||||
button_x = button_x + 1
|
||||
end
|
||||
end
|
||||
tab_controller:set_active(smart_inventory.registered_pages[1].name)
|
||||
end)
|
||||
|
||||
if minetest.settings:get_bool("smart_inventory_workbench_mode") then
|
||||
dofile(modpath.."/workbench.lua")
|
||||
smart_inventory.get_player_state = function(playername)
|
||||
-- check the inventory is shown
|
||||
local state = smartfs.opened[playername]
|
||||
if state and (not state.obsolete) and
|
||||
state.location.type == "player" and
|
||||
state.def.name == "smart_inventory:main" then
|
||||
return state
|
||||
end
|
||||
end
|
||||
else
|
||||
smartfs.set_player_inventory(inventory_form)
|
||||
smart_inventory.get_player_state = function(playername)
|
||||
return smartfs.inv[playername]
|
||||
end
|
||||
end
|
||||
|
||||
-- pages list
|
||||
smart_inventory.registered_pages = {}
|
||||
|
||||
-- add new page
|
||||
function smart_inventory.register_page(def)
|
||||
table.insert(smart_inventory.registered_pages, def)
|
||||
end
|
||||
|
||||
-- smart_inventory.get_player_state(playername) defined above
|
||||
|
||||
-- get state of active page
|
||||
function smart_inventory.get_page_state(pagename, playername)
|
||||
local rootstate = smart_inventory.get_player_state(playername)
|
||||
if not rootstate then
|
||||
return
|
||||
end
|
||||
local view = rootstate:get(pagename.."_container")
|
||||
if not view then
|
||||
return
|
||||
end
|
||||
return view:getContainerState()
|
||||
end
|
||||
|
||||
-- get definition of registered page
|
||||
function smart_inventory.get_registered_page(pagename)
|
||||
for _, registred_page in ipairs(smart_inventory.registered_pages) do
|
||||
if registred_page.name == pagename then
|
||||
return registred_page
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,139 +0,0 @@
|
|||
local filter = smart_inventory.filter
|
||||
|
||||
local cache = {}
|
||||
cache.cgroups = {} -- cache groups
|
||||
cache.itemgroups = {} -- raw item groups for recipe checks
|
||||
cache.citems = {}
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Add an Item to the cache
|
||||
-----------------------------------------------------
|
||||
function cache.add_item(item_def)
|
||||
|
||||
-- already in cache. Skip duplicate processing
|
||||
if cache.citems[item_def.name] then
|
||||
return
|
||||
end
|
||||
|
||||
-- fill raw groups cache for recipes
|
||||
for group, value in pairs(item_def.groups) do
|
||||
cache.itemgroups[group] = cache.itemgroups[group] or {}
|
||||
cache.itemgroups[group][item_def.name] = item_def
|
||||
end
|
||||
|
||||
local entry = {
|
||||
name = item_def.name,
|
||||
in_output_recipe = {},
|
||||
in_craft_recipe = {},
|
||||
cgroups = {}
|
||||
}
|
||||
cache.citems[item_def.name] = entry
|
||||
-- classify the item
|
||||
for _, flt in pairs(filter.registered_filter) do
|
||||
local filter_result = flt:check_item_by_def(item_def)
|
||||
if filter_result then
|
||||
if filter_result == true then
|
||||
cache.assign_to_group(flt.name, item_def, flt)
|
||||
else
|
||||
if type(filter_result) ~= "table" then
|
||||
if tonumber(filter_result) ~= nil then
|
||||
filter_result = {[flt.name..":"..filter_result] = true}
|
||||
else
|
||||
filter_result = {[filter_result] = true}
|
||||
end
|
||||
end
|
||||
for key, val in pairs(filter_result) do
|
||||
local filter_entry = tostring(key)
|
||||
if val ~= true then
|
||||
filter_entry = filter_entry..":"..tostring(val)
|
||||
end
|
||||
cache.assign_to_group(filter_entry, item_def, flt)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Add a item to cache group
|
||||
-----------------------------------------------------
|
||||
function cache.assign_to_group(group_name, itemdef, flt)
|
||||
|
||||
-- check and build filter chain
|
||||
local abs_group
|
||||
local parent_ref
|
||||
local parent_stringpos
|
||||
|
||||
for rel_group in group_name:gmatch("[^:]+") do
|
||||
-- get parent relation and absolute path
|
||||
if abs_group then
|
||||
parent_ref = cache.cgroups[abs_group]
|
||||
parent_stringpos = string.len(abs_group)+2
|
||||
abs_group = abs_group..":"..rel_group
|
||||
else
|
||||
abs_group = rel_group
|
||||
end
|
||||
if flt:is_valid(abs_group) then
|
||||
-- check if group is new, create it
|
||||
if not cache.cgroups[abs_group] then
|
||||
if parent_ref then
|
||||
parent_ref.childs[abs_group] = string.sub(group_name, parent_stringpos)
|
||||
end
|
||||
local group = {
|
||||
name = abs_group,
|
||||
items = {},
|
||||
parent = parent_ref,
|
||||
childs = {},
|
||||
}
|
||||
group.group_desc = flt:get_description(group)
|
||||
group.keyword = flt:get_keyword(group)
|
||||
cache.cgroups[abs_group] = group
|
||||
end
|
||||
|
||||
-- set relation
|
||||
cache.cgroups[abs_group].items[itemdef.name] = itemdef
|
||||
cache.citems[itemdef.name].cgroups[abs_group] = cache.cgroups[abs_group]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Hook / Event for further initializations of the cache is filled
|
||||
-----------------------------------------------------
|
||||
cache.registered_on_cache_filled = {}
|
||||
function cache.register_on_cache_filled(func, ...)
|
||||
assert(type(func) == "function", "register_on_cache_filled needs a function")
|
||||
table.insert(cache.registered_on_cache_filled, { func = func, opt = {...}})
|
||||
end
|
||||
|
||||
local function process_on_cache_filled()
|
||||
for _, hook in ipairs(cache.registered_on_cache_filled) do
|
||||
hook.func(unpack(hook.opt))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Fill the cache at init
|
||||
-----------------------------------------------------
|
||||
local function fill_cache()
|
||||
local shape_filter = filter.get("shape")
|
||||
for _, def in pairs(minetest.registered_items) do
|
||||
|
||||
-- build groups and items cache
|
||||
if def.description and def.description ~= "" and
|
||||
(not def.groups.not_in_creative_inventory or shape_filter:check_item_by_def(def)) then
|
||||
cache.add_item(def)
|
||||
end
|
||||
end
|
||||
|
||||
-- call hooks
|
||||
minetest.after(0, process_on_cache_filled)
|
||||
end
|
||||
minetest.after(0, fill_cache)
|
||||
|
||||
-----------------------------------------------------
|
||||
-- return the reference to the mod
|
||||
-----------------------------------------------------
|
||||
return cache
|
|
@ -1,400 +0,0 @@
|
|||
local doc_addon = smart_inventory.doc_addon
|
||||
local cache = smart_inventory.cache
|
||||
local filter = smart_inventory.filter
|
||||
|
||||
local crecipes = {}
|
||||
crecipes.crecipes = {} --list of all recipes
|
||||
|
||||
-----------------------------------------------------
|
||||
-- crecipe: Class
|
||||
-----------------------------------------------------
|
||||
local crecipe_class = {}
|
||||
local crecipe_class_mt = {__index = crecipe_class}
|
||||
crecipes.crecipe_class = crecipe_class
|
||||
|
||||
-----------------------------------------------------
|
||||
-- crecipes: analyze all data. Return false if invalid recipe. true on success
|
||||
-----------------------------------------------------
|
||||
function crecipe_class:analyze()
|
||||
-- check recipe output
|
||||
|
||||
if self._recipe.type == "cooking" then
|
||||
return false --fuel not supported
|
||||
end
|
||||
|
||||
if self._recipe.output == "" then
|
||||
minetest.log("[smartfs_inventory] broken recipe without output "..dump(self._recipe))
|
||||
return false
|
||||
end
|
||||
|
||||
local outstack = ItemStack(self._recipe.output)
|
||||
if outstack:get_meta():get_int("palette_index") > 0 then
|
||||
minetest.log("verbose", "[smartfs_inventory] ignore unifieddyes recipe "..self._recipe.output)
|
||||
return -- not supported
|
||||
end
|
||||
|
||||
self.out_item = outstack:get_definition()
|
||||
|
||||
if not self.out_item or not self.out_item.name then
|
||||
minetest.log("[smartfs_inventory] unknown recipe result "..self._recipe.output)
|
||||
return false
|
||||
end
|
||||
|
||||
-- check recipe items/groups
|
||||
for _, recipe_item in pairs(self._recipe.items) do
|
||||
if recipe_item ~= "" then
|
||||
if self._items[recipe_item] then
|
||||
self._items[recipe_item].count = self._items[recipe_item].count + 1
|
||||
else
|
||||
self._items[recipe_item] = {count = 1}
|
||||
end
|
||||
end
|
||||
end
|
||||
for recipe_item, iteminfo in pairs(self._items) do
|
||||
if recipe_item:sub(1, 6) ~= "group:" then
|
||||
local itemname = minetest.registered_aliases[recipe_item] or recipe_item
|
||||
if minetest.registered_items[itemname] then
|
||||
iteminfo.items = {[itemname] = minetest.registered_items[itemname]}
|
||||
else
|
||||
minetest.log("[smartfs_inventory] unknown item in recipe: "..itemname.." for result "..self.out_item.name)
|
||||
return false
|
||||
end
|
||||
else
|
||||
local retitems
|
||||
for groupname in string.gmatch(recipe_item:sub(7), '([^,]+)') do
|
||||
if not retitems then --first entry
|
||||
if cache.itemgroups[groupname] then
|
||||
retitems = {}
|
||||
for k,v in pairs(cache.itemgroups[groupname]) do
|
||||
retitems[k] = v
|
||||
end
|
||||
else
|
||||
minetest.log("[smartfs_inventory] unknown group description in recipe: "..recipe_item.." / "..groupname.." for result "..self.out_item.name)
|
||||
return false
|
||||
end
|
||||
else
|
||||
for itemname, itemdef in pairs(retitems) do
|
||||
if not minetest.registered_items[itemname].groups[groupname] then
|
||||
retitems[itemname] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
if not retitems or not next(retitems) then
|
||||
minetest.log("[smartfs_inventory] no items matches group: "..recipe_item.." for result "..self.out_item.name)
|
||||
return false
|
||||
end
|
||||
end
|
||||
iteminfo.items = retitems
|
||||
end
|
||||
end
|
||||
|
||||
-- invalid recipe
|
||||
if not self._items then
|
||||
minetest.log("[smartfs_inventory] skip recipe for: "..recipe_item)
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- crecipes: Check if the recipe is revealed to the player
|
||||
-----------------------------------------------------
|
||||
function crecipe_class:is_revealed(playername, recursiv_checked_items)
|
||||
local recipe_valid = true
|
||||
for _, entry in pairs(self._items) do
|
||||
recipe_valid = false
|
||||
for _, itemdef in pairs(entry.items) do
|
||||
if doc_addon.is_revealed_item(itemdef.name, playername) then
|
||||
recipe_valid = true
|
||||
break
|
||||
end
|
||||
|
||||
if cache.citems[itemdef.name].cgroups["shape"] then -- Check shapes recursive
|
||||
recursiv_checked_items = recursiv_checked_items or {}
|
||||
for _, recipe in ipairs(cache.citems[itemdef.name].in_output_recipe) do
|
||||
local crecipe = crecipes.crecipes[recipe]
|
||||
if recursiv_checked_items[crecipe.out_item.name] == nil then
|
||||
recursiv_checked_items[crecipe.out_item.name] = false --avoid re-recursion
|
||||
recursiv_checked_items[crecipe.out_item.name] = crecipe:is_revealed(playername, recursiv_checked_items)
|
||||
end
|
||||
if recursiv_checked_items[crecipe.out_item.name] == true then
|
||||
recipe_valid = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if recipe_valid then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not recipe_valid then
|
||||
break
|
||||
end
|
||||
end
|
||||
return recipe_valid
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- crecipes: Returns recipe without groups, with replacements
|
||||
-----------------------------------------------------
|
||||
function crecipe_class:get_with_placeholder(playername, inventory_tab)
|
||||
local recipe = {}
|
||||
for k, v in pairs(self._recipe) do
|
||||
recipe[k] = v
|
||||
end
|
||||
recipe.items = {}
|
||||
for k, v in pairs(self._recipe.items) do
|
||||
recipe.items[k] = v
|
||||
end
|
||||
|
||||
local recursiv_checked_items = {}
|
||||
if inventory_tab then
|
||||
for k, v in pairs(inventory_tab) do
|
||||
recursiv_checked_items[k] = v
|
||||
end
|
||||
end
|
||||
self:is_revealed(playername, recursiv_checked_items) -- enhance recursiv_checked_items
|
||||
|
||||
for key, recipe_item in pairs(recipe.items) do
|
||||
local item
|
||||
|
||||
-- Check for matching item in inventory and revealed cache
|
||||
if inventory_tab then
|
||||
local itemcount = 0
|
||||
for _, item_in_list in pairs(self._items[recipe_item].items) do
|
||||
local in_inventory = inventory_tab[item_in_list.name]
|
||||
if in_inventory == true then
|
||||
item = item_in_list.name
|
||||
break
|
||||
elseif in_inventory and in_inventory > itemcount then
|
||||
item = item_in_list.name
|
||||
itemcount = in_inventory
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- second try, revealed by recipe item
|
||||
if not item then
|
||||
for _, item_in_list in pairs(self._items[recipe_item].items) do
|
||||
if recursiv_checked_items[item_in_list.name] then
|
||||
item = item_in_list.name
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- third try, get any revealed item
|
||||
if not item then
|
||||
for _, item_in_list in pairs(self._items[recipe_item].items) do
|
||||
if doc_addon.is_revealed_item(item_in_list.name, playername) then
|
||||
item = item_in_list.name
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- last try, just get one item
|
||||
if not item and self._items[recipe_item].items[1] then
|
||||
item = self._items[recipe_item].items[1].name
|
||||
end
|
||||
|
||||
-- set recipe item
|
||||
if item then
|
||||
if recipe_item ~= item then
|
||||
recipe.items[key] = {
|
||||
item = item,
|
||||
tooltip = recipe_item,
|
||||
text = 'G',
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
return recipe
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- crecipes: Check if recipe contains only items provided in reference_items
|
||||
-----------------------------------------------------
|
||||
function crecipe_class:is_craftable_by_items(reference_items)
|
||||
local item_ok = false
|
||||
for _, entry in pairs(self._items) do
|
||||
item_ok = false
|
||||
for _, itemdef in pairs(entry.items) do
|
||||
if reference_items[itemdef.name] then
|
||||
item_ok = true
|
||||
end
|
||||
end
|
||||
if item_ok == false then
|
||||
break
|
||||
end
|
||||
end
|
||||
return item_ok
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- crecipes: Check if the items placed in grid matches the recipe
|
||||
-----------------------------------------------------
|
||||
function crecipe_class:check_craftable_by_grid(grid)
|
||||
-- only "normal" recipes supported
|
||||
if self.recipe_type ~= "normal" then
|
||||
return false
|
||||
end
|
||||
|
||||
for i = 1, 9 do
|
||||
local grid_item = grid[i]:get_name()
|
||||
-- check only fields filled in crafting grid
|
||||
if grid_item and grid_item ~= "" then
|
||||
-- check if item defined in recipe at this place
|
||||
local item_ok = false
|
||||
local recipe_item
|
||||
-- default case - 3x3 crafting grid
|
||||
local width = self._recipe.width
|
||||
if not width or width == 0 or width == 3 then
|
||||
recipe_item = self._recipe.items[i]
|
||||
else
|
||||
-- complex case - recalculate to the 3x3 crafting grid
|
||||
local x = math.fmod((i-1),3)+1
|
||||
if x <= width then
|
||||
local y = math.floor((i-1)/3+1)
|
||||
local coord = (y-1)*width+x
|
||||
recipe_item = self._recipe.items[coord]
|
||||
else
|
||||
recipe_item = ""
|
||||
end
|
||||
end
|
||||
|
||||
if not recipe_item or recipe_item == "" then
|
||||
return false
|
||||
end
|
||||
|
||||
-- check if it is a compatible item
|
||||
for _, itemdef in pairs(self._items[recipe_item].items) do
|
||||
if itemdef.name == grid_item then
|
||||
item_ok = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not item_ok then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Recipe object Constructor
|
||||
-----------------------------------------------------
|
||||
function crecipes.new(recipe)
|
||||
local self = setmetatable({}, crecipe_class_mt)
|
||||
-- self.out_item = nil
|
||||
self._recipe = recipe
|
||||
self.recipe_type = recipe.type
|
||||
self._items = {}
|
||||
return self
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Get all revealed recipes with at least one item in reference_items table
|
||||
-----------------------------------------------------
|
||||
function crecipes.get_revealed_recipes_with_items(playername, reference_items)
|
||||
local recipelist = {}
|
||||
local revealed_items_cache = {}
|
||||
for itemname, _ in pairs(reference_items) do
|
||||
if cache.citems[itemname] and cache.citems[itemname].in_craft_recipe then
|
||||
for _, recipe in ipairs(cache.citems[itemname].in_craft_recipe) do
|
||||
local crecipe = crecipes.crecipes[recipe]
|
||||
if crecipe and crecipe:is_revealed(playername, revealed_items_cache) then
|
||||
recipelist[recipe] = crecipe
|
||||
end
|
||||
-- lookup one step forward for shapes
|
||||
if cache.citems[crecipe.out_item.name].cgroups["shape"] then
|
||||
for _, recipe2 in ipairs(cache.citems[crecipe.out_item.name].in_craft_recipe) do
|
||||
local crecipe = crecipes.crecipes[recipe2]
|
||||
if crecipe and crecipe:is_revealed(playername, revealed_items_cache) then
|
||||
recipelist[recipe2] = crecipe
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if cache.citems[itemname] and cache.citems[itemname].in_output_recipe then
|
||||
for _, recipe in ipairs(cache.citems[itemname].in_output_recipe) do
|
||||
local crecipe = crecipes.crecipes[recipe]
|
||||
if crecipe and crecipe:is_revealed(playername, revealed_items_cache) then
|
||||
recipelist[recipe] = crecipe
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return recipelist
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Get all recipes with all required items in reference items
|
||||
-----------------------------------------------------
|
||||
function crecipes.get_recipes_craftable(playername, reference_items)
|
||||
local all = crecipes.get_revealed_recipes_with_items(playername, reference_items)
|
||||
local craftable = {}
|
||||
for recipe, crecipe in pairs(all) do
|
||||
if crecipe:is_craftable_by_items(reference_items) then
|
||||
craftable[recipe] = crecipe
|
||||
end
|
||||
end
|
||||
return craftable
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Get all recipes that match to already placed items on crafting grid
|
||||
-----------------------------------------------------
|
||||
function crecipes.get_recipes_started_craft(playername, grid, reference_items)
|
||||
local all = crecipes.get_revealed_recipes_with_items(playername, reference_items)
|
||||
local craftable = {}
|
||||
for recipe, crecipe in pairs(all) do
|
||||
if crecipe:check_craftable_by_grid(grid) then
|
||||
craftable[recipe] = crecipe
|
||||
end
|
||||
end
|
||||
return craftable
|
||||
end
|
||||
|
||||
function crecipes.add_recipes_from_list(recipelist)
|
||||
if recipelist then
|
||||
for _, recipe in ipairs(recipelist) do
|
||||
local recipe_obj = crecipes.new(recipe)
|
||||
if recipe_obj:analyze() then
|
||||
-- probably hidden therefore not indexed previous. But Items with recipe should be allways visible
|
||||
cache.add_item(minetest.registered_items[recipe_obj.out_item.name])
|
||||
table.insert(cache.citems[recipe_obj.out_item.name].in_output_recipe, recipe)
|
||||
crecipes.crecipes[recipe] = recipe_obj
|
||||
if recipe_obj.recipe_type ~= "normal" then
|
||||
cache.assign_to_group("recipetype:"..recipe_obj.recipe_type, recipe_obj.out_item, filter.get("recipetype"))
|
||||
end
|
||||
for _, entry in pairs(recipe_obj._items) do
|
||||
for itemname, itemdef in pairs(entry.items) do
|
||||
cache.add_item(itemdef) -- probably hidden therefore not indexed previous. But Items with recipe should be allways visible
|
||||
table.insert(cache.citems[itemdef.name].in_craft_recipe, recipe)
|
||||
cache.assign_to_group("ingredient:"..itemdef.name, recipe_obj.out_item, filter.get("ingredient"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Fill the recipes cache at init
|
||||
-----------------------------------------------------
|
||||
local function fill_recipe_cache()
|
||||
for itemname, _ in pairs(minetest.registered_items) do
|
||||
crecipes.add_recipes_from_list(minetest.get_all_craft_recipes(itemname))
|
||||
end
|
||||
for itemname, _ in pairs(minetest.registered_aliases) do
|
||||
crecipes.add_recipes_from_list(minetest.get_all_craft_recipes(itemname))
|
||||
end
|
||||
end
|
||||
-- register to process after cache is filled
|
||||
cache.register_on_cache_filled(fill_recipe_cache)
|
||||
|
||||
return crecipes
|
|
@ -1,409 +0,0 @@
|
|||
local txt = smart_inventory.txt
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- Filter class
|
||||
--------------------------------------------------------------
|
||||
local filter_class = {}
|
||||
local filter_class_mt = {__index = filter_class}
|
||||
|
||||
function filter_class:check_item_by_name(itemname)
|
||||
if minetest.registered_items[itemname] then
|
||||
return self:check_item_by_def(minetest.registered_items[itemname])
|
||||
end
|
||||
end
|
||||
|
||||
function filter_class:check_item_by_def(def)
|
||||
error("check_item_by_def needs redefinition:"..debug.traceback())
|
||||
end
|
||||
|
||||
function filter_class:_get_description(group)
|
||||
if txt then
|
||||
if txt[group.name] then
|
||||
return txt[group.name].." ("..group.name..")"
|
||||
elseif group.parent and group.parent.childs[group.name] and txt[group.parent.name] then
|
||||
return txt[group.parent.name].." "..group.parent.childs[group.name].." ("..group.name..")"
|
||||
else
|
||||
return group.name
|
||||
end
|
||||
else
|
||||
return group.name
|
||||
end
|
||||
end
|
||||
filter_class.get_description = filter_class._get_description
|
||||
|
||||
function filter_class:_get_keyword(group)
|
||||
return group.group_desc
|
||||
end
|
||||
|
||||
filter_class.get_keyword = filter_class._get_keyword
|
||||
|
||||
function filter_class:is_valid(group)
|
||||
return true
|
||||
end
|
||||
|
||||
local filter = {}
|
||||
filter.registered_filter = {}
|
||||
|
||||
function filter.get(name)
|
||||
return filter.registered_filter[name]
|
||||
end
|
||||
|
||||
function filter.register_filter(def)
|
||||
assert(def.name, "filter needs a name")
|
||||
assert(def.check_item_by_def, "filter function check_item_by_def required")
|
||||
assert(not filter.registered_filter[def.name], "filter already exists")
|
||||
setmetatable(def, filter_class_mt)
|
||||
filter.registered_filter[def.name] = def
|
||||
end
|
||||
|
||||
|
||||
-- rename groups for beter consistency
|
||||
filter.group_rename = {
|
||||
customnode_default = "customnode",
|
||||
}
|
||||
|
||||
-- group configurations per basename
|
||||
-- true means is dimension
|
||||
-- 1 means replace the base only ("food_choco_powder" => food:choco_powder")
|
||||
filter.base_group_config = {
|
||||
armor = true,
|
||||
physics = true,
|
||||
basecolor = true,
|
||||
excolor = true,
|
||||
color = true,
|
||||
unicolor = true,
|
||||
food = 1,
|
||||
customnode = true,
|
||||
}
|
||||
|
||||
-- hide this groups
|
||||
filter.group_hide_config = {
|
||||
armor_count = true,
|
||||
not_in_creative_inventory = false,
|
||||
}
|
||||
|
||||
-- value of this group will be recalculated to %
|
||||
filter.group_wear_config = {
|
||||
armor_use = true,
|
||||
}
|
||||
|
||||
-- Ususally 1 means true for group values. This is an exceptions table for this rule
|
||||
filter.group_with_value_1_config = {
|
||||
oddly_breakable_by_hand = true,
|
||||
}
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- Filter group
|
||||
--------------------------------------------------------------
|
||||
filter.register_filter({
|
||||
name = "group",
|
||||
check_item_by_def = function(self, def)
|
||||
local ret = {}
|
||||
for k_orig, v in pairs(def.groups) do
|
||||
local k = filter.group_rename[k_orig] or k_orig
|
||||
local mk, mv
|
||||
|
||||
-- Check group base
|
||||
local basename
|
||||
for z in k:gmatch("[^_]+") do
|
||||
basename = z
|
||||
break
|
||||
end
|
||||
local basegroup_config = filter.base_group_config[basename]
|
||||
if basegroup_config == true then
|
||||
mk = string.gsub(k, "_", ":")
|
||||
elseif basegroup_config == 1 then
|
||||
mk = string.gsub(k, "^"..basename.."_", basename..":")
|
||||
else
|
||||
mk = k
|
||||
end
|
||||
|
||||
-- stack wear related value
|
||||
if filter.group_wear_config[k] then
|
||||
mv = tostring(math.floor(v / 65535 * 10000 + 0.5)/100).." %"
|
||||
-- value-expandable groups
|
||||
elseif v ~= 1 or k == filter.group_with_value_1_config[k] then
|
||||
mv = v
|
||||
else
|
||||
mv = true
|
||||
end
|
||||
|
||||
if v ~= 0 and mk and not filter.group_hide_config[k] then
|
||||
ret[mk] = mv
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end,
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = "type",
|
||||
check_item_by_def = function(self, def)
|
||||
return self.name..":"..def.type
|
||||
end,
|
||||
get_keyword = function(self, group)
|
||||
if group.name ~= self.name then
|
||||
return group.parent.childs[group.name]
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = "mod",
|
||||
check_item_by_def = function(self, def)
|
||||
if def.mod_origin then
|
||||
return self.name..":"..def.mod_origin
|
||||
end
|
||||
end,
|
||||
get_keyword = function(self, group)
|
||||
if group.name ~= self.name then
|
||||
return group.parent.childs[group.name]
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = "translucent",
|
||||
check_item_by_def = function(self, def)
|
||||
if def.sunlight_propagates ~= 0 then
|
||||
return def.sunlight_propagates
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = "light",
|
||||
check_item_by_def = function(self, def)
|
||||
if def.light_source ~= 0 then
|
||||
return def.light_source
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = "metainv",
|
||||
check_item_by_def = function(self, def)
|
||||
if def.allow_metadata_inventory_move or
|
||||
def.allow_metadata_inventory_take or
|
||||
def.allow_metadata_inventory_put or
|
||||
def.on_metadata_inventory_move or
|
||||
def.on_metadata_inventory_take or
|
||||
def.on_metadata_inventory_put then
|
||||
return true
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
--[[ does it sense to filter them? I cannot define the human readable groups for them
|
||||
filter.register_filter({
|
||||
name = "drawtype",
|
||||
check_item_by_def = function(self, def)
|
||||
if def.drawtype ~= "normal" then
|
||||
return def.drawtype
|
||||
end
|
||||
end,
|
||||
})
|
||||
]]
|
||||
|
||||
local shaped_groups = {}
|
||||
local shaped_list = minetest.setting_get("smart_inventory_shaped_groups") or "carpet,door,fence,stair,slab,wall,micro,panel,slope"
|
||||
if shaped_list then
|
||||
for z in shaped_list:gmatch("[^,]+") do
|
||||
shaped_groups[z] = true
|
||||
end
|
||||
end
|
||||
|
||||
filter.register_filter({
|
||||
name = "shape",
|
||||
check_item_by_def = function(self, def)
|
||||
local door_groups
|
||||
if shaped_groups["door"] then
|
||||
local door_filter = filter.get("door")
|
||||
door_groups = door_filter:check_item_by_def(def)
|
||||
if door_groups and door_groups.door then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(def.groups) do
|
||||
if k ~= "door" and shaped_groups[k] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
--[[ disabled since debug.getupvalue is not usable to secure environment
|
||||
filter.register_filter({
|
||||
name = "food",
|
||||
check_item_by_def = function(self, def)
|
||||
if def.on_use then
|
||||
local name,change=debug.getupvalue(def.on_use, 1)
|
||||
if name~=nil and name=="hp_change" and change > 0 then
|
||||
return tostring(change)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = "toxic",
|
||||
check_item_by_def = function(self, def)
|
||||
if def.on_use then
|
||||
local name,change=debug.getupvalue(def.on_use, 1)
|
||||
if name~=nil and name=="hp_change" and change < 0 then
|
||||
return tostring(change)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
]]
|
||||
|
||||
filter.register_filter({
|
||||
name = "tool",
|
||||
check_item_by_def = function(self, def)
|
||||
if not def.tool_capabilities then
|
||||
return
|
||||
end
|
||||
local rettab = {}
|
||||
for k, v in pairs(def.tool_capabilities) do
|
||||
if type(v) ~= "table" and v ~= 0 then
|
||||
rettab["tool:"..k] = v
|
||||
end
|
||||
end
|
||||
if def.tool_capabilities.damage_groups then
|
||||
for k, v in pairs(def.tool_capabilities.damage_groups) do
|
||||
if v ~= 0 then
|
||||
rettab["damage:"..k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
--[[ disabled, I cannot find right human readable interpretation for this
|
||||
if def.tool_capabilities.groupcaps then
|
||||
for groupcap, gdef in pairs(def.tool_capabilities.groupcaps) do
|
||||
for k, v in pairs(gdef) do
|
||||
if type(v) ~= "table" then
|
||||
rettab["groupcaps:"..groupcap..":"..k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
]]
|
||||
return rettab
|
||||
end,
|
||||
get_keyword = function(self, group)
|
||||
if group.name == "tool" or group.name == "damage" then
|
||||
return nil
|
||||
else
|
||||
return self:_get_keyword(group)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = "armor",
|
||||
check_item_by_def = function(self, def)
|
||||
return def.armor_groups
|
||||
end,
|
||||
})
|
||||
|
||||
filter.register_filter({
|
||||
name = 'clothing_cape',
|
||||
check_item_by_def = function(self, def)
|
||||
if def.groups.cape then
|
||||
return 'clothing'
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
-- Burn times
|
||||
filter.register_filter({
|
||||
name = "fuel",
|
||||
check_item_by_def = function(self, def)
|
||||
local burntime = minetest.get_craft_result({method="fuel",width=1,items={def.name}}).time
|
||||
if burntime > 0 then
|
||||
return "fuel:"..burntime
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
-- Group assignment done in cache framework internally
|
||||
filter.register_filter({
|
||||
name = "recipetype",
|
||||
check_item_by_def = function(self, def) end,
|
||||
get_keyword = function(self, group)
|
||||
if group.name ~= self.name then
|
||||
return group.parent.childs[group.name]
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- Group assignment done in cache framework internally
|
||||
filter.register_filter({
|
||||
name = "ingredient",
|
||||
check_item_by_def = function(self, def) end,
|
||||
get_description = function(self, group)
|
||||
local itemname = group.name:sub(12)
|
||||
if txt and txt["ingredient"] and
|
||||
minetest.registered_items[itemname] and minetest.registered_items[itemname].description then
|
||||
return txt["ingredient"] .." "..minetest.registered_items[itemname].description.." ("..group.name..")"
|
||||
else
|
||||
return group.name
|
||||
end
|
||||
end,
|
||||
get_keyword = function(self, group)
|
||||
-- not searchable by ingedient
|
||||
return nil
|
||||
end,
|
||||
is_valid = function(self, groupname)
|
||||
local itemname = groupname:sub(12)
|
||||
if itemname ~= "" and minetest.registered_items[itemname] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
local door_groups
|
||||
local function fill_door_groups()
|
||||
door_groups = {}
|
||||
for _, extend_def in pairs(minetest.registered_items) do
|
||||
local base_def
|
||||
if extend_def.groups and extend_def.groups.door then
|
||||
if extend_def.door then
|
||||
base_def = minetest.registered_items[extend_def.door.name]
|
||||
elseif extend_def.drop and type(extend_def.drop) == "string" then
|
||||
base_def = minetest.registered_items[extend_def.drop]
|
||||
end
|
||||
end
|
||||
if base_def then
|
||||
door_groups[base_def.name] = extend_def
|
||||
door_groups[extend_def.name] = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
filter.register_filter({
|
||||
name = "door",
|
||||
check_item_by_def = function(self, def)
|
||||
if not door_groups then
|
||||
fill_door_groups()
|
||||
end
|
||||
if not door_groups[def.name] then
|
||||
return
|
||||
end
|
||||
|
||||
local group_filter = filter.get("group")
|
||||
local ret = group_filter:check_item_by_def(door_groups[def.name])
|
||||
if ret then
|
||||
ret["not_in_creative_inventory"] = nil
|
||||
return ret
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
----------------
|
||||
return filter
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
-- Enhanced main inventory methods
|
||||
local maininvClass = {}
|
||||
maininvClass_mt = {__index = maininvClass}
|
||||
|
||||
-- Clear the inventory
|
||||
function maininvClass:remove_all()
|
||||
for idx = 1, self.inventory:get_size("main") do
|
||||
self.inventory:set_stack("main", idx, "")
|
||||
end
|
||||
end
|
||||
|
||||
-- Save inventory content to a slot (file)
|
||||
function maininvClass:save_to_slot(slot)
|
||||
local savedata = {}
|
||||
for idx, stack in ipairs(self.inventory:get_list("main")) do
|
||||
if not stack:is_empty() then
|
||||
savedata[idx] = stack:to_string()
|
||||
end
|
||||
end
|
||||
|
||||
local player = minetest.get_player_by_name(self.playername)
|
||||
player:set_attribute("inv_save_slot_"..tostring(slot), minetest.serialize(savedata))
|
||||
end
|
||||
|
||||
-- Get restore the inventory content from a slot (file)
|
||||
function maininvClass:restore_from_slot(slot)
|
||||
local player = minetest.get_player_by_name(self.playername)
|
||||
local savedata = minetest.deserialize(player:get_attribute("inv_save_slot_"..tostring(slot)))
|
||||
if savedata then
|
||||
for idx = 1, self.inventory:get_size("main") do
|
||||
self.inventory:set_stack("main", idx, savedata[idx])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Add a item to inventory
|
||||
function maininvClass:add_item(item)
|
||||
return self.inventory:add_item("main", item)
|
||||
end
|
||||
|
||||
function maininvClass:add_sepearate_stack(item)
|
||||
for idx, stack in ipairs(self.inventory:get_list("main")) do
|
||||
if stack:is_empty() then
|
||||
self.inventory:set_stack("main", idx, item)
|
||||
item = ""
|
||||
break
|
||||
end
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
-- Get inventory content as consolidated table
|
||||
function maininvClass:get_items()
|
||||
local items_in_inventory = {}
|
||||
|
||||
for _, stack in ipairs(self.inventory:get_list("main")) do
|
||||
local itemname = stack:get_name()
|
||||
if itemname and itemname ~= "" then
|
||||
if not items_in_inventory[itemname] then
|
||||
items_in_inventory[itemname] = stack:get_count()
|
||||
else
|
||||
items_in_inventory[itemname] = items_in_inventory[itemname] + stack:get_count()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- add items in crafting field to the available items in inventory
|
||||
for _, stack in ipairs(self.inventory:get_list("craft")) do
|
||||
local itemname = stack:get_name()
|
||||
if itemname and itemname ~= "" then
|
||||
if not items_in_inventory[itemname] then
|
||||
items_in_inventory[itemname] = stack:get_count()
|
||||
else
|
||||
items_in_inventory[itemname] = items_in_inventory[itemname] + stack:get_count()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return items_in_inventory
|
||||
end
|
||||
|
||||
-- try to get empty stacks by move items to other stacky up to max_size
|
||||
function maininvClass:compress()
|
||||
for idx1 = self.inventory:get_size("main"), 1, -1 do
|
||||
local stack1 = self.inventory:get_stack("main", idx1)
|
||||
if not stack1:is_empty() then
|
||||
for idx2 = 1, idx1 do
|
||||
local stack2 = self.inventory:get_stack("main", idx2)
|
||||
if idx1 ~= idx2 and stack1:get_name() == stack2:get_name() then
|
||||
stack1 = stack2:add_item(stack1)
|
||||
self.inventory:set_stack("main", idx1, stack1)
|
||||
self.inventory:set_stack("main", idx2, stack2)
|
||||
if stack1:is_empty() then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- move items to crafting grid to craft item
|
||||
function maininvClass:craft_item(grid)
|
||||
for idx_main, stack_main in ipairs(self.inventory:get_list("main")) do
|
||||
for x, col in pairs(grid) do
|
||||
for y, item in pairs(col) do
|
||||
local idx_craft = (y-1)*3+x
|
||||
local stack_craft = self.inventory:get_stack("craft", idx_craft )
|
||||
if not stack_main:is_empty() and stack_main:get_name() == item then --right item
|
||||
local left = stack_craft:add_item(stack_main:take_item(1))
|
||||
stack_main:add_item(left)
|
||||
self.inventory:set_stack("craft", idx_craft, stack_craft)
|
||||
self.inventory:set_stack("main", idx_main, stack_main)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- move all items from crafting inventory back to main inventory
|
||||
function maininvClass:sweep_crafting_inventory()
|
||||
for idx = 1, self.inventory:get_size("craft") do
|
||||
local stack = self.inventory:get_stack("craft", idx)
|
||||
if not stack:is_empty() then
|
||||
local left = self.inventory:add_item("main", stack)
|
||||
self.inventory:set_stack("craft", idx, left)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Swap row to the top. Asumption the inventory is 8x4, the row number should be 2, 3 or 4
|
||||
function maininvClass:swap_row_to_top(row)
|
||||
local width = 8
|
||||
for idx1 = 1, width do
|
||||
local idx2 = (row -1) * width + idx1
|
||||
local stack1 = self.inventory:get_stack("main", idx1)
|
||||
local stack2 = self.inventory:get_stack("main", idx2)
|
||||
self.inventory:set_stack("main", idx2, stack1)
|
||||
self.inventory:set_stack("main", idx1, stack2)
|
||||
end
|
||||
end
|
||||
|
||||
-- player inventory class
|
||||
local maininv = {}
|
||||
function maininv.get(playername)
|
||||
local self = setmetatable({}, maininvClass_mt)
|
||||
self.playername = playername
|
||||
self.inventory = minetest.get_player_by_name(playername):get_inventory()
|
||||
self.inventory:set_width("craft", 3)
|
||||
self.inventory:set_size("craft", 9)
|
||||
return self
|
||||
end
|
||||
|
||||
-- Check if player has creative privilege.
|
||||
function maininvClass:get_has_creative()
|
||||
return minetest.is_creative_enabled(self.playername)
|
||||
end
|
||||
|
||||
return maininv
|
|
@ -1,41 +0,0 @@
|
|||
local txt_usage = minetest.setting_getbool("smart_inventory_friendly_group_names") --or true
|
||||
if txt_usage == false then
|
||||
return false
|
||||
end
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname()).."/locale"
|
||||
|
||||
local LANG = minetest.setting_get("language")
|
||||
if not (LANG and (LANG ~= "")) then LANG = os.getenv("LANG") end
|
||||
if not (LANG and (LANG ~= "")) then LANG = "en" end
|
||||
local pofile = modpath.."/groups_"..LANG:sub(1,2)..".po"
|
||||
|
||||
local f=io.open(pofile,"r")
|
||||
--fallback to en
|
||||
if not f then
|
||||
pofile = modpath.."/groups_en.po"
|
||||
f=io.open(pofile,"r")
|
||||
end
|
||||
|
||||
local texttab = {}
|
||||
|
||||
local msgid
|
||||
local msgstr
|
||||
|
||||
for line in f:lines() do
|
||||
if line:sub(1,5) == 'msgid' then -- msgid ""
|
||||
msgid = line:sub(8, line:len()-1)
|
||||
elseif line:sub(1,6) == 'msgstr' then -- msgstr ""
|
||||
msgstr = line:sub(9, line:len()-1)
|
||||
end
|
||||
if msgid and msgstr then
|
||||
if msgid ~= "" and msgstr ~= "" then
|
||||
texttab[msgid] = msgstr
|
||||
end
|
||||
msgid = nil
|
||||
msgstr = nil
|
||||
end
|
||||
end
|
||||
|
||||
io.close(f)
|
||||
return texttab
|
|
@ -1,287 +0,0 @@
|
|||
local smartfs = smart_inventory.smartfs
|
||||
local elements = {}
|
||||
|
||||
-----------------------------------------------------
|
||||
--- Crafting Preview applet
|
||||
-----------------------------------------------------
|
||||
-- enhanced / prepared container
|
||||
-- Additional methods
|
||||
-- craft_preview:setCraft(craft)
|
||||
-- craft_preview:onButtonClicked(function(self, itemname, player))
|
||||
-- if craft=nil, the view will be initialized
|
||||
|
||||
local craft_preview = table.copy(smartfs._edef.container)
|
||||
function craft_preview:onCreate()
|
||||
self.data.relative = true
|
||||
smartfs._edef.container.onCreate(self)
|
||||
for x = 1, 3 do
|
||||
for y = 1, 3 do
|
||||
local button = self._state:image_button(
|
||||
(x-1)*self.data.zoom+self.data.pos.x,
|
||||
(y-1)*self.data.zoom+self.data.pos.y,
|
||||
self.data.zoom, self.data.zoom,
|
||||
"craft:"..x..":"..y,"")
|
||||
button:setVisible(false)
|
||||
button:onClick(function(self, state, player)
|
||||
local parent_element = state.location.containerElement
|
||||
if parent_element._button_click then
|
||||
parent_element._button_click(parent_element, self.data.item, player)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
if self.data.recipe then
|
||||
self:setCraft(self.data.recipe)
|
||||
end
|
||||
end
|
||||
|
||||
function craft_preview:onButtonClicked(func)
|
||||
self._button_click = func
|
||||
end
|
||||
|
||||
-- Update fields
|
||||
function craft_preview:setCraft(craft)
|
||||
local width
|
||||
if craft then -- adjust width to 1 if the recipe contains just 1 item
|
||||
width = craft.width or 3
|
||||
if width == 0 then
|
||||
width = 3
|
||||
end
|
||||
if craft.items[1] and next(craft.items, 1) == nil then
|
||||
width = 1
|
||||
end
|
||||
end
|
||||
for x = 1, 3 do
|
||||
for y = 1, 3 do
|
||||
local item = nil
|
||||
if craft then
|
||||
if width <= 1 then
|
||||
if x == 2 then
|
||||
item = craft.items[y]
|
||||
end
|
||||
elseif x <= width then
|
||||
item = craft.items[(y-1)*width+x]
|
||||
end
|
||||
end
|
||||
local btn = self._state:get("craft:"..x..":"..y)
|
||||
if item then
|
||||
if type(item) == "string" then
|
||||
btn:setItem(item)
|
||||
btn:setTooltip()
|
||||
btn:setText("")
|
||||
else
|
||||
btn:setItem(item.item)
|
||||
btn:setTooltip(item.tooltip)
|
||||
btn:setText(item.text)
|
||||
end
|
||||
btn:setVisible(true)
|
||||
else
|
||||
btn:setVisible(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- get the preview as table
|
||||
function craft_preview:getCraft()
|
||||
local grid = {}
|
||||
for x = 1, 3 do
|
||||
grid[x] = {}
|
||||
for y = 1, 3 do
|
||||
local button = self._state:get("craft:"..x..":"..y)
|
||||
if button:getVisible() then
|
||||
grid[x][y] = button:getItem()
|
||||
end
|
||||
end
|
||||
end
|
||||
return grid
|
||||
end
|
||||
|
||||
smartfs.element("craft_preview", craft_preview)
|
||||
|
||||
function elements:craft_preview(x, y, name, zoom, recipe)
|
||||
return self:element("craft_preview", {
|
||||
pos = {x=x, y=y},
|
||||
name = name,
|
||||
recipe = recipe,
|
||||
zoom = zoom or 1
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------
|
||||
--- Pagable grid buttons
|
||||
-----------------------------------------------------
|
||||
--[[ enhanced / prepared container
|
||||
Additional methods
|
||||
buttons_grid:setList(craft)
|
||||
buttons_grid:onClick(function(state, index, player)...end)
|
||||
buttons_grid:setList(iconlist)
|
||||
buttons_grid:getFirstVisible()
|
||||
buttons_grid:setFirstVisible(index)
|
||||
|
||||
iconslist is a list of next entries:
|
||||
entry = {
|
||||
image | item =
|
||||
tooltip=
|
||||
is_button = true,
|
||||
size = {w=,h=}
|
||||
}
|
||||
]]
|
||||
local buttons_grid = table.copy(smartfs._edef.container)
|
||||
function buttons_grid:onCreate()
|
||||
self.data.relative = true
|
||||
assert(self.data.size and self.data.size.w and self.data.size.h, "button needs valid size")
|
||||
smartfs._edef.container.onCreate(self)
|
||||
if not self.data.cell_size or not self.data.cell_size.w or not self.data.cell_size.h then
|
||||
self.data.cell_size = {w=1, h=1}
|
||||
end
|
||||
self:setSize(self.data.size.w, self.data.size.h) -- view size for background
|
||||
self.data.grid_size = {w = math.floor(self.data.size.w/self.data.cell_size.w), h = math.floor(self.data.size.h/self.data.cell_size.h)}
|
||||
self.data.list_start = self.data.list_start or 1
|
||||
self.data.list = self.data.list or {}
|
||||
for x = 1, self.data.grid_size.w do
|
||||
for y=1, self.data.grid_size.h do
|
||||
local button = self._state:button(
|
||||
self.data.pos.x + (x-1)*self.data.cell_size.w,
|
||||
self.data.pos.y + (y-1)*self.data.cell_size.h,
|
||||
self.data.cell_size.w,
|
||||
self.data.cell_size.h,
|
||||
tostring((y-1)*self.data.grid_size.w+x),
|
||||
"")
|
||||
button:onClick(function(self, state, player)
|
||||
local rel = tonumber(self.name)
|
||||
local parent_element = state.location.containerElement
|
||||
local idx = rel
|
||||
if parent_element.data.list_start > 1 then
|
||||
idx = parent_element.data.list_start + rel - 2
|
||||
end
|
||||
if rel == 1 and parent_element.data.list_start > 1 then
|
||||
-- page back
|
||||
local full_pagesize = parent_element.data.grid_size.w * parent_element.data.grid_size.h
|
||||
if parent_element.data.list_start <= full_pagesize then
|
||||
parent_element.data.list_start = 1
|
||||
else
|
||||
--prev page use allways 2x navigation buttons at list_start > 1 and the next page (we navigate from) exists
|
||||
parent_element.data.list_start = parent_element.data.list_start - (full_pagesize-2)
|
||||
end
|
||||
parent_element:update()
|
||||
elseif rel == (parent_element.data.grid_size.w * parent_element.data.grid_size.h) and
|
||||
parent_element.data.list[parent_element.data.list_start+parent_element.data.pagesize] then
|
||||
-- page forward
|
||||
parent_element.data.list_start = parent_element.data.list_start+parent_element.data.pagesize
|
||||
parent_element:update()
|
||||
else
|
||||
-- pass call to the button function
|
||||
if parent_element._click then
|
||||
parent_element:_click(parent_element.root, idx, player)
|
||||
end
|
||||
end
|
||||
end)
|
||||
button:setVisible(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function buttons_grid:reset(x, y, w, h, col_size, row_size)
|
||||
self._state = nil
|
||||
|
||||
self.data.pos.x = x or self.data.pos.x
|
||||
self.data.pos.y = y or self.data.pos.y
|
||||
self.data.size.w = w or self.data.size.w
|
||||
self.data.size.h = h or self.data.size.h
|
||||
self.data.cell_size.w = col_size or self.data.cell_size.w
|
||||
self.data.cell_size.h = row_size or self.data.cell_size.h
|
||||
|
||||
self:onCreate()
|
||||
self:update()
|
||||
end
|
||||
|
||||
function buttons_grid:onClick(func)
|
||||
self._click = func
|
||||
end
|
||||
function buttons_grid:getFirstVisible()
|
||||
return self.data.list_start
|
||||
end
|
||||
function buttons_grid:setFirstVisible(idx)
|
||||
self.data.list_start = idx
|
||||
end
|
||||
function buttons_grid:setList(iconlist)
|
||||
self.data.list = iconlist or {}
|
||||
self:update()
|
||||
end
|
||||
|
||||
function buttons_grid:update()
|
||||
--init pagesize
|
||||
self.data.pagesize = self.data.grid_size.w * self.data.grid_size.h
|
||||
--adjust start position
|
||||
if self.data.list_start > #self.data.list then
|
||||
self.data.list_start = #self.data.list - self.data.pagesize
|
||||
end
|
||||
if self.data.list_start < 1 then
|
||||
self.data.list_start = 1
|
||||
end
|
||||
|
||||
local itemindex = self.data.list_start
|
||||
for btnid = 1, self.data.grid_size.w * self.data.grid_size.h do
|
||||
local button = self._state:get(tostring(btnid))
|
||||
if btnid == 1 and self.data.list_start > 1 then
|
||||
-- setup back button
|
||||
button:setVisible(true)
|
||||
button:setImage("smart_inventory_left_arrow.png")
|
||||
button:setText(tostring(self.data.list_start-1))
|
||||
button:setSize(self.data.cell_size.w, self.data.cell_size.h)
|
||||
self.data.pagesize = self.data.pagesize - 1
|
||||
elseif btnid == self.data.grid_size.w * self.data.grid_size.h and self.data.list[itemindex+1] then
|
||||
-- setup next button
|
||||
button:setVisible(true)
|
||||
button:setImage("smart_inventory_right_arrow.png")
|
||||
self.data.pagesize = self.data.pagesize - 1
|
||||
button:setText(tostring(#self.data.list-self.data.list_start-self.data.pagesize+1))
|
||||
button:setSize(self.data.cell_size.w, self.data.cell_size.h)
|
||||
else
|
||||
-- functional button
|
||||
local entry = self.data.list[itemindex]
|
||||
if entry then
|
||||
if entry.size then
|
||||
button:setSize(entry.size.w, entry.size.h)
|
||||
else
|
||||
button:setSize(self.data.cell_size.w, self.data.cell_size.h)
|
||||
end
|
||||
if entry.item and entry.is_button == true then
|
||||
button:setVisible(true)
|
||||
button:setItem(entry.item)
|
||||
button:setText(entry.text or "")
|
||||
button:setTooltip(nil)
|
||||
elseif entry.image and entry.is_button == true then
|
||||
button:setVisible(true)
|
||||
button:setImage(entry.image)
|
||||
button:setText(entry.text or "")
|
||||
button:setTooltip(entry.tooltip)
|
||||
-- TODO 1: entry.image to display *.png
|
||||
-- TODO 2: entry.text to display label on button
|
||||
-- TODO 3,4,5: is_button == false to get just pic or label without button
|
||||
end
|
||||
else
|
||||
button:setVisible(false)
|
||||
end
|
||||
itemindex = itemindex + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
smartfs.element("buttons_grid", buttons_grid)
|
||||
|
||||
function elements:buttons_grid(x, y, w, h, name, col_size, row_size)
|
||||
return self:element("buttons_grid", {
|
||||
pos = {x=x, y=y},
|
||||
size = {w=w, h=h},
|
||||
cell_size = {w=col_size, h=row_size},
|
||||
name = name
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-------------------------
|
||||
return elements
|
|
@ -1,651 +0,0 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.5\n"
|
||||
|
||||
msgid "all"
|
||||
msgstr "Alles"
|
||||
|
||||
msgid "other"
|
||||
msgstr "Weitere"
|
||||
|
||||
msgid "antiportal"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor"
|
||||
msgstr "Rüstung"
|
||||
|
||||
msgid "armor:feet"
|
||||
msgstr "Stiefel"
|
||||
|
||||
msgid "armor:fire"
|
||||
msgstr "Feuerschutz"
|
||||
|
||||
msgid "armor:head"
|
||||
msgstr "Kopfschutz"
|
||||
|
||||
msgid "armor:heal"
|
||||
msgstr "Heilen"
|
||||
|
||||
msgid "armor:legs"
|
||||
msgstr "Beinschutz"
|
||||
|
||||
msgid "armor:shield"
|
||||
msgstr "Schild"
|
||||
|
||||
msgid "armor:torso"
|
||||
msgstr "Körperschutz"
|
||||
|
||||
msgid "armor:use"
|
||||
msgstr "Abnutzung bei Schaden"
|
||||
|
||||
msgid "attached_node"
|
||||
msgstr "Verbundbar"
|
||||
|
||||
msgid "bag"
|
||||
msgstr "Tasche"
|
||||
|
||||
msgid "basecolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:brown"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:magenta"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "bed"
|
||||
msgstr "Bett"
|
||||
|
||||
msgid "bendy"
|
||||
msgstr ""
|
||||
|
||||
msgid "book"
|
||||
msgstr "Buch"
|
||||
|
||||
msgid "bouncy"
|
||||
msgstr "Federnd"
|
||||
|
||||
msgid "cannon"
|
||||
msgstr ""
|
||||
|
||||
msgid "cannonstand"
|
||||
msgstr ""
|
||||
|
||||
msgid "choppy"
|
||||
msgstr "Abgehackt"
|
||||
|
||||
msgid "coal"
|
||||
msgstr "Kohle"
|
||||
|
||||
msgid "color"
|
||||
msgstr "Farbe"
|
||||
|
||||
msgid "color:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "connect_to_raillike"
|
||||
msgstr "Schienenartig"
|
||||
|
||||
msgid "cools_lava"
|
||||
msgstr ""
|
||||
|
||||
msgid "cracky"
|
||||
msgstr "Knackig"
|
||||
|
||||
msgid "crossbrace_connectable"
|
||||
msgstr ""
|
||||
|
||||
msgid "crumbly"
|
||||
msgstr "Brüchig"
|
||||
|
||||
msgid "customnode"
|
||||
msgstr "Dekorativer Block"
|
||||
|
||||
msgid "damage"
|
||||
msgstr "Schaden"
|
||||
|
||||
msgid "damage:fleshy"
|
||||
msgstr "Fleischverletzung"
|
||||
|
||||
msgid "desert"
|
||||
msgstr ""
|
||||
|
||||
msgid "dig_immediate"
|
||||
msgstr "Schnell abbaubar"
|
||||
|
||||
msgid "dig_immediate:3"
|
||||
msgstr "Sofort abbaubar"
|
||||
|
||||
msgid "disable_jump"
|
||||
msgstr "Klebrig"
|
||||
|
||||
msgid "door"
|
||||
msgstr "Tür"
|
||||
|
||||
msgid "dry_grass"
|
||||
msgstr ""
|
||||
|
||||
msgid "dye"
|
||||
msgstr "Farbstoff"
|
||||
|
||||
msgid "eatable"
|
||||
msgstr "Essbar"
|
||||
|
||||
msgid "excolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:darkgrey"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:red:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "fall_damage_add_percent"
|
||||
msgstr "Aufprallschaden"
|
||||
|
||||
msgid "falling_node"
|
||||
msgstr "Fallend"
|
||||
|
||||
msgid "false"
|
||||
msgstr ""
|
||||
|
||||
msgid "fence"
|
||||
msgstr "Zaun"
|
||||
|
||||
msgid "flammable"
|
||||
msgstr "Brennbar"
|
||||
|
||||
msgid "fleshy"
|
||||
msgstr "Fleischig"
|
||||
|
||||
msgid "flora"
|
||||
msgstr "Flora"
|
||||
|
||||
msgid "flower"
|
||||
msgstr "Blume"
|
||||
|
||||
msgid "food"
|
||||
msgstr "Nahrung"
|
||||
|
||||
msgid "food:apple"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:blueberry"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:bowl"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:butter"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cactus"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:carrot"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cheese"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:chicken"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:choco"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:choco:powder"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cocoa"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cup"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:dark:chocolate"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:egg"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:flour"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:lemon"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:meat"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:meat:raw"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:milk"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:milk:chocolate"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:nut"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:pasta"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:potato"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:rhubarb"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:strawberry"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:sugar"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:tomato"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:walnut"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:wheat"
|
||||
msgstr ""
|
||||
|
||||
msgid "fuel"
|
||||
msgstr "Brennstoff"
|
||||
|
||||
msgid "grass"
|
||||
msgstr "Gras"
|
||||
|
||||
msgid "grassland"
|
||||
msgstr ""
|
||||
|
||||
msgid "gunpowder"
|
||||
msgstr ""
|
||||
|
||||
msgid "hot"
|
||||
msgstr ""
|
||||
|
||||
msgid "igniter"
|
||||
msgstr ""
|
||||
|
||||
msgid "ingredient"
|
||||
msgstr "Erzeugt aus"
|
||||
|
||||
msgid "key"
|
||||
msgstr "Schlüssel"
|
||||
|
||||
msgid "lava"
|
||||
msgstr ""
|
||||
|
||||
msgid "leaves"
|
||||
msgstr "Laub"
|
||||
|
||||
msgid "level"
|
||||
msgstr "Wertvoll"
|
||||
|
||||
msgid "light"
|
||||
msgstr "Lichtquelle"
|
||||
|
||||
msgid "liquid"
|
||||
msgstr ""
|
||||
|
||||
msgid "marble"
|
||||
msgstr ""
|
||||
|
||||
msgid "meat"
|
||||
msgstr ""
|
||||
|
||||
msgid "melty"
|
||||
msgstr ""
|
||||
|
||||
msgid "metainv"
|
||||
msgstr "Mit Inventar"
|
||||
|
||||
msgid "mod"
|
||||
msgstr "Mod"
|
||||
|
||||
msgid "not_cuttable"
|
||||
msgstr ""
|
||||
|
||||
msgid "not_in_creative_inventory"
|
||||
msgstr ""
|
||||
|
||||
msgid "oddly_breakable_by_hand"
|
||||
msgstr "Ohne Werkzeug abbaubar"
|
||||
|
||||
msgid "pane"
|
||||
msgstr ""
|
||||
|
||||
msgid "physics"
|
||||
msgstr ""
|
||||
|
||||
msgid "physics:gravity"
|
||||
msgstr "Erdanziehung"
|
||||
|
||||
msgid "physics:speed"
|
||||
msgstr "Geschwindigkeit"
|
||||
|
||||
msgid "plant"
|
||||
msgstr ""
|
||||
|
||||
msgid "poison"
|
||||
msgstr ""
|
||||
|
||||
msgid "potting_soil"
|
||||
msgstr ""
|
||||
|
||||
msgid "puts_out_fire"
|
||||
msgstr ""
|
||||
|
||||
msgid "rail"
|
||||
msgstr ""
|
||||
|
||||
msgid "recipetype"
|
||||
msgstr ""
|
||||
|
||||
msgid "recipetype:cooking"
|
||||
msgstr "Gekocht"
|
||||
|
||||
msgid "rock"
|
||||
msgstr ""
|
||||
|
||||
msgid "sand"
|
||||
msgstr "Sand"
|
||||
|
||||
msgid "sapling"
|
||||
msgstr ""
|
||||
|
||||
msgid "seed"
|
||||
msgstr "Samen"
|
||||
|
||||
msgid "shape"
|
||||
msgstr "Geformt"
|
||||
|
||||
msgid "slab"
|
||||
msgstr "Platte"
|
||||
|
||||
msgid "snappy"
|
||||
msgstr "Schnittig"
|
||||
|
||||
msgid "snowy"
|
||||
msgstr ""
|
||||
|
||||
msgid "soil"
|
||||
msgstr "Erde"
|
||||
|
||||
msgid "soil:1"
|
||||
msgstr "Ackerboden"
|
||||
|
||||
msgid "soil:2"
|
||||
msgstr "Trockener Ackerboden"
|
||||
|
||||
msgid "soil:3"
|
||||
msgstr "Nasser Ackerboden"
|
||||
|
||||
msgid "spreading_dirt_type"
|
||||
msgstr ""
|
||||
|
||||
msgid "stair"
|
||||
msgstr "Treppe"
|
||||
|
||||
msgid "stick"
|
||||
msgstr "Stock"
|
||||
|
||||
msgid "stone"
|
||||
msgstr "Stein"
|
||||
|
||||
msgid "surface_hot"
|
||||
msgstr ""
|
||||
|
||||
msgid "tar_block"
|
||||
msgstr ""
|
||||
|
||||
msgid "tool"
|
||||
msgstr ""
|
||||
|
||||
msgid "tool:full_punch_interval"
|
||||
msgstr "Verwendungsinterval"
|
||||
|
||||
msgid "tool:max_drop_level"
|
||||
msgstr "Max drop Level"
|
||||
|
||||
msgid "torch"
|
||||
msgstr ""
|
||||
|
||||
msgid "translucent"
|
||||
msgstr "Lichtdurchläßig"
|
||||
|
||||
msgid "tree"
|
||||
msgstr "Baum"
|
||||
|
||||
msgid "type"
|
||||
msgstr ""
|
||||
|
||||
msgid "type:craft"
|
||||
msgstr "Gegenstand"
|
||||
|
||||
msgid "type:node"
|
||||
msgstr "Block"
|
||||
|
||||
msgid "type:tool"
|
||||
msgstr "Werkzeug"
|
||||
|
||||
msgid "ud_param2_colorable"
|
||||
msgstr "Färbbar"
|
||||
|
||||
msgid "unicolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:darkgrey"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:light"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:light:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:red:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "vessel"
|
||||
msgstr "Behälter"
|
||||
|
||||
msgid "wall"
|
||||
msgstr "Mauer"
|
||||
|
||||
msgid "water"
|
||||
msgstr "Wasser"
|
||||
|
||||
msgid "water_bucket"
|
||||
msgstr "Eimer"
|
||||
|
||||
msgid "wet"
|
||||
msgstr "Nass"
|
||||
|
||||
msgid "wood"
|
||||
msgstr "Holz"
|
||||
|
||||
msgid "wool"
|
||||
msgstr "Wolle"
|
||||
|
||||
#~ msgid "physics:jump"
|
||||
#~ msgstr "Sprunghöhe"
|
||||
|
||||
#~ msgid "armor:state"
|
||||
#~ msgstr "Rüstungsstatus"
|
||||
|
||||
#~ msgid "damage:choppy"
|
||||
#~ msgstr "Abgehackt"
|
||||
|
||||
#~ msgid "slope"
|
||||
#~ msgstr "Neigung"
|
||||
|
||||
#~ msgid "leavedecay"
|
||||
#~ msgstr "Verwelkbar"
|
||||
|
||||
#~ msgid "damage:snappy"
|
||||
#~ msgstr "Schnittverletzung"
|
||||
|
||||
#~ msgid "micro"
|
||||
#~ msgstr "Mikro"
|
||||
|
||||
#~ msgid "panel"
|
||||
#~ msgstr "Paneel"
|
||||
|
||||
#~ msgid "armor:level"
|
||||
#~ msgstr "Level der Rüstung"
|
||||
|
||||
#~ msgid "carpet"
|
||||
#~ msgstr "Teppich"
|
||||
|
||||
#~ msgid "explody"
|
||||
#~ msgstr "Explosiv"
|
||||
|
||||
#~ msgid "armor:water"
|
||||
#~ msgstr "Wasserschutz"
|
||||
|
||||
#~ msgid "radiation"
|
||||
#~ msgstr "Schutz gegen Radioaktivität"
|
||||
|
||||
#~ msgid "tool:damage:choppy"
|
||||
#~ msgstr "Hack-Schaden"
|
||||
|
||||
#~ msgid "transluc"
|
||||
#~ msgstr "Lichtdurchlässig"
|
||||
|
||||
#~ msgid "tool:damage:snappy"
|
||||
#~ msgstr "Schnitt-Schaden"
|
||||
|
||||
#~ msgid "tool:damage:fleshy"
|
||||
#~ msgstr "Wund-Schaden"
|
|
@ -1,636 +0,0 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: en\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=iso-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.5\n"
|
||||
|
||||
msgid "all"
|
||||
msgstr "All items"
|
||||
|
||||
msgid "other"
|
||||
msgstr "Other items"
|
||||
|
||||
msgid "antiportal"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor"
|
||||
msgstr "Armor"
|
||||
|
||||
msgid "armor:feet"
|
||||
msgstr "Feet protection"
|
||||
|
||||
msgid "armor:fire"
|
||||
msgstr "Fire protection"
|
||||
|
||||
msgid "armor:head"
|
||||
msgstr "Head protection"
|
||||
|
||||
msgid "armor:heal"
|
||||
msgstr "Heal"
|
||||
|
||||
msgid "armor:legs"
|
||||
msgstr "Legs protection"
|
||||
|
||||
msgid "armor:shield"
|
||||
msgstr "Shield"
|
||||
|
||||
msgid "armor:torso"
|
||||
msgstr "Torso protection"
|
||||
|
||||
msgid "armor:use"
|
||||
msgstr "Wear on damage"
|
||||
|
||||
msgid "attached_node"
|
||||
msgstr "Attachable"
|
||||
|
||||
msgid "bag"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:brown"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:magenta"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "bed"
|
||||
msgstr "Bed"
|
||||
|
||||
msgid "bendy"
|
||||
msgstr ""
|
||||
|
||||
msgid "book"
|
||||
msgstr "Book"
|
||||
|
||||
msgid "bouncy"
|
||||
msgstr "Bouncy"
|
||||
|
||||
msgid "cannon"
|
||||
msgstr ""
|
||||
|
||||
msgid "cannonstand"
|
||||
msgstr ""
|
||||
|
||||
msgid "choppy"
|
||||
msgstr "Choppy"
|
||||
|
||||
msgid "coal"
|
||||
msgstr "Coal"
|
||||
|
||||
msgid "color"
|
||||
msgstr "Colour"
|
||||
|
||||
msgid "color:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "connect_to_raillike"
|
||||
msgstr "Rail-like"
|
||||
|
||||
msgid "cools_lava"
|
||||
msgstr ""
|
||||
|
||||
msgid "cracky"
|
||||
msgstr "Cracky"
|
||||
|
||||
msgid "crossbrace_connectable"
|
||||
msgstr ""
|
||||
|
||||
msgid "crumbly"
|
||||
msgstr "Crumbly"
|
||||
|
||||
msgid "customnode"
|
||||
msgstr "Decorative node"
|
||||
|
||||
msgid "damage"
|
||||
msgstr "Damage"
|
||||
|
||||
msgid "damage:fleshy"
|
||||
msgstr "Fleshy damage"
|
||||
|
||||
msgid "desert"
|
||||
msgstr "Desert"
|
||||
|
||||
msgid "dig_immediate"
|
||||
msgstr "Fast diggable"
|
||||
|
||||
msgid "dig_immediate:3"
|
||||
msgstr "Immediate diggable"
|
||||
|
||||
msgid "disable_jump"
|
||||
msgstr "Sticky"
|
||||
|
||||
msgid "door"
|
||||
msgstr "Door"
|
||||
|
||||
msgid "dry_grass"
|
||||
msgstr "Dry grass"
|
||||
|
||||
msgid "dye"
|
||||
msgstr "Dye"
|
||||
|
||||
msgid "eatable"
|
||||
msgstr "Eatable"
|
||||
|
||||
msgid "excolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:darkgrey"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:red:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "fall_damage_add_percent"
|
||||
msgstr "Fall damage"
|
||||
|
||||
msgid "falling_node"
|
||||
msgstr "Falling"
|
||||
|
||||
msgid "false"
|
||||
msgstr ""
|
||||
|
||||
msgid "fence"
|
||||
msgstr "Fence"
|
||||
|
||||
msgid "flammable"
|
||||
msgstr "Flammable"
|
||||
|
||||
msgid "fleshy"
|
||||
msgstr "Fleshy"
|
||||
|
||||
msgid "flora"
|
||||
msgstr "Flora"
|
||||
|
||||
msgid "flower"
|
||||
msgstr "Flower"
|
||||
|
||||
msgid "food"
|
||||
msgstr "Food"
|
||||
|
||||
msgid "food:apple"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:blueberry"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:bowl"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:butter"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cactus"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:carrot"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cheese"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:chicken"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:choco"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:choco:powder"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cocoa"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cup"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:dark:chocolate"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:egg"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:flour"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:lemon"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:meat"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:meat:raw"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:milk"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:milk:chocolate"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:nut"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:pasta"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:potato"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:rhubarb"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:strawberry"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:sugar"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:tomato"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:walnut"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:wheat"
|
||||
msgstr ""
|
||||
|
||||
msgid "fuel"
|
||||
msgstr "Fuel"
|
||||
|
||||
msgid "grass"
|
||||
msgstr "Grass"
|
||||
|
||||
msgid "grassland"
|
||||
msgstr ""
|
||||
|
||||
msgid "gunpowder"
|
||||
msgstr ""
|
||||
|
||||
msgid "hot"
|
||||
msgstr "Hot"
|
||||
|
||||
msgid "igniter"
|
||||
msgstr ""
|
||||
|
||||
msgid "ingredient"
|
||||
msgstr "Crafted with"
|
||||
|
||||
msgid "key"
|
||||
msgstr "Key"
|
||||
|
||||
msgid "lava"
|
||||
msgstr ""
|
||||
|
||||
msgid "leaves"
|
||||
msgstr "Leaves"
|
||||
|
||||
msgid "level"
|
||||
msgstr "Valuable"
|
||||
|
||||
msgid "light"
|
||||
msgstr "Light source"
|
||||
|
||||
msgid "liquid"
|
||||
msgstr ""
|
||||
|
||||
msgid "marble"
|
||||
msgstr ""
|
||||
|
||||
msgid "meat"
|
||||
msgstr ""
|
||||
|
||||
msgid "melty"
|
||||
msgstr ""
|
||||
|
||||
msgid "metainv"
|
||||
msgstr "With inventory"
|
||||
|
||||
msgid "mod"
|
||||
msgstr "Mod"
|
||||
|
||||
msgid "not_cuttable"
|
||||
msgstr ""
|
||||
|
||||
msgid "not_in_creative_inventory"
|
||||
msgstr ""
|
||||
|
||||
msgid "oddly_breakable_by_hand"
|
||||
msgstr "Oddly breakable"
|
||||
|
||||
msgid "pane"
|
||||
msgstr ""
|
||||
|
||||
msgid "physics"
|
||||
msgstr ""
|
||||
|
||||
msgid "physics:gravity"
|
||||
msgstr "Gravity"
|
||||
|
||||
msgid "physics:speed"
|
||||
msgstr "Walking speed"
|
||||
|
||||
msgid "plant"
|
||||
msgstr ""
|
||||
|
||||
msgid "poison"
|
||||
msgstr ""
|
||||
|
||||
msgid "potting_soil"
|
||||
msgstr ""
|
||||
|
||||
msgid "puts_out_fire"
|
||||
msgstr ""
|
||||
|
||||
msgid "rail"
|
||||
msgstr ""
|
||||
|
||||
msgid "recipetype"
|
||||
msgstr ""
|
||||
|
||||
msgid "recipetype:cooking"
|
||||
msgstr "Cooking result"
|
||||
|
||||
msgid "rock"
|
||||
msgstr ""
|
||||
|
||||
msgid "sand"
|
||||
msgstr "Sand"
|
||||
|
||||
msgid "sapling"
|
||||
msgstr "Sapling"
|
||||
|
||||
msgid "seed"
|
||||
msgstr "Seed"
|
||||
|
||||
msgid "shape"
|
||||
msgstr "Shape"
|
||||
|
||||
msgid "slab"
|
||||
msgstr "Slab"
|
||||
|
||||
msgid "snappy"
|
||||
msgstr "Snappy"
|
||||
|
||||
msgid "snowy"
|
||||
msgstr "Snowy"
|
||||
|
||||
msgid "soil"
|
||||
msgstr "Soil"
|
||||
|
||||
msgid "soil:1"
|
||||
msgstr "Basic soil"
|
||||
|
||||
msgid "soil:2"
|
||||
msgstr "Dry farming soil"
|
||||
|
||||
msgid "soil:3"
|
||||
msgstr "Wet farming"
|
||||
|
||||
msgid "spreading_dirt_type"
|
||||
msgstr ""
|
||||
|
||||
msgid "stair"
|
||||
msgstr "Stair"
|
||||
|
||||
msgid "stick"
|
||||
msgstr "Stick"
|
||||
|
||||
msgid "stone"
|
||||
msgstr "Stone"
|
||||
|
||||
msgid "surface_hot"
|
||||
msgstr ""
|
||||
|
||||
msgid "tar_block"
|
||||
msgstr ""
|
||||
|
||||
msgid "tool"
|
||||
msgstr ""
|
||||
|
||||
msgid "tool:full_punch_interval"
|
||||
msgstr "Punch interval"
|
||||
|
||||
msgid "tool:max_drop_level"
|
||||
msgstr "Max drop level"
|
||||
|
||||
msgid "torch"
|
||||
msgstr "Torch"
|
||||
|
||||
msgid "translucent"
|
||||
msgstr "Translucent"
|
||||
|
||||
msgid "tree"
|
||||
msgstr "Tree"
|
||||
|
||||
msgid "type"
|
||||
msgstr ""
|
||||
|
||||
msgid "type:craft"
|
||||
msgstr "Item"
|
||||
|
||||
msgid "type:node"
|
||||
msgstr "Node"
|
||||
|
||||
msgid "type:tool"
|
||||
msgstr "Tool"
|
||||
|
||||
msgid "ud_param2_colorable"
|
||||
msgstr "Colorable by dye punch"
|
||||
|
||||
msgid "unicolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:darkgrey"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:light"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:light:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:red:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "vessel"
|
||||
msgstr "Vessel"
|
||||
|
||||
msgid "wall"
|
||||
msgstr "Wall"
|
||||
|
||||
msgid "water"
|
||||
msgstr "Water"
|
||||
|
||||
msgid "water_bucket"
|
||||
msgstr "Bucket"
|
||||
|
||||
msgid "wet"
|
||||
msgstr ""
|
||||
|
||||
msgid "wood"
|
||||
msgstr "Wood"
|
||||
|
||||
msgid "wool"
|
||||
msgstr "Wool"
|
||||
|
||||
#~ msgid "physics:jump"
|
||||
#~ msgstr "Jump high"
|
||||
|
||||
#~ msgid "armor:state"
|
||||
#~ msgstr "Armor state"
|
||||
|
||||
#~ msgid "damage:choppy"
|
||||
#~ msgstr "Choppy damage"
|
||||
|
||||
#~ msgid "slope"
|
||||
#~ msgstr "Slope"
|
||||
|
||||
#~ msgid "leavedecay"
|
||||
#~ msgstr "Decayable"
|
||||
|
||||
#~ msgid "damage:snappy"
|
||||
#~ msgstr "Snappy damage"
|
||||
|
||||
#~ msgid "micro"
|
||||
#~ msgstr "Micro"
|
||||
|
||||
#~ msgid "panel"
|
||||
#~ msgstr "Panel"
|
||||
|
||||
#~ msgid "armor:level"
|
||||
#~ msgstr "Armor level"
|
||||
|
||||
#~ msgid "carpet"
|
||||
#~ msgstr "Carpet"
|
||||
|
||||
#~ msgid "explody"
|
||||
#~ msgstr "Explosive"
|
||||
|
||||
#~ msgid "armor:water"
|
||||
#~ msgstr "Water protection"
|
|
@ -1,588 +0,0 @@
|
|||
msgid "all"
|
||||
msgstr ""
|
||||
|
||||
msgid "other"
|
||||
msgstr ""
|
||||
|
||||
msgid "antiportal"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:feet"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:fire"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:head"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:heal"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:legs"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:shield"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:torso"
|
||||
msgstr ""
|
||||
|
||||
msgid "armor:use"
|
||||
msgstr ""
|
||||
|
||||
msgid "attached_node"
|
||||
msgstr ""
|
||||
|
||||
msgid "bag"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:brown"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:magenta"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "basecolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "bed"
|
||||
msgstr ""
|
||||
|
||||
msgid "bendy"
|
||||
msgstr ""
|
||||
|
||||
msgid "book"
|
||||
msgstr ""
|
||||
|
||||
msgid "bouncy"
|
||||
msgstr ""
|
||||
|
||||
msgid "cannon"
|
||||
msgstr ""
|
||||
|
||||
msgid "cannonstand"
|
||||
msgstr ""
|
||||
|
||||
msgid "choppy"
|
||||
msgstr ""
|
||||
|
||||
msgid "coal"
|
||||
msgstr ""
|
||||
|
||||
msgid "color"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "color:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "connect_to_raillike"
|
||||
msgstr ""
|
||||
|
||||
msgid "cools_lava"
|
||||
msgstr ""
|
||||
|
||||
msgid "cracky"
|
||||
msgstr ""
|
||||
|
||||
msgid "crossbrace_connectable"
|
||||
msgstr ""
|
||||
|
||||
msgid "crumbly"
|
||||
msgstr ""
|
||||
|
||||
msgid "customnode"
|
||||
msgstr ""
|
||||
|
||||
msgid "damage"
|
||||
msgstr ""
|
||||
|
||||
msgid "damage:fleshy"
|
||||
msgstr ""
|
||||
|
||||
msgid "desert"
|
||||
msgstr ""
|
||||
|
||||
msgid "dig_immediate"
|
||||
msgstr ""
|
||||
|
||||
msgid "dig_immediate:3"
|
||||
msgstr ""
|
||||
|
||||
msgid "disable_jump"
|
||||
msgstr ""
|
||||
|
||||
msgid "door"
|
||||
msgstr ""
|
||||
|
||||
msgid "dry_grass"
|
||||
msgstr ""
|
||||
|
||||
msgid "dye"
|
||||
msgstr ""
|
||||
|
||||
msgid "eatable"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:darkgrey"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:red:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "excolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "fall_damage_add_percent"
|
||||
msgstr ""
|
||||
|
||||
msgid "falling_node"
|
||||
msgstr ""
|
||||
|
||||
msgid "false"
|
||||
msgstr ""
|
||||
|
||||
msgid "fence"
|
||||
msgstr ""
|
||||
|
||||
msgid "flammable"
|
||||
msgstr ""
|
||||
|
||||
msgid "fleshy"
|
||||
msgstr ""
|
||||
|
||||
msgid "flora"
|
||||
msgstr ""
|
||||
|
||||
msgid "flower"
|
||||
msgstr ""
|
||||
|
||||
msgid "food"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:apple"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:blueberry"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:bowl"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:butter"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cactus"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:carrot"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cheese"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:chicken"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:choco"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:choco:powder"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cocoa"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:cup"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:dark:chocolate"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:egg"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:flour"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:lemon"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:meat"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:meat:raw"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:milk"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:milk:chocolate"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:nut"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:pasta"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:potato"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:rhubarb"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:strawberry"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:sugar"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:tomato"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:walnut"
|
||||
msgstr ""
|
||||
|
||||
msgid "food:wheat"
|
||||
msgstr ""
|
||||
|
||||
msgid "fuel"
|
||||
msgstr ""
|
||||
|
||||
msgid "grass"
|
||||
msgstr ""
|
||||
|
||||
msgid "grassland"
|
||||
msgstr ""
|
||||
|
||||
msgid "gunpowder"
|
||||
msgstr ""
|
||||
|
||||
msgid "hot"
|
||||
msgstr ""
|
||||
|
||||
msgid "igniter"
|
||||
msgstr ""
|
||||
|
||||
msgid "ingredient"
|
||||
msgstr ""
|
||||
|
||||
msgid "key"
|
||||
msgstr ""
|
||||
|
||||
msgid "lava"
|
||||
msgstr ""
|
||||
|
||||
msgid "leaves"
|
||||
msgstr ""
|
||||
|
||||
msgid "level"
|
||||
msgstr ""
|
||||
|
||||
msgid "light"
|
||||
msgstr ""
|
||||
|
||||
msgid "liquid"
|
||||
msgstr ""
|
||||
|
||||
msgid "marble"
|
||||
msgstr ""
|
||||
|
||||
msgid "meat"
|
||||
msgstr ""
|
||||
|
||||
msgid "melty"
|
||||
msgstr ""
|
||||
|
||||
msgid "metainv"
|
||||
msgstr ""
|
||||
|
||||
msgid "mod"
|
||||
msgstr ""
|
||||
|
||||
msgid "not_cuttable"
|
||||
msgstr ""
|
||||
|
||||
msgid "not_in_creative_inventory"
|
||||
msgstr ""
|
||||
|
||||
msgid "oddly_breakable_by_hand"
|
||||
msgstr ""
|
||||
|
||||
msgid "pane"
|
||||
msgstr ""
|
||||
|
||||
msgid "physics"
|
||||
msgstr ""
|
||||
|
||||
msgid "physics:gravity"
|
||||
msgstr ""
|
||||
|
||||
msgid "physics:speed"
|
||||
msgstr ""
|
||||
|
||||
msgid "plant"
|
||||
msgstr ""
|
||||
|
||||
msgid "poison"
|
||||
msgstr ""
|
||||
|
||||
msgid "potting_soil"
|
||||
msgstr ""
|
||||
|
||||
msgid "puts_out_fire"
|
||||
msgstr ""
|
||||
|
||||
msgid "rail"
|
||||
msgstr ""
|
||||
|
||||
msgid "recipetype"
|
||||
msgstr ""
|
||||
|
||||
msgid "recipetype:cooking"
|
||||
msgstr ""
|
||||
|
||||
msgid "rock"
|
||||
msgstr ""
|
||||
|
||||
msgid "sand"
|
||||
msgstr ""
|
||||
|
||||
msgid "sapling"
|
||||
msgstr ""
|
||||
|
||||
msgid "seed"
|
||||
msgstr ""
|
||||
|
||||
msgid "shape"
|
||||
msgstr ""
|
||||
|
||||
msgid "slab"
|
||||
msgstr ""
|
||||
|
||||
msgid "snappy"
|
||||
msgstr ""
|
||||
|
||||
msgid "snowy"
|
||||
msgstr ""
|
||||
|
||||
msgid "soil"
|
||||
msgstr ""
|
||||
|
||||
msgid "soil:1"
|
||||
msgstr ""
|
||||
|
||||
msgid "soil:2"
|
||||
msgstr ""
|
||||
|
||||
msgid "soil:3"
|
||||
msgstr ""
|
||||
|
||||
msgid "spreading_dirt_type"
|
||||
msgstr ""
|
||||
|
||||
msgid "stair"
|
||||
msgstr ""
|
||||
|
||||
msgid "stick"
|
||||
msgstr ""
|
||||
|
||||
msgid "stone"
|
||||
msgstr ""
|
||||
|
||||
msgid "surface_hot"
|
||||
msgstr ""
|
||||
|
||||
msgid "tar_block"
|
||||
msgstr ""
|
||||
|
||||
msgid "tool"
|
||||
msgstr ""
|
||||
|
||||
msgid "tool:full_punch_interval"
|
||||
msgstr ""
|
||||
|
||||
msgid "tool:max_drop_level"
|
||||
msgstr ""
|
||||
|
||||
msgid "torch"
|
||||
msgstr ""
|
||||
|
||||
msgid "translucent"
|
||||
msgstr ""
|
||||
|
||||
msgid "tree"
|
||||
msgstr ""
|
||||
|
||||
msgid "type"
|
||||
msgstr ""
|
||||
|
||||
msgid "type:craft"
|
||||
msgstr ""
|
||||
|
||||
msgid "type:node"
|
||||
msgstr ""
|
||||
|
||||
msgid "type:tool"
|
||||
msgstr ""
|
||||
|
||||
msgid "ud_param2_colorable"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:black"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:blue"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:cyan"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:dark:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:darkgrey"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:green"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:grey"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:light"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:light:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:orange"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:red"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:red:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:violet"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:white"
|
||||
msgstr ""
|
||||
|
||||
msgid "unicolor:yellow"
|
||||
msgstr ""
|
||||
|
||||
msgid "vessel"
|
||||
msgstr ""
|
||||
|
||||
msgid "wall"
|
||||
msgstr ""
|
||||
|
||||
msgid "water"
|
||||
msgstr ""
|
||||
|
||||
msgid "water_bucket"
|
||||
msgstr ""
|
||||
|
||||
msgid "wet"
|
||||
msgstr ""
|
||||
|
||||
msgid "wood"
|
||||
msgstr ""
|
||||
|
||||
msgid "wool"
|
||||
msgstr ""
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
name = smart_inventory
|
||||
title = Smart Inventory
|
||||
author = bell07
|
||||
license = CC0
|
|
@ -1,33 +0,0 @@
|
|||
if not minetest.get_modpath("awards") then
|
||||
return
|
||||
end
|
||||
|
||||
local function awards_callback(state)
|
||||
local codebox = state:element("code", { name = "code", code = "", playername = state.location.rootState.location.player })
|
||||
codebox:onBuild(function(self)
|
||||
local formspec = awards.getFormspec(self.data.playername, self.data.playername, self.data.awards_idx or 1)
|
||||
|
||||
-- patch elememt sizes and positions
|
||||
formspec = formspec:gsub('textarea%[0.25,3.75;3.9,4.2', 'textarea[-0.75,3.75;5.9,4.2')
|
||||
formspec = formspec:gsub('box%[%-0.05,3.75;3.9,4.2', 'box[-1.05,3.75;5.9,4.2')
|
||||
formspec = formspec:gsub('textlist%[4,0;3.8,8.6', 'textlist[6,0;6.8,8.6')
|
||||
self.data.code = "container[3,0]".. formspec .."container_end[]"
|
||||
end)
|
||||
|
||||
state:onInput(function(state, fields, player)
|
||||
if fields.awards then
|
||||
local event = minetest.explode_textlist_event(fields.awards)
|
||||
if event.type == "CHG" then
|
||||
state:get("code").data.awards_idx = event.index
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
smart_inventory.register_page({
|
||||
name = "awards",
|
||||
icon = "awards_ui_icon.png",
|
||||
tooltip = "Awards",
|
||||
smartfs_callback = awards_callback,
|
||||
sequence = 25,
|
||||
})
|
|
@ -1,760 +0,0 @@
|
|||
local cache = smart_inventory.cache
|
||||
local crecipes = smart_inventory.crecipes
|
||||
local doc_addon = smart_inventory.doc_addon
|
||||
local ui_tools = smart_inventory.ui_tools
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Update recipe preview item informations about the selected item
|
||||
-----------------------------------------------------
|
||||
local function update_crafting_preview(state)
|
||||
local player = state.location.rootState.location.player
|
||||
local listentry = state.param.crafting_recipes_preview_listentry
|
||||
local selected = state.param.crafting_recipes_preview_selected
|
||||
local itemdef = listentry.itemdef
|
||||
local inf_state = state:get("inf_area"):getContainerState()
|
||||
local cr_type_img = state:get("cr_type_img")
|
||||
local craft_result = inf_state:get("craft_result")
|
||||
local group_list = inf_state:get("item_groups")
|
||||
|
||||
-- get recipe to display, check paging buttons needed
|
||||
local all_recipes
|
||||
local valid_recipes = {}
|
||||
local recipe
|
||||
local revealed_items_cache = {}
|
||||
|
||||
if listentry.recipes then -- preselected recipes (ie. craftable)
|
||||
all_recipes = listentry.recipes
|
||||
elseif cache.citems[listentry.item] then -- check all available recipes (ie. search)
|
||||
all_recipes = cache.citems[listentry.item].in_output_recipe or {}
|
||||
else -- no recipes
|
||||
all_recipes = {}
|
||||
end
|
||||
|
||||
for _, recipe in ipairs(all_recipes) do
|
||||
if crecipes.crecipes[recipe]:is_revealed(player, revealed_items_cache) then
|
||||
table.insert(valid_recipes, recipe)
|
||||
end
|
||||
end
|
||||
|
||||
if valid_recipes[1] then
|
||||
if not valid_recipes[selected] then
|
||||
selected = 1
|
||||
end
|
||||
state.param.crafting_recipes_preview_selected = selected
|
||||
if selected > 1 and valid_recipes[selected-1] then
|
||||
state:get("preview_prev"):setVisible(true)
|
||||
else
|
||||
state:get("preview_prev"):setVisible(false)
|
||||
end
|
||||
if valid_recipes[selected+1] then
|
||||
state:get("preview_next"):setVisible(true)
|
||||
else
|
||||
state:get("preview_next"):setVisible(false)
|
||||
end
|
||||
|
||||
if valid_recipes[selected] then
|
||||
recipe = valid_recipes[selected]
|
||||
local crecipe = crecipes.crecipes[recipe]
|
||||
if crecipe then
|
||||
recipe = crecipe:get_with_placeholder(player, state.param.crafting_items_in_inventory)
|
||||
end
|
||||
end
|
||||
else
|
||||
state:get("preview_prev"):setVisible(false)
|
||||
state:get("preview_next"):setVisible(false)
|
||||
end
|
||||
|
||||
-- display the recipe result or selected item
|
||||
if recipe then
|
||||
if recipe.type == "normal" then
|
||||
state:get("cr_type"):setText("")
|
||||
cr_type_img:setVisible(false)
|
||||
state:get("ac1"):setVisible(true)
|
||||
elseif recipe.type == "cooking" then
|
||||
state:get("cr_type"):setText(recipe.type)
|
||||
state:get("cr_type"):setText("")
|
||||
cr_type_img:setVisible(true)
|
||||
cr_type_img:setImage("smart_inventory_furnace.png")
|
||||
state:get("ac1"):setVisible(false)
|
||||
else
|
||||
state:get("cr_type"):setText(recipe.type)
|
||||
cr_type_img:setVisible(false)
|
||||
state:get("ac1"):setVisible(false)
|
||||
end
|
||||
craft_result:setImage(recipe.output)
|
||||
craft_result:setVisible()
|
||||
state:get("craft_preview"):setCraft(recipe)
|
||||
else
|
||||
state:get("cr_type"):setText("")
|
||||
state:get("craft_preview"):setCraft(nil)
|
||||
cr_type_img:setVisible(false)
|
||||
state:get("ac1"):setVisible(false)
|
||||
if itemdef then
|
||||
craft_result:setVisible(true)
|
||||
craft_result:setImage(itemdef.name)
|
||||
else
|
||||
craft_result:setVisible(false)
|
||||
end
|
||||
end
|
||||
|
||||
-- display docs icon if revealed item
|
||||
if smart_inventory.doc_items_mod then
|
||||
inf_state:get("doc_btn"):setVisible(false)
|
||||
local outitem = craft_result:getImage()
|
||||
if outitem then
|
||||
for z in outitem:gmatch("[^%s]+") do
|
||||
if doc_addon.is_revealed_item(z, player) then
|
||||
inf_state:get("doc_btn"):setVisible(true)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- update info area
|
||||
if itemdef then
|
||||
inf_state:get("info1"):setText(itemdef.description)
|
||||
inf_state:get("info2"):setText("("..itemdef.name..")")
|
||||
if itemdef._doc_items_longdesc then
|
||||
inf_state:get("info3"):setText(itemdef._doc_items_longdesc)
|
||||
else
|
||||
inf_state:get("info3"):setText("")
|
||||
end
|
||||
|
||||
group_list:clearItems()
|
||||
cache.add_item(listentry.itemdef) -- Note: this addition does not affect the already prepared root lists
|
||||
if cache.citems[itemdef.name] then
|
||||
for _, groupdef in ipairs(ui_tools.get_tight_groups(cache.citems[itemdef.name].cgroups)) do
|
||||
group_list:addItem(groupdef.group_desc)
|
||||
end
|
||||
end
|
||||
elseif listentry.item then
|
||||
inf_state:get("info1"):setText("")
|
||||
inf_state:get("info2"):setText("("..listentry.item..")")
|
||||
inf_state:get("info3"):setText("")
|
||||
else
|
||||
inf_state:get("info1"):setText("")
|
||||
inf_state:get("info2"):setText("")
|
||||
inf_state:get("info3"):setText("")
|
||||
group_list:clearItems()
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Update the group selection table
|
||||
-----------------------------------------------------
|
||||
local function update_group_selection(state, rebuild)
|
||||
local grouped = state.param.crafting_grouped_items
|
||||
local groups_sel = state:get("groups_sel")
|
||||
local grid = state:get("buttons_grid")
|
||||
local label = state:get("inf_area"):getContainerState():get("groups_label")
|
||||
|
||||
if rebuild then
|
||||
state.param.crafting_group_list = ui_tools.update_group_selection(grouped, groups_sel, state.param.crafting_group_list)
|
||||
end
|
||||
|
||||
local sel_id = groups_sel:getSelected()
|
||||
if state.param.crafting_group_list[sel_id] then
|
||||
state.param.crafting_craftable_list = grouped[state.param.crafting_group_list[sel_id]].items
|
||||
table.sort(state.param.crafting_craftable_list, function(a,b)
|
||||
return a.sort_value < b.sort_value
|
||||
end)
|
||||
grid:setList(state.param.crafting_craftable_list)
|
||||
label:setText(groups_sel:getSelectedItem())
|
||||
else
|
||||
label:setText("Empty List")
|
||||
grid:setList({})
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Update the items list
|
||||
-----------------------------------------------------
|
||||
local function update_from_recipelist(state, recipelist, preview_item, replace_not_in_list)
|
||||
local old_preview_entry, old_preview_item, new_preview_entry, new_preview_item
|
||||
if state.param.crafting_recipes_preview_listentry then
|
||||
old_preview_item = state.param.crafting_recipes_preview_listentry.item
|
||||
end
|
||||
if preview_item == "" then
|
||||
new_preview_item = nil
|
||||
else
|
||||
new_preview_item = preview_item
|
||||
end
|
||||
|
||||
local duplicate_index_tmp = {}
|
||||
local craftable_itemlist = {}
|
||||
|
||||
for recipe, _ in pairs(recipelist) do
|
||||
local def = crecipes.crecipes[recipe].out_item
|
||||
local itemname = def.name
|
||||
if duplicate_index_tmp[itemname] then
|
||||
table.insert(duplicate_index_tmp[itemname].recipes, recipe)
|
||||
else
|
||||
local entry = {}
|
||||
for k,v in pairs(cache.citems[itemname].ui_item) do
|
||||
entry[k] = v
|
||||
end
|
||||
|
||||
entry.recipes = {}
|
||||
duplicate_index_tmp[itemname] = entry
|
||||
table.insert(entry.recipes, recipe)
|
||||
table.insert(craftable_itemlist, entry)
|
||||
if new_preview_item and itemname == new_preview_item then
|
||||
new_preview_entry = entry
|
||||
end
|
||||
if old_preview_item and itemname == old_preview_item then
|
||||
old_preview_entry = entry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- update crafting preview if the old is not in list anymore
|
||||
if new_preview_item then
|
||||
if not replace_not_in_list or not old_preview_entry then
|
||||
if not new_preview_entry then
|
||||
new_preview_entry = {
|
||||
itemdef = minetest.registered_items[new_preview_item],
|
||||
item = new_preview_item
|
||||
}
|
||||
end
|
||||
state.param.crafting_recipes_preview_selected = 1
|
||||
state.param.crafting_recipes_preview_listentry = new_preview_entry
|
||||
update_crafting_preview(state)
|
||||
if state:get("info_tog"):getId() == 1 then
|
||||
state:get("info_tog"):submit()
|
||||
end
|
||||
end
|
||||
elseif replace_not_in_list and not old_preview_entry then
|
||||
state.param.crafting_recipes_preview_selected = 1
|
||||
state.param.crafting_recipes_preview_listentry = {}
|
||||
update_crafting_preview(state)
|
||||
end
|
||||
|
||||
-- update the groups selection
|
||||
state.param.crafting_grouped_items = ui_tools.get_list_grouped(craftable_itemlist)
|
||||
update_group_selection(state, true)
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Build list matching the placed grid
|
||||
-----------------------------------------------------
|
||||
local function update_from_grid(state, craft_grid, lookup_item)
|
||||
-- get all grid items for reference
|
||||
local player = state.location.rootState.location.player
|
||||
local reference_items = {}
|
||||
local items_hash = ""
|
||||
for _, stack in ipairs(craft_grid) do
|
||||
local name = stack:get_name()
|
||||
if name and name ~= "" then
|
||||
reference_items[name] = true
|
||||
items_hash=items_hash.."|"..name
|
||||
else
|
||||
items_hash=items_hash.."|empty"
|
||||
end
|
||||
end
|
||||
|
||||
if items_hash ~= state.param.survival_grid_items_hash then
|
||||
state.param.survival_grid_items_hash = items_hash
|
||||
if next(reference_items) then
|
||||
-- update the grid with matched recipe items
|
||||
local recipes = crecipes.get_recipes_started_craft(player, craft_grid, reference_items)
|
||||
update_from_recipelist(state, recipes, lookup_item, true) -- replace_not_in_list=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Lookup for item lookup_item
|
||||
-----------------------------------------------------
|
||||
local function do_lookup_item(state, playername, lookup_item)
|
||||
state.param.crafting_items_in_inventory = state.param.invobj:get_items()
|
||||
state.param.crafting_items_in_inventory[lookup_item] = true -- prefer in recipe preview
|
||||
-- get all craftable recipes with lookup-item as ingredient. Add recipes of lookup item to the list
|
||||
local recipes = crecipes.get_revealed_recipes_with_items(playername, {[lookup_item] = true })
|
||||
update_from_recipelist(state, recipes, lookup_item)
|
||||
state.param.crafting_ui_controller:update_list_variant("lookup", lookup_item)
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Lookup inventory
|
||||
-----------------------------------------------------
|
||||
local function create_lookup_inv(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local invname = name.."_crafting_inv"
|
||||
local plistname = "crafting_inv_lookup"
|
||||
local listname = "lookup"
|
||||
local pinv = player:get_inventory()
|
||||
local inv = minetest.get_inventory({type="detached", name=invname})
|
||||
if not inv then
|
||||
inv = minetest.create_detached_inventory(invname, {
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
return 0
|
||||
end,
|
||||
allow_put = function(inv, listname, index, stack, player)
|
||||
if pinv:is_empty(plistname) then
|
||||
return 99
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
allow_take = function(inv, listname, index, stack, player)
|
||||
return 99
|
||||
end,
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
pinv:set_stack(plistname, index, stack)
|
||||
local name = player:get_player_name()
|
||||
local state = smart_inventory.get_page_state("crafting", name)
|
||||
do_lookup_item(state, name, stack:get_name())
|
||||
|
||||
-- we are outsite of usual smartfs processing. So trigger the formspec update byself
|
||||
state.location.rootState:show()
|
||||
|
||||
-- put back
|
||||
minetest.after(1, function()
|
||||
-- Check maybe player is away from the game
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
-- Check the player did not removed item from lookup field
|
||||
local pinv = player:get_inventory()
|
||||
local inv = minetest.get_inventory({type="detached", name=invname})
|
||||
local stack = pinv:get_stack(plistname, 1)
|
||||
|
||||
-- put back
|
||||
local applied = pinv:add_item("main", stack)
|
||||
pinv:set_stack(plistname, 1, applied)
|
||||
inv:set_stack(listname, 1, applied)
|
||||
end)
|
||||
end,
|
||||
on_take = function(inv, listname, index, stack, player)
|
||||
pinv:set_stack(plistname, index, nil)
|
||||
end,
|
||||
}, name)
|
||||
end
|
||||
-- copy the item from player:listname inventory to the detached
|
||||
inv:set_size(listname, 1)
|
||||
pinv:set_size(plistname, 1)
|
||||
local stack = pinv:get_stack(plistname, 1)
|
||||
inv:set_stack(listname, 1, stack)
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Page layout definition
|
||||
-----------------------------------------------------
|
||||
local function crafting_callback(state)
|
||||
local player = state.location.rootState.location.player
|
||||
|
||||
-- build up UI controller
|
||||
local ui_controller = {}
|
||||
ui_controller.state = state
|
||||
ui_controller.player = minetest.get_player_by_name(state.location.rootState.location.player)
|
||||
state.param.crafting_ui_controller = ui_controller
|
||||
|
||||
function ui_controller:set_ui_variant(new_ui)
|
||||
-- check if change needed
|
||||
if new_ui == self.toggle1 or new_ui == self.toggle2 then
|
||||
return
|
||||
end
|
||||
|
||||
-- toggle show/hide elements
|
||||
if new_ui == 'list_small' then
|
||||
self.toggle1 = new_ui
|
||||
self.state:get("craft_img2"):setVisible(true) --rahmen oben
|
||||
self.state:get("lookup_icon"):setPosition(10, 4)
|
||||
self.state:get("lookup"):setPosition(10, 4)
|
||||
self.state:get("craftable"):setPosition(11, 4)
|
||||
self.state:get("btn_all"):setPosition(11, 4.5)
|
||||
self.state:get("btn_grid"):setPosition(11.5, 4.0)
|
||||
if smart_inventory.doc_items_mod then
|
||||
self.state:get("reveal_tipp"):setPosition(11.5, 4.5)
|
||||
end
|
||||
self.state:get("search"):setPosition(12.2, 4.5)
|
||||
self.state:get("search_bg"):setPosition(12, 4)
|
||||
self.state:get("search_btn"):setPosition(15.2, 4.2)
|
||||
self.state:get("info_tog"):setPosition(16.2, 4.2)
|
||||
|
||||
self.state:get("buttons_grid_Bg"):setPosition(10, 5)
|
||||
self.state:get("buttons_grid_Bg"):setSize(8, 4)
|
||||
self.state:get("buttons_grid"):reset(10.25, 5.15, 8, 4)
|
||||
|
||||
elseif new_ui == 'list_big' then
|
||||
self.toggle1 = new_ui
|
||||
self.state:get("craft_img2"):setVisible(false) --rahmen oben
|
||||
self.state:get("lookup_icon"):setPosition(10, 0)
|
||||
self.state:get("lookup"):setPosition(10, 0)
|
||||
self.state:get("craftable"):setPosition(11, 0)
|
||||
self.state:get("btn_all"):setPosition(11, 0.5)
|
||||
self.state:get("btn_grid"):setPosition(11.5, 0.0)
|
||||
if smart_inventory.doc_items_mod then
|
||||
self.state:get("reveal_tipp"):setPosition(11.5, 0.5)
|
||||
end
|
||||
self.state:get("search"):setPosition(12.2, 0.5)
|
||||
self.state:get("search_bg"):setPosition(12, 0)
|
||||
self.state:get("search_btn"):setPosition(15.2, 0.2)
|
||||
self.state:get("info_tog"):setPosition(16.2, 0.2)
|
||||
|
||||
self.state:get("groups_sel"):setVisible(false)
|
||||
self.state:get("inf_area"):setVisible(false)
|
||||
|
||||
self.state:get("buttons_grid_Bg"):setPosition(10, 1)
|
||||
self.state:get("buttons_grid_Bg"):setSize(8, 8)
|
||||
self.state:get("buttons_grid"):reset(10.25, 1.15, 8, 8)
|
||||
self.state:get("info_tog"):setId(3)
|
||||
else
|
||||
self.toggle2 = new_ui
|
||||
end
|
||||
|
||||
if self.toggle1 == 'list_small' then
|
||||
if self.toggle2 == 'info' then
|
||||
self.state:get("groups_sel"):setVisible(false)
|
||||
self.state:get("inf_area"):setVisible(true)
|
||||
self.state:get("info_tog"):setId(1)
|
||||
elseif self.toggle2 == 'groups' then
|
||||
self.state:get("groups_sel"):setVisible(true)
|
||||
self.state:get("inf_area"):setVisible(false)
|
||||
self.state:get("info_tog"):setId(2)
|
||||
end
|
||||
end
|
||||
self:save()
|
||||
end
|
||||
|
||||
function ui_controller:update_list_variant(list_variant, add_info)
|
||||
self.add_info = add_info
|
||||
-- reset group selection and search field on proposal mode change
|
||||
if self.list_variant ~= list_variant then
|
||||
self.list_variant = list_variant
|
||||
self.state:get("groups_sel"):setSelected(1)
|
||||
if list_variant ~= "search" then
|
||||
self.state:get("search"):setText("")
|
||||
end
|
||||
end
|
||||
|
||||
-- auto-switch to the groups
|
||||
if list_variant == "lookup" or list_variant == "reveal_tipp" then
|
||||
state.param.crafting_ui_controller:set_ui_variant("info")
|
||||
else
|
||||
state.param.crafting_ui_controller:set_ui_variant("groups")
|
||||
end
|
||||
|
||||
|
||||
state:get("lookup_icon"):setBackground()
|
||||
state:get("search_bg"):setBackground()
|
||||
state:get("craftable"):setBackground()
|
||||
state:get("btn_grid"):setBackground()
|
||||
state:get("btn_all"):setBackground()
|
||||
if smart_inventory.doc_items_mod then
|
||||
state:get("reveal_tipp"):setBackground()
|
||||
end
|
||||
-- highlight the right button
|
||||
if list_variant == "lookup" then
|
||||
state:get("lookup_icon"):setBackground("halo.png")
|
||||
elseif list_variant == "search" then
|
||||
state:get("search_bg"):setBackground("halo.png")
|
||||
elseif list_variant == "craftable" then
|
||||
state:get("craftable"):setBackground("halo.png")
|
||||
elseif list_variant == "grid" then
|
||||
state:get("btn_grid"):setBackground("halo.png")
|
||||
elseif list_variant == "btn_all" then
|
||||
state:get("btn_all"):setBackground("halo.png")
|
||||
elseif list_variant == "reveal_tipp" then
|
||||
state:get("reveal_tipp"):setBackground("halo.png")
|
||||
end
|
||||
self:save()
|
||||
end
|
||||
|
||||
function ui_controller:save()
|
||||
local savedata = minetest.deserialize(self.player:get_attribute("smart_inventory_settings")) or {}
|
||||
savedata.survival_list_variant = self.list_variant
|
||||
savedata.survival_toggle1 = self.toggle1
|
||||
savedata.survival_toggle2 = self.toggle2
|
||||
savedata.survival_lookup_item = self.lookup_item
|
||||
savedata.survival_add_info = self.add_info
|
||||
self.player:set_attribute("smart_inventory_settings", minetest.serialize(savedata))
|
||||
end
|
||||
|
||||
function ui_controller:restore()
|
||||
local savedata = minetest.deserialize(self.player:get_attribute("smart_inventory_settings")) or {}
|
||||
|
||||
if savedata.survival_toggle1 then
|
||||
self:set_ui_variant(savedata.survival_toggle1)
|
||||
end
|
||||
if savedata.survival_toggle2 then
|
||||
self:set_ui_variant(savedata.survival_toggle2)
|
||||
end
|
||||
if savedata.survival_list_variant then
|
||||
if savedata.survival_list_variant == "search" then
|
||||
local ui_text = self.state:get(savedata.survival_list_variant)
|
||||
ui_text:setText(savedata.survival_add_info)
|
||||
ui_text:submit_key_enter("unused", self.state.location.rootState.location.player)
|
||||
elseif savedata.survival_list_variant == "lookup" then
|
||||
do_lookup_item(self.state, self.state.location.rootState.location.player, savedata.survival_add_info)
|
||||
else
|
||||
local ui_button = self.state:get(savedata.survival_list_variant)
|
||||
if ui_button then
|
||||
ui_button:submit("unused", self.state.location.rootState.location.player)
|
||||
end
|
||||
end
|
||||
else
|
||||
self.state:get("craftable"):submit("unused", self.state.location.rootState.location.player)
|
||||
self:set_ui_variant("groups")
|
||||
self:update_list_variant("craftable")
|
||||
end
|
||||
end
|
||||
|
||||
-- set inventory style
|
||||
state:element("code", {name = "additional_code", code =
|
||||
"listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]"..
|
||||
"listring[current_player;main]listring[current_player;craft]"
|
||||
})
|
||||
|
||||
--Inventorys / left site
|
||||
state:inventory(1, 5, 8, 4,"main")
|
||||
state:inventory(1.2, 0.2, 3, 3,"craft")
|
||||
state:inventory(4.3, 1.2, 1, 1,"craftpreview")
|
||||
state:background(1, 0, 4.5, 3.5, "img1", "menu_bg.png")
|
||||
|
||||
|
||||
-- crafting helper buttons
|
||||
local btn_ac1 = state:image_button(4.4, 0.3, 0.8, 0.8, "ac1", "", "smart_inventory_preview_to_crafting_field.png")
|
||||
btn_ac1:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "crafting", "ac1")
|
||||
local grid = state:get("craft_preview"):getCraft()
|
||||
state.param.invobj:craft_item(grid)
|
||||
end)
|
||||
btn_ac1:setVisible(false)
|
||||
|
||||
-- swap slots buttons
|
||||
state:image_button(0, 6, 1, 1, "swap1", "", "smart_inventory_swapline_button.png"):onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "crafting", "swap1")
|
||||
state.param.invobj:swap_row_to_top(2)
|
||||
end)
|
||||
state:image_button(0, 7, 1, 1, "swap2", "", "smart_inventory_swapline_button.png"):onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "crafting", "swap2")
|
||||
state.param.invobj:swap_row_to_top(3)
|
||||
end)
|
||||
state:image_button(0, 8, 1, 1, "swap3", "", "smart_inventory_swapline_button.png"):onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "crafting", "swap3")
|
||||
state.param.invobj:swap_row_to_top(4)
|
||||
end)
|
||||
|
||||
ui_tools.create_trash_inv(state, player)
|
||||
state:image(8,9,1,1,"trash_icon","smart_inventory_trash.png")
|
||||
state:inventory(8, 9, 1, 1, "trash"):useDetached(player.."_trash_inv")
|
||||
|
||||
local btn_compress = state:image_button(1, 3.8, 1, 1, "compress", "","smart_inventory_compress_button.png")
|
||||
btn_compress:setTooltip("Merge stacks with same items to get free place")
|
||||
btn_compress:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "crafting", "compress")
|
||||
state.param.invobj:compress()
|
||||
end)
|
||||
|
||||
local btn_sweep = state:image_button(2, 3.8, 1, 1, "clear", "", "smart_inventory_sweep_button.png")
|
||||
btn_sweep:setTooltip("Move all items from crafting grid back to inventory")
|
||||
btn_sweep:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "crafting", "clear")
|
||||
state.param.invobj:sweep_crafting_inventory()
|
||||
end)
|
||||
|
||||
-- recipe preview area
|
||||
smart_inventory.smartfs_elements.craft_preview(state, 6, 0, "craft_preview"):onButtonClicked(function(self, item, player)
|
||||
do_lookup_item(state, player, item)
|
||||
end)
|
||||
state:image(7,2.8,1,1,"cr_type_img",""):setVisible(false)
|
||||
state:label(7,3,"cr_type", "")
|
||||
local pr_prev_btn = state:button(6, 3, 1, 0.5, "preview_prev", "<<")
|
||||
pr_prev_btn:onClick(function(self, state, player)
|
||||
state.param.crafting_recipes_preview_selected = state.param.crafting_recipes_preview_selected -1
|
||||
update_crafting_preview(state)
|
||||
end)
|
||||
pr_prev_btn:setVisible(false)
|
||||
local pr_next_btn = state:button(8, 3, 1, 0.5, "preview_next", ">>")
|
||||
pr_next_btn:onClick(function(self, state, player)
|
||||
state.param.crafting_recipes_preview_selected = state.param.crafting_recipes_preview_selected +1
|
||||
update_crafting_preview(state)
|
||||
end)
|
||||
pr_next_btn:setVisible(false)
|
||||
|
||||
-- (dynamic-1) group selection
|
||||
local group_sel = state:listbox(10.2, 0.15, 7.6, 3.6, "groups_sel",nil, true)
|
||||
group_sel:onClick(function(self, state, player)
|
||||
local selected = self:getSelectedItem()
|
||||
if selected then
|
||||
update_group_selection(state, false)
|
||||
end
|
||||
end)
|
||||
|
||||
-- (dynamic-2) item preview area
|
||||
state:background(10.0, 0.1, 8, 3.8, "craft_img2", "minimap_overlay_square.png")
|
||||
local inf_area = state:view(6.4, 0.1, "inf_area")
|
||||
local inf_state = inf_area:getContainerState()
|
||||
inf_state:label(11.5,0.5,"info1", "")
|
||||
inf_state:label(11.5,1.0,"info2", "")
|
||||
inf_state:label(11.5,1.5,"info3", "")
|
||||
inf_state:item_image(10.2,0.3, 1, 1, "craft_result",nil):setVisible(false)
|
||||
if smart_inventory.doc_items_mod then
|
||||
local doc_btn = inf_state:image_button(10.4,2.3, 0.7, 0.7, "doc_btn","", "doc_button_icon_lores.png")
|
||||
doc_btn:setTooltip("Show documentation for revealed item")
|
||||
doc_btn:setVisible(false)
|
||||
doc_btn:onClick(function(self, state, player)
|
||||
local outitem = state:get("craft_result"):getImage()
|
||||
if outitem then
|
||||
for z in outitem:gmatch("[^%s]+") do
|
||||
if minetest.registered_items[z] then
|
||||
doc_addon.show(z, player)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
inf_state:label(10.3, 3.25, "groups_label", "All")
|
||||
|
||||
inf_state:listbox(12, 2, 5.7, 1.3, "item_groups",nil, true)
|
||||
inf_area:setVisible(false)
|
||||
|
||||
-- Lookup
|
||||
create_lookup_inv(player)
|
||||
state:image(10, 4, 1, 1,"lookup_icon", "smart_inventory_lookup_field.png")
|
||||
local inv_lookup = state:inventory(10, 4.0, 1, 1,"lookup"):useDetached(player.."_crafting_inv")
|
||||
|
||||
|
||||
-- Get craftable by items in inventory
|
||||
local btn_craftable = state:image_button(11, 4, 0.5, 0.5, "craftable", "", "smart_inventory_craftable_button.png")
|
||||
btn_craftable:setTooltip("Show items crafteable by items in inventory")
|
||||
btn_craftable:onClick(function(self, state, player)
|
||||
state.param.crafting_items_in_inventory = state.param.invobj:get_items()
|
||||
local craftable = crecipes.get_recipes_craftable(player, state.param.crafting_items_in_inventory)
|
||||
update_from_recipelist(state, craftable)
|
||||
ui_controller:update_list_variant("craftable")
|
||||
end)
|
||||
|
||||
local grid_btn = state:image_button(11.5, 4, 0.5, 0.5, "btn_grid", "", "smart_inventory_craftable_button.png")
|
||||
grid_btn:setTooltip("Search for recipes matching the grid")
|
||||
grid_btn:onClick(function(self, state, player)
|
||||
local player = state.location.rootState.location.player
|
||||
state.param.crafting_ui_controller:update_list_variant("grid")
|
||||
local craft_grid = state.param.invobj.inventory:get_list("craft")
|
||||
local ret_item = state.param.invobj.inventory:get_list("craftpreview")[1]
|
||||
update_from_grid(state, craft_grid, ret_item:get_name())
|
||||
end)
|
||||
|
||||
-- Get craftable by items in inventory
|
||||
local btn_all = state:image_button(11, 4.5, 0.5, 0.5, "btn_all", "", "smart_inventory_creative_button.png")
|
||||
if smart_inventory.doc_items_mod then
|
||||
btn_all:setTooltip("Show all already revealed items")
|
||||
else
|
||||
btn_all:setTooltip("Show all items")
|
||||
end
|
||||
btn_all:onClick(function(self, state, player)
|
||||
local all_revealed = ui_tools.filter_by_revealed(ui_tools.root_list_all, player, true)
|
||||
state.param.crafting_recipes_preview_selected = 1
|
||||
state.param.crafting_recipes_preview_listentry = all_revealed[1] or {}
|
||||
update_crafting_preview(state)
|
||||
state.param.crafting_grouped_items = ui_tools.get_list_grouped(all_revealed)
|
||||
|
||||
update_group_selection(state, true)
|
||||
ui_controller:update_list_variant("btn_all")
|
||||
end)
|
||||
|
||||
-- Reveal tipps button
|
||||
if smart_inventory.doc_items_mod then
|
||||
local reveal_button = state:image_button(11.5, 4.5, 0.5, 0.5, "reveal_tipp", "", "smart_inventory_reveal_tips_button.png")
|
||||
reveal_button:setTooltip("Show proposal what should be crafted to reveal more items")
|
||||
reveal_button:onClick(function(self, state, player)
|
||||
local all_revealed = ui_tools.filter_by_revealed(ui_tools.root_list_all, player)
|
||||
local top_revealed = ui_tools.filter_by_top_reveal(all_revealed, player)
|
||||
state.param.crafting_recipes_preview_selected = 1
|
||||
state.param.crafting_recipes_preview_listentry = top_revealed[1] or {}
|
||||
update_crafting_preview(state)
|
||||
state.param.crafting_grouped_items = ui_tools.get_list_grouped(top_revealed)
|
||||
|
||||
update_group_selection(state, true)
|
||||
ui_controller:update_list_variant("reveal_tipp")
|
||||
end)
|
||||
end
|
||||
|
||||
-- search
|
||||
state:background(12, 4, 4, 0.9, "search_bg", nil) --field background not usable
|
||||
local searchfield = state:field(12.2, 4.5, 3.4, 0.5, "search")
|
||||
searchfield:setCloseOnEnter(false)
|
||||
searchfield:onKeyEnter(function(self, state, player)
|
||||
local search_string = self:getText()
|
||||
if string.len(search_string) < 3 then
|
||||
return
|
||||
end
|
||||
|
||||
local filtered_list = ui_tools.filter_by_searchstring(ui_tools.root_list_all, search_string, state.location.rootState.lang_code)
|
||||
filtered_list = ui_tools.filter_by_revealed(filtered_list, player)
|
||||
state.param.crafting_grouped_items = ui_tools.get_list_grouped(filtered_list)
|
||||
update_group_selection(state, true)
|
||||
ui_controller:update_list_variant("search", search_string)
|
||||
end)
|
||||
|
||||
local search_button = state:button(15.2, 4.2, 0.8, 0.5, "search_btn", "Go")
|
||||
search_button:setTooltip("Perform search action")
|
||||
search_button:onClick(function(self, state, player)
|
||||
state:get("search"):submit_key_enter("", player)
|
||||
end)
|
||||
|
||||
-- groups toggle
|
||||
local info_tog = state:toggle(16.2,4.2,1.8,0.5, "info_tog", {"Info", "Groups", "Hide"})
|
||||
info_tog:onToggle(function(self, state, player)
|
||||
local id = self:getId()
|
||||
if id == 1 then
|
||||
state.param.crafting_ui_controller:set_ui_variant("list_small")
|
||||
state.param.crafting_ui_controller:set_ui_variant("info")
|
||||
elseif id == 2 then
|
||||
state.param.crafting_ui_controller:set_ui_variant("list_small")
|
||||
state.param.crafting_ui_controller:set_ui_variant("groups")
|
||||
elseif id == 3 then
|
||||
state.param.crafting_ui_controller:set_ui_variant("list_big")
|
||||
end
|
||||
end)
|
||||
|
||||
-- craftable items grid
|
||||
state:background(10, 5, 8, 4, "buttons_grid_Bg", "minimap_overlay_square.png")
|
||||
local grid = smart_inventory.smartfs_elements.buttons_grid(state, 10.25, 5.15, 8 , 4, "buttons_grid", 0.75,0.75)
|
||||
grid:onClick(function(self, state, index, player)
|
||||
local listentry = state.param.crafting_craftable_list[index]
|
||||
if ui_controller.list_variant == "lookup" then
|
||||
do_lookup_item(state, state.location.rootState.location.player, listentry.item)
|
||||
else
|
||||
state.param.crafting_recipes_preview_selected = 1
|
||||
state.param.crafting_recipes_preview_listentry = listentry
|
||||
update_crafting_preview(state)
|
||||
end
|
||||
state.param.crafting_ui_controller:set_ui_variant("info")
|
||||
end)
|
||||
|
||||
ui_controller:restore()
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Register page in smart_inventory
|
||||
-----------------------------------------------------
|
||||
smart_inventory.register_page({
|
||||
name = "crafting",
|
||||
tooltip = "Craft new items",
|
||||
icon = "smart_inventory_crafting_inventory_button.png",
|
||||
smartfs_callback = crafting_callback,
|
||||
sequence = 10
|
||||
})
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Use lookup for predict item
|
||||
-----------------------------------------------------
|
||||
minetest.register_craft_predict(function(stack, player, old_craft_grid, craft_inv)
|
||||
local name = player:get_player_name()
|
||||
local state = smart_inventory.get_page_state("crafting", name)
|
||||
if not state then
|
||||
return
|
||||
end
|
||||
|
||||
if state.param.crafting_ui_controller.list_variant ~= 'grid' then
|
||||
return
|
||||
end
|
||||
update_from_grid(state, old_craft_grid, stack:get_name())
|
||||
state.location.rootState:show()
|
||||
end)
|
|
@ -1,310 +0,0 @@
|
|||
local cache = smart_inventory.cache
|
||||
local ui_tools = smart_inventory.ui_tools
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Update on group selection change
|
||||
-----------------------------------------------------
|
||||
local function update_group_selection(state, changed_group)
|
||||
local grouped = state.param.creative_grouped_items
|
||||
local groups_sel1 = state:get("groups_sel1")
|
||||
local groups_sel2 = state:get("groups_sel2")
|
||||
local groups_sel3 = state:get("groups_sel3")
|
||||
local grid = state:get("buttons_grid")
|
||||
local outlist
|
||||
|
||||
if state.param.creative_grouped_shape_items and
|
||||
next(state.param.creative_grouped_shape_items) then
|
||||
local group_info = {}
|
||||
group_info.name = "shape"
|
||||
group_info.cgroup = cache.cgroups["shape"]
|
||||
group_info.group_desc = "#01DF74> "..group_info.cgroup.group_desc
|
||||
group_info.items = state.param.creative_grouped_shape_items
|
||||
grouped["shape"] = group_info
|
||||
end
|
||||
|
||||
-- update group 1
|
||||
if changed_group < 1 or not state.param.creative_group_list1 then
|
||||
state.param.creative_group_list1 = ui_tools.update_group_selection(grouped, groups_sel1, state.param.creative_group_list1)
|
||||
end
|
||||
|
||||
local sel_id = groups_sel1:getSelected()
|
||||
if state.param.creative_group_list1[sel_id] == "all"
|
||||
or not state.param.creative_group_list1[sel_id]
|
||||
or not grouped[state.param.creative_group_list1[sel_id]] then
|
||||
outlist = grouped["all"].items
|
||||
groups_sel2:clearItems()
|
||||
groups_sel3:clearItems()
|
||||
else
|
||||
-- update group 2
|
||||
grouped = ui_tools.get_list_grouped(grouped[state.param.creative_group_list1[sel_id]].items)
|
||||
if changed_group < 2 or not state.param.creative_group_list2 then
|
||||
state.param.creative_group_list2 = ui_tools.update_group_selection(grouped, groups_sel2, state.param.creative_group_list2)
|
||||
end
|
||||
|
||||
sel_id = groups_sel2:getSelected()
|
||||
if state.param.creative_group_list2[sel_id] == "all"
|
||||
or not state.param.creative_group_list2[sel_id]
|
||||
or not grouped[state.param.creative_group_list2[sel_id]] then
|
||||
outlist = grouped["all"].items
|
||||
groups_sel3:clearItems()
|
||||
else
|
||||
-- update group 3
|
||||
grouped = ui_tools.get_list_grouped(grouped[state.param.creative_group_list2[sel_id]].items)
|
||||
if changed_group < 3 or not state.param.creative_group_list3 then
|
||||
state.param.creative_group_list3 = ui_tools.update_group_selection(grouped, groups_sel3, state.param.creative_group_list3)
|
||||
end
|
||||
sel_id = groups_sel3:getSelected()
|
||||
outlist = grouped[state.param.creative_group_list3[sel_id]].items
|
||||
end
|
||||
end
|
||||
|
||||
-- update grid list
|
||||
if outlist then
|
||||
table.sort(outlist, function(a,b)
|
||||
return a.sort_value < b.sort_value
|
||||
end)
|
||||
grid:setList(outlist)
|
||||
state.param.creative_outlist = outlist
|
||||
else
|
||||
grid:setList({})
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Page layout definition
|
||||
-----------------------------------------------------
|
||||
local function creative_callback(state)
|
||||
|
||||
local player = state.location.rootState.location.player
|
||||
|
||||
-- build up UI controller
|
||||
local ui_controller = {}
|
||||
ui_controller.state = state
|
||||
state.param.creative_ui_controller = ui_controller
|
||||
ui_controller.player = minetest.get_player_by_name(state.location.rootState.location.player)
|
||||
|
||||
function ui_controller:set_ui_variant(new_ui)
|
||||
-- check if change needed
|
||||
if new_ui == self.ui_toggle then
|
||||
return
|
||||
end
|
||||
|
||||
-- toggle show/hide elements
|
||||
if new_ui == 'list_small' then
|
||||
self.ui_toggle = new_ui
|
||||
self.state:get("groups_sel1"):setSize(5.6, 3)
|
||||
self.state:get("groups_sel2"):setVisible(true)
|
||||
self.state:get("groups_sel3"):setVisible(true)
|
||||
self.state:get("buttons_grid"):reset(9.55, 3.75, 9.0 , 6.5)
|
||||
self.state:get("buttons_grid_bg"):setPosition(9.2, 3.5)
|
||||
self.state:get("buttons_grid_bg"):setSize(9.5, 6.5)
|
||||
self.state:get("btn_tog"):setId(1)
|
||||
elseif new_ui == 'list_big' then
|
||||
self.ui_toggle = new_ui
|
||||
self.state:get("groups_sel1"):setSize(7.8, 3)
|
||||
self.state:get("groups_sel2"):setVisible(false)
|
||||
self.state:get("groups_sel3"):setVisible(false)
|
||||
self.state:get("buttons_grid"):reset(9.55, 0.25, 9.0 , 10)
|
||||
self.state:get("buttons_grid_bg"):setPosition(9.2, 0)
|
||||
self.state:get("buttons_grid_bg"):setSize(9.5, 10)
|
||||
self.state:get("btn_tog"):setId(2)
|
||||
end
|
||||
self:save()
|
||||
end
|
||||
function ui_controller:save()
|
||||
local savedata = minetest.deserialize(self.player:get_attribute("smart_inventory_settings")) or {}
|
||||
savedata.creative_ui_toggle = self.ui_toggle
|
||||
self.player:set_attribute("smart_inventory_settings", minetest.serialize(savedata))
|
||||
end
|
||||
|
||||
function ui_controller:restore()
|
||||
local savedata = minetest.deserialize(self.player:get_attribute("smart_inventory_settings")) or {}
|
||||
|
||||
if savedata.creative_ui_toggle then
|
||||
ui_controller:set_ui_variant(savedata.creative_ui_toggle)
|
||||
end
|
||||
end
|
||||
|
||||
-- groups 1-3
|
||||
local group_sel1 = state:listbox(1, 0.15, 5.6, 3, "groups_sel1",nil, false)
|
||||
group_sel1:onClick(function(self, state, player)
|
||||
local selected = self:getSelectedItem()
|
||||
if selected then
|
||||
state:get("groups_sel2"):setSelected(1)
|
||||
state:get("groups_sel3"):setSelected(1)
|
||||
update_group_selection(state, 1)
|
||||
end
|
||||
end)
|
||||
|
||||
local group_sel2 = state:listbox(7, 0.15, 5.6, 3, "groups_sel2",nil, false)
|
||||
group_sel2:onClick(function(self, state, player)
|
||||
local selected = self:getSelectedItem()
|
||||
if selected then
|
||||
state:get("groups_sel3"):setSelected(1)
|
||||
update_group_selection(state, 2)
|
||||
end
|
||||
end)
|
||||
|
||||
local group_sel3 = state:listbox(13, 0.15, 5.6, 3, "groups_sel3",nil, false)
|
||||
group_sel3:onClick(function(self, state, player)
|
||||
local selected = self:getSelectedItem()
|
||||
if selected then
|
||||
update_group_selection(state, 3)
|
||||
end
|
||||
end)
|
||||
|
||||
-- functions
|
||||
local searchfield = state:field(1.3, 4.1, 4.2, 0.5, "search")
|
||||
searchfield:setCloseOnEnter(false)
|
||||
searchfield:onKeyEnter(function(self, state, player)
|
||||
local search_string = self:getText()
|
||||
local lang_code = state.location.rootState.lang_code
|
||||
local filtered_list = ui_tools.filter_by_searchstring(ui_tools.root_list, search_string, lang_code)
|
||||
state.param.creative_grouped_items = ui_tools.get_list_grouped(filtered_list)
|
||||
filtered_list = ui_tools.filter_by_searchstring(ui_tools.root_list_shape, search_string, lang_code)
|
||||
state.param.creative_grouped_shape_items = filtered_list
|
||||
update_group_selection(state, 0)
|
||||
end)
|
||||
|
||||
local search_button = state:button(5.0, 3.8, 1, 0.5, "search_btn", "Go")
|
||||
search_button:setTooltip("Perform search action")
|
||||
search_button:onClick(function(self, state, player)
|
||||
state:get("search"):submit_key_enter("", player)
|
||||
end)
|
||||
|
||||
|
||||
-- action mode toggle
|
||||
state:toggle(6, 3.8,1.5,0.5, "btn_tog_mode", {"Give 1", "Give stack"})
|
||||
|
||||
-- groups toggle
|
||||
local btn_toggle = state:toggle(7.5, 3.8,1.5,0.5, "btn_tog", {"Groups", "Hide"})
|
||||
btn_toggle:onToggle(function(self, state, player)
|
||||
local id = self:getId()
|
||||
if id == 1 then
|
||||
state.param.creative_ui_controller:set_ui_variant("list_small")
|
||||
elseif id == 2 then
|
||||
state.param.creative_ui_controller:set_ui_variant("list_big")
|
||||
end
|
||||
end)
|
||||
|
||||
-- craftable items grid
|
||||
state:background(9.2, 3.5, 9.5, 6.5, "buttons_grid_bg", "minimap_overlay_square.png")
|
||||
local grid = smart_inventory.smartfs_elements.buttons_grid(state, 9.55, 3.75, 9.0 , 6.5, "buttons_grid", 0.75,0.75)
|
||||
grid:onClick(function(self, state, index, player)
|
||||
local mode = state:get("btn_tog_mode"):getId() or 1
|
||||
local selected = ItemStack(state.param.creative_outlist[index].item)
|
||||
if mode == 1 then -- give 1 item
|
||||
state.param.invobj:add_item(selected)
|
||||
elseif mode == 2 then --give full stack
|
||||
selected:set_count(selected:get_stack_max())
|
||||
state.param.invobj:add_sepearate_stack(selected)
|
||||
end
|
||||
end)
|
||||
|
||||
-- inventory
|
||||
state:inventory(1, 5, 8, 4,"main")
|
||||
ui_tools.create_trash_inv(state, player)
|
||||
state:image(8,9,1,1,"trash_icon","smart_inventory_trash.png")
|
||||
state:element("code", {name = "trash_bg_code", code = "listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]"})
|
||||
state:inventory(8,9,1,1, "trash"):useDetached(player.."_trash_inv")
|
||||
|
||||
-- swap slots buttons
|
||||
state:image_button(0, 6, 1, 1, "swap1", "", "smart_inventory_swapline_button.png"):onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "swap1")
|
||||
state.param.invobj:swap_row_to_top(2)
|
||||
end)
|
||||
state:image_button(0, 7, 1, 1, "swap2", "", "smart_inventory_swapline_button.png"):onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "swap2")
|
||||
state.param.invobj:swap_row_to_top(3)
|
||||
end)
|
||||
state:image_button(0, 8, 1, 1, "swap3", "", "smart_inventory_swapline_button.png"):onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "swap3")
|
||||
state.param.invobj:swap_row_to_top(4)
|
||||
end)
|
||||
|
||||
-- trash button
|
||||
local trash_all = state:image_button(7,9,1,1, "trash_all", "", "smart_inventory_trash_all_button.png")
|
||||
trash_all:setTooltip("Trash all inventory content")
|
||||
trash_all:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "trash_all")
|
||||
state.param.invobj:remove_all()
|
||||
end)
|
||||
|
||||
-- save/restore buttons
|
||||
local btn_save1 = state:image_button(1,9,1,1, "save1", "", "smart_inventory_save1_button.png")
|
||||
btn_save1:setTooltip("Save inventory content to slot 1")
|
||||
btn_save1:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "save1")
|
||||
state.param.invobj:save_to_slot(1)
|
||||
end)
|
||||
local btn_save2 = state:image_button(1.9,9,1,1, "save2", "", "smart_inventory_save2_button.png")
|
||||
btn_save2:setTooltip("Save inventory content to slot 2")
|
||||
btn_save2:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "save2")
|
||||
state.param.invobj:save_to_slot(2)
|
||||
end)
|
||||
local btn_save3 = state:image_button(2.8,9,1,1, "save3", "", "smart_inventory_save3_button.png")
|
||||
btn_save3:setTooltip("Save inventory content to slot 3")
|
||||
btn_save3:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "save3")
|
||||
state.param.invobj:save_to_slot(3)
|
||||
end)
|
||||
local btn_restore1 = state:image_button(4,9,1,1, "restore1", "", "smart_inventory_get1_button.png")
|
||||
btn_restore1:setTooltip("Restore inventory content from slot 1")
|
||||
btn_restore1:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "restore1")
|
||||
state.param.invobj:restore_from_slot(1)
|
||||
end)
|
||||
local btn_restore2 = state:image_button(4.9,9,1,1, "restore2", "", "smart_inventory_get2_button.png")
|
||||
btn_restore2:setTooltip("Restore inventory content from slot 2")
|
||||
btn_restore2:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "restore2")
|
||||
state.param.invobj:restore_from_slot(2)
|
||||
end)
|
||||
local btn_restore3 = state:image_button(5.8,9,1,1, "restore3", "", "smart_inventory_get3_button.png")
|
||||
btn_restore3:setTooltip("Restore inventory content from slot 3")
|
||||
btn_restore3:onClick(function(self, state, player)
|
||||
ui_tools.image_button_feedback(player, "creative", "restore3")
|
||||
state.param.invobj:restore_from_slot(3)
|
||||
end)
|
||||
|
||||
-- fill with data
|
||||
state.param.creative_grouped_items = ui_tools.get_list_grouped(ui_tools.root_list)
|
||||
state.param.creative_grouped_shape_items = ui_tools.root_list_shape
|
||||
update_group_selection(state, 0)
|
||||
ui_controller:restore()
|
||||
end
|
||||
|
||||
local function player_has_creative(state)
|
||||
return state.param.invobj:get_has_creative()
|
||||
end
|
||||
|
||||
-----------------------------------------------------
|
||||
-- Register page in smart_inventory
|
||||
-----------------------------------------------------
|
||||
smart_inventory.register_page({
|
||||
name = "creative",
|
||||
tooltip = "The creative way to get items",
|
||||
icon = "smart_inventory_creative_button.png",
|
||||
smartfs_callback = creative_callback,
|
||||
is_visible_func = player_has_creative,
|
||||
sequence = 15
|
||||
})
|
||||
|
||||
-- Redefinition for sfinv method maybe called from other mods
|
||||
if minetest.global_exists("sfinv") then
|
||||
function sfinv.set_player_inventory_formspec(player, context)
|
||||
local playername = player:get_player_name()
|
||||
|
||||
local page_state = smart_inventory.get_page_state("creative", playername)
|
||||
if page_state then
|
||||
local state = page_state.location.parentState
|
||||
local has_creative = player_has_creative(state)
|
||||
state:get("creative_button"):setVisible(has_creative)
|
||||
if not has_creative then
|
||||
state:get("crafting_button"):submit(nil, playername)
|
||||
end
|
||||
state:show()
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,138 +0,0 @@
|
|||
local doc_addon = smart_inventory.doc_addon
|
||||
|
||||
if not smart_inventory.doc_items_mod then
|
||||
return
|
||||
end
|
||||
|
||||
local COLOR_NOT_VIEWED = "#00FFFF" -- cyan
|
||||
local COLOR_VIEWED = "#FFFFFF" -- white
|
||||
local COLOR_HIDDEN = "#999999" -- gray
|
||||
local COLOR_ERROR = "#FF0000" -- red
|
||||
|
||||
local function update_entry_list(state, selected_eid)
|
||||
local playername = state.location.rootState.location.player
|
||||
local category_id, category
|
||||
|
||||
category_id = state:get("category"):getSelected()
|
||||
if category_id then
|
||||
category = doc_addon.get_category_list()[category_id]
|
||||
end
|
||||
if not category then
|
||||
return
|
||||
end
|
||||
|
||||
local total = doc.get_entry_count(category.cid)
|
||||
local revealed = doc.get_revealed_count(playername, category.cid)
|
||||
local viewed = doc.get_viewed_count(playername, category.cid)
|
||||
local hidden = total - revealed
|
||||
local new = total - viewed - hidden
|
||||
|
||||
state:get("lbl_category"):setText(category.data.def.description)
|
||||
state:get("lbl_viewed"):setText(minetest.colorize(COLOR_VIEWED,"Viewed: "..viewed.."/"..revealed))
|
||||
state:get("lbl_hidden"):setText(minetest.colorize(COLOR_HIDDEN,"Hidden: "..hidden.."/"..total))
|
||||
state:get("lbl_new"):setText(minetest.colorize(COLOR_NOT_VIEWED,"New: "..new))
|
||||
local entries_box = state:get("entries")
|
||||
entries_box:clearItems()
|
||||
state.param.doc_entry_list = {}
|
||||
for _, edata in ipairs(category.entries) do
|
||||
local viewedprefix
|
||||
if doc.entry_revealed(playername, category.cid, edata.eid) then
|
||||
if doc.entry_viewed(playername, category.cid, edata.eid) then
|
||||
viewedprefix = COLOR_VIEWED
|
||||
else
|
||||
viewedprefix = COLOR_NOT_VIEWED
|
||||
end
|
||||
|
||||
local name = edata.data.name
|
||||
if name == nil or name == "" then
|
||||
name = edata.eid
|
||||
end
|
||||
|
||||
local idx = entries_box:addItem(viewedprefix..name)
|
||||
table.insert(state.param.doc_entry_list, edata)
|
||||
if selected_eid == edata.eid then
|
||||
entries_box:setSelected(idx)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function doc_callback(state)
|
||||
local playername = state.location.rootState.location.player
|
||||
|
||||
state:label(0, 0, "lbl_category", "")
|
||||
state:background(0,0,20,0.5,"cat_bg", "halo.png")
|
||||
-- state:label(0, 0.5, "lbl_revealed", "")
|
||||
state:label(0, 0.5, "lbl_viewed", "")
|
||||
state:label(3, 0.5, "lbl_new", "")
|
||||
state:label(0, 1, "lbl_hidden", "")
|
||||
|
||||
local category_box = state:listbox(0, 1.5, 4.8, 2, "category", nil, false)
|
||||
category_box:onClick(function(self, state, player)
|
||||
update_entry_list(state)
|
||||
end)
|
||||
|
||||
state:listbox(0, 4, 4.8, 6, "entries", nil, false):onDoubleClick(function(self, state, player)
|
||||
local playername = state.location.rootState.location.player
|
||||
local selected = self:getSelected()
|
||||
local doc_entry = state.param.doc_entry_list[selected]
|
||||
if doc_entry then
|
||||
doc.mark_entry_as_viewed(playername, doc_entry.cid, doc_entry.eid)
|
||||
state:get("code").edata = doc_entry
|
||||
doc.data.players[playername].galidx = 1
|
||||
update_entry_list(state)
|
||||
end
|
||||
end)
|
||||
|
||||
local codebox = state:element("code", { name = "code", code = "" })
|
||||
codebox:onBuild(function(self)
|
||||
if self.edata then
|
||||
local state = self.root
|
||||
local playername = state.location.rootState.location.player
|
||||
self.data.code = "container[5.5,0]".. self.edata.cid_data.def.build_formspec(self.edata.data.data, playername).."container_end[]"
|
||||
else
|
||||
self.data.code = ""
|
||||
end
|
||||
end)
|
||||
|
||||
-- to trigger the page update
|
||||
codebox:onSubmit(function(self, state)
|
||||
-- select the right category
|
||||
for idx, category in ipairs(doc_addon.get_category_list()) do
|
||||
if category.cid == self.edata.cid then
|
||||
state:get("category"):setSelected(idx)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- update page for new category
|
||||
update_entry_list(state, self.edata.eid)
|
||||
end)
|
||||
|
||||
state:onInput(function(state, fields, player)
|
||||
if fields.doc_button_gallery_prev then
|
||||
if doc.data.players[playername].galidx - doc.data.players[playername].galrows > 0 then
|
||||
doc.data.players[playername].galidx = doc.data.players[playername].galidx - doc.data.players[playername].galrows
|
||||
end
|
||||
|
||||
elseif fields.doc_button_gallery_next then
|
||||
if doc.data.players[playername].galidx + doc.data.players[playername].galrows <= doc.data.players[playername].maxgalidx then
|
||||
doc.data.players[playername].galidx = doc.data.players[playername].galidx + doc.data.players[playername].galrows
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- fill category table
|
||||
for _, category in ipairs(doc_addon.get_category_list()) do
|
||||
category_box:addItem(category.data.def.name)
|
||||
end
|
||||
end
|
||||
|
||||
smart_inventory.register_page({
|
||||
name = "doc",
|
||||
icon = "doc_awards_icon_generic.png",
|
||||
tooltip = "Ingame documentation",
|
||||
smartfs_callback = doc_callback,
|
||||
sequence = 30,
|
||||
on_button_click = update_entry_list,
|
||||
})
|
|
@ -1,445 +0,0 @@
|
|||
smart_inventory.skins_mod = minetest.get_modpath("skinsdb")
|
||||
smart_inventory.armor_mod = minetest.get_modpath("3d_armor")
|
||||
smart_inventory.clothing_mod = minetest.get_modpath("clothing")
|
||||
|
||||
if not smart_inventory.skins_mod and
|
||||
not smart_inventory.armor_mod and
|
||||
not smart_inventory.clothing_mod then
|
||||
return
|
||||
end
|
||||
|
||||
local filter = smart_inventory.filter
|
||||
local cache = smart_inventory.cache
|
||||
local ui_tools = smart_inventory.ui_tools
|
||||
local txt = smart_inventory.txt
|
||||
|
||||
local function update_grid(state, listname)
|
||||
local player_has_creative = state.param.invobj:get_has_creative()
|
||||
-- Update the users inventory grid
|
||||
local list = {}
|
||||
state.param["player_"..listname.."_list"] = list
|
||||
local name = state.location.rootState.location.player
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local invlist_tab = {}
|
||||
if listname == "main" then
|
||||
local inventory = player:get_inventory()
|
||||
local invlist = inventory and inventory:get_list("main")
|
||||
table.insert(invlist_tab, invlist)
|
||||
else
|
||||
if smart_inventory.armor_mod then
|
||||
local inventory = minetest.get_inventory({type="detached", name=name.."_armor"})
|
||||
local invlist = inventory and inventory:get_list("armor")
|
||||
if invlist then
|
||||
table.insert(invlist_tab, invlist)
|
||||
end
|
||||
end
|
||||
if smart_inventory.clothing_mod then
|
||||
local clothing_meta = player:get_attribute("clothing:inventory")
|
||||
state.param.player_clothing_data = clothing_meta and minetest.deserialize(clothing_meta) or {}
|
||||
local invlist = {}
|
||||
for i=1,6 do
|
||||
table.insert(invlist, ItemStack(state.param.player_clothing_data[i]))
|
||||
end
|
||||
table.insert(invlist_tab, invlist)
|
||||
end
|
||||
end
|
||||
|
||||
local list_dedup = {}
|
||||
for _, invlist in ipairs(invlist_tab) do
|
||||
for stack_index, stack in ipairs(invlist) do
|
||||
local itemdef = stack:get_definition()
|
||||
local is_armor = false
|
||||
if itemdef then
|
||||
cache.add_item(itemdef) -- analyze groups in case of hidden armor
|
||||
if cache.citems[itemdef.name].cgroups["armor"] or cache.citems[itemdef.name].cgroups["clothing"] then
|
||||
local entry = {}
|
||||
for k, v in pairs(cache.citems[itemdef.name].ui_item) do
|
||||
entry[k] = v
|
||||
end
|
||||
entry.stack_index = stack_index
|
||||
local wear = stack:get_wear()
|
||||
if wear > 0 then
|
||||
entry.text = tostring(math.floor((1 - wear / 65535) * 100 + 0.5)).." %"
|
||||
end
|
||||
table.insert(list, entry)
|
||||
list_dedup[itemdef.name] = itemdef
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- add all usable in creative available armor to the main list
|
||||
if listname == "main" and player_has_creative == true then
|
||||
if smart_inventory.armor_mod then
|
||||
for _, itemdef in pairs(cache.cgroups["armor"].items) do
|
||||
if not list_dedup[itemdef.name] and not itemdef.groups.not_in_creative_inventory then
|
||||
list_dedup[itemdef.name] = itemdef
|
||||
table.insert(list, cache.citems[itemdef.name].ui_item)
|
||||
end
|
||||
end
|
||||
end
|
||||
if smart_inventory.clothing_mod then
|
||||
for _, itemdef in pairs(cache.cgroups["clothing"].items) do
|
||||
if not list_dedup[itemdef.name] and not itemdef.groups.not_in_creative_inventory then
|
||||
list_dedup[itemdef.name] = itemdef
|
||||
table.insert(list, cache.citems[itemdef.name].ui_item)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local grid = state:get(listname.."_grid")
|
||||
grid:setList(list)
|
||||
end
|
||||
|
||||
local function update_selected_item(state, listentry)
|
||||
local name = state.location.rootState.location.player
|
||||
state.param.armor_selected_item = listentry or state.param.armor_selected_item
|
||||
listentry = state.param.armor_selected_item
|
||||
if not listentry then
|
||||
return
|
||||
end
|
||||
local i_list = state:get("i_list")
|
||||
i_list:clearItems()
|
||||
for _, groupdef in ipairs(ui_tools.get_tight_groups(cache.citems[listentry.itemdef.name].cgroups)) do
|
||||
i_list:addItem(groupdef.group_desc)
|
||||
end
|
||||
state:get("item_name"):setText(listentry.itemdef.description)
|
||||
state:get("item_image"):setImage(listentry.item)
|
||||
end
|
||||
|
||||
local function update_page(state)
|
||||
local name = state.location.rootState.location.player
|
||||
local player_obj = minetest.get_player_by_name(name)
|
||||
local skin_obj = smart_inventory.skins_mod and skins.get_player_skin(player_obj)
|
||||
|
||||
-- Update grid lines
|
||||
if smart_inventory.armor_mod or smart_inventory.clothing_mod then
|
||||
update_grid(state, "main")
|
||||
update_grid(state, "overlay")
|
||||
end
|
||||
|
||||
-- Update preview area and armor informations list
|
||||
if smart_inventory.armor_mod then
|
||||
state:get("preview"):setImage(armor.textures[name].preview)
|
||||
state.location.parentState:get("player_button"):setImage(armor.textures[name].preview)
|
||||
local a_list = state:get("a_list")
|
||||
a_list:clearItems()
|
||||
for k, v in pairs(armor.def[name]) do
|
||||
local grouptext
|
||||
if k == "groups" then
|
||||
for gn, gv in pairs(v) do
|
||||
if txt and txt["armor:"..gn] then
|
||||
grouptext = txt["armor:"..gn]
|
||||
else
|
||||
grouptext = "armor:"..gn
|
||||
end
|
||||
if grouptext and gv ~= 0 then
|
||||
a_list:addItem(grouptext..": "..gv)
|
||||
end
|
||||
end
|
||||
else
|
||||
local is_physics = false
|
||||
for _, group in ipairs(armor.physics) do
|
||||
if group == k then
|
||||
is_physics = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if is_physics then
|
||||
if txt and txt["physics:"..k] then
|
||||
grouptext = txt["physics:"..k]
|
||||
else
|
||||
grouptext = "physics:"..k
|
||||
end
|
||||
if grouptext and v ~= 1 then
|
||||
a_list:addItem(grouptext..": "..v)
|
||||
end
|
||||
else
|
||||
if txt and txt["armor:"..k] then
|
||||
grouptext = txt["armor:"..k]
|
||||
else
|
||||
grouptext = "armor:"..k
|
||||
end
|
||||
if grouptext and v ~= 0 then
|
||||
if k == "state" then
|
||||
a_list:addItem(grouptext..": "..tostring(math.floor((1 - v / armor.def[name].count / 65535) * 100 + 0.5)).." %")
|
||||
else
|
||||
a_list:addItem(grouptext..": "..v)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
update_selected_item(state)
|
||||
elseif skin_obj then
|
||||
local skin_preview = skin_obj:get_preview()
|
||||
state.location.parentState:get("player_button"):setImage(skin_preview)
|
||||
state:get("preview"):setImage(skin_preview)
|
||||
elseif smart_inventory.clothing_mod then
|
||||
update_selected_item(state)
|
||||
state.location.parentState:get("player_button"):setImage('inventory_plus_clothing.png')
|
||||
state:get("preview"):setImage('blank.png') --TODO: build up clothing preview
|
||||
end
|
||||
|
||||
-- Update skins list and skins info area
|
||||
if skin_obj then
|
||||
local m_name = skin_obj:get_meta_string("name")
|
||||
local m_author = skin_obj:get_meta_string("author")
|
||||
local m_license = skin_obj:get_meta_string("license")
|
||||
if m_name then
|
||||
state:get("skinname"):setText("Skin name: "..(skin_obj:get_meta_string("name")))
|
||||
else
|
||||
state:get("skinname"):setText("")
|
||||
end
|
||||
if m_author then
|
||||
state:get("skinauthor"):setText("Author: "..(skin_obj:get_meta_string("author")))
|
||||
else
|
||||
state:get("skinauthor"):setText("")
|
||||
end
|
||||
if m_license then
|
||||
state:get("skinlicense"):setText("License: "..(skin_obj:get_meta_string("license")))
|
||||
else
|
||||
state:get("skinlicense"):setText("")
|
||||
end
|
||||
|
||||
-- set the skins list
|
||||
state.param.skins_list = skins.get_skinlist_for_player(name)
|
||||
local cur_skin = skins.get_player_skin(player_obj)
|
||||
local skins_grid_data = {}
|
||||
local grid_skins = state:get("skins_grid")
|
||||
for idx, skin in ipairs(state.param.skins_list) do
|
||||
table.insert(skins_grid_data, {
|
||||
image = skin:get_preview(),
|
||||
tooltip = skin:get_meta_string("name"),
|
||||
is_button = true,
|
||||
size = { w = 0.87, h = 1.30 }
|
||||
})
|
||||
if not state.param.skins_initial_page_adjusted and skin:get_key() == cur_skin:get_key() then
|
||||
grid_skins:setFirstVisible(idx - 19) --8x5 (grid size) / 2 -1
|
||||
state.param.skins_initial_page_adjusted = true
|
||||
end
|
||||
end
|
||||
grid_skins:setList(skins_grid_data)
|
||||
end
|
||||
end
|
||||
|
||||
local function move_item_to_armor(state, item)
|
||||
local player_has_creative = state.param.invobj:get_has_creative()
|
||||
local name = state.location.rootState.location.player
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local inventory = player:get_inventory()
|
||||
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
|
||||
|
||||
-- get item to be moved to armor inventory
|
||||
local itemstack, itemname, itemdef
|
||||
if player_has_creative == true then
|
||||
itemstack = ItemStack(item.item)
|
||||
itemname = item.item
|
||||
else
|
||||
itemstack = inventory:get_stack("main", item.stack_index)
|
||||
itemname = itemstack:get_name()
|
||||
end
|
||||
itemdef = minetest.registered_items[itemname]
|
||||
local new_groups = {}
|
||||
for _, element in ipairs(armor.elements) do
|
||||
if itemdef.groups["armor_"..element] then
|
||||
new_groups["armor_"..element] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- remove all items with the same group
|
||||
local removed_items = {}
|
||||
for stack_index, stack in ipairs(armor_inv:get_list("armor")) do
|
||||
local old_def = stack:get_definition()
|
||||
if old_def then
|
||||
for groupname, groupdef in pairs(old_def.groups) do
|
||||
if new_groups[groupname] then
|
||||
table.insert(removed_items, stack)
|
||||
armor_inv:set_stack("armor", stack_index, {}) --take old
|
||||
minetest.detached_inventories[name.."_armor"].on_take(armor_inv, "armor", stack_index, stack, player)
|
||||
if armor_inv:set_stack("armor", stack_index, itemstack) then --put new
|
||||
minetest.detached_inventories[name.."_armor"].on_put(armor_inv, "armor", stack_index, itemstack, player)
|
||||
itemstack = ItemStack("")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if stack:is_empty() and not itemstack:is_empty() then
|
||||
if armor_inv:set_stack("armor", stack_index, itemstack) then
|
||||
minetest.detached_inventories[name.."_armor"].on_put(armor_inv, "armor", stack_index, itemstack, player)
|
||||
itemstack = ItemStack("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- handle put backs in non-creative to not lost items
|
||||
if player_has_creative == false then
|
||||
inventory:set_stack("main", item.stack_index, itemstack)
|
||||
for _, stack in ipairs(removed_items) do
|
||||
stack = inventory:add_item("main", stack)
|
||||
if not stack:is_empty() then
|
||||
armor_inv:add_item("armor", stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function move_item_to_clothing(state, item)
|
||||
local name = state.location.rootState.location.player
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local inventory = player:get_inventory()
|
||||
|
||||
local clothes = state.param.player_clothing_data
|
||||
local clothes_ordered = {}
|
||||
|
||||
for i=1, 6 do
|
||||
if clothes[i] then
|
||||
table.insert(clothes_ordered, clothes[i])
|
||||
end
|
||||
end
|
||||
|
||||
if #clothes_ordered < 6 then
|
||||
table.insert(clothes_ordered, item.item)
|
||||
player:set_attribute("clothing:inventory", minetest.serialize(clothes_ordered))
|
||||
clothing:set_player_clothing(player)
|
||||
state.param.player_clothing_data = clothes_ordered
|
||||
-- handle put backs in non-creative to not lost items
|
||||
if player_has_creative == false then
|
||||
local itemstack = inventory:get_stack("main", item.stack_index)
|
||||
itemstack:take_item()
|
||||
inventory:set_stack("main", item.stack_index, itemstack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function move_item_to_inv(state, item)
|
||||
local player_has_creative = state.param.invobj:get_has_creative()
|
||||
local name = state.location.rootState.location.player
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local inventory = player:get_inventory()
|
||||
|
||||
if cache.cgroups["armor"] and cache.cgroups["armor"].items[item.item] then
|
||||
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
|
||||
local itemstack = armor_inv:get_stack("armor", item.stack_index)
|
||||
if player_has_creative == true then
|
||||
-- trash armor item in creative
|
||||
itemstack = ItemStack("")
|
||||
else
|
||||
itemstack = inventory:add_item("main", itemstack)
|
||||
end
|
||||
armor_inv:set_stack("armor", item.stack_index, itemstack)
|
||||
minetest.detached_inventories[name.."_armor"].on_take(armor_inv, "armor", item.stack_index, itemstack, player)
|
||||
|
||||
elseif cache.cgroups["clothing"] and cache.cgroups["clothing"].items[item.item] then
|
||||
local clothes = state.param.player_clothing_data
|
||||
|
||||
if player_has_creative ~= true and clothes[item.stack_index] then
|
||||
local itemstack = inventory:add_item("main", ItemStack(clothes[item.stack_index]))
|
||||
if itemstack:is_empty() then
|
||||
clothes[item.stack_index] = nil
|
||||
end
|
||||
else
|
||||
clothes[item.stack_index] = nil
|
||||
end
|
||||
player:set_attribute("clothing:inventory", minetest.serialize(clothes))
|
||||
clothing:set_player_clothing(player)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function player_callback(state)
|
||||
local name = state.location.rootState.location.player
|
||||
state:background(0, 1.2, 6, 6.6, "it_bg", "smart_inventory_background_border.png")
|
||||
state:item_image(0.8, 1.5,2,2,"item_image","")
|
||||
state:label(2.5,1.2,"item_name", "")
|
||||
state:listbox(0.8,3.3,5.1,4,"i_list", nil, true)
|
||||
|
||||
state:background(6.2, 1.2, 6, 6.6, "pl_bg", "smart_inventory_background_border.png")
|
||||
state:image(6.7,1.7,2,4,"preview","")
|
||||
state:listbox(8.6,1.7,3.5,3,"a_list", nil, true)
|
||||
state:label(6.7,5.5,"skinname","")
|
||||
state:label(6.7,6.0,"skinauthor", "")
|
||||
state:label(6.7,6.5, "skinlicense", "")
|
||||
|
||||
state:background(0, 0, 20, 1, "top_bg", "halo.png")
|
||||
state:background(0, 8, 20, 2, "bottom_bg", "halo.png")
|
||||
if smart_inventory.armor_mod or smart_inventory.clothing_mod then
|
||||
local grid_overlay = smart_inventory.smartfs_elements.buttons_grid(state, 0, 0, 20, 1, "overlay_grid")
|
||||
|
||||
grid_overlay:onClick(function(self, state, index, player)
|
||||
if state.param.player_overlay_list[index] then
|
||||
update_selected_item(state, state.param.player_overlay_list[index])
|
||||
move_item_to_inv(state, state.param.player_overlay_list[index])
|
||||
update_page(state)
|
||||
end
|
||||
end)
|
||||
|
||||
local grid_main = smart_inventory.smartfs_elements.buttons_grid(state, 0, 8, 20, 2, "main_grid")
|
||||
grid_main:onClick(function(self, state, index, player)
|
||||
update_selected_item(state, state.param.player_main_list[index])
|
||||
local item = state.param.player_main_list[index]
|
||||
if cache.citems[item.item].cgroups["armor"] then
|
||||
move_item_to_armor(state, state.param.player_main_list[index])
|
||||
elseif cache.citems[item.item].cgroups["clothing"] then
|
||||
move_item_to_clothing(state, state.param.player_main_list[index])
|
||||
end
|
||||
update_page(state)
|
||||
end)
|
||||
end
|
||||
|
||||
if smart_inventory.skins_mod then
|
||||
local player_obj = minetest.get_player_by_name(name)
|
||||
-- Skins Grid
|
||||
local grid_skins = smart_inventory.smartfs_elements.buttons_grid(state, 12.9, 1.5, 7 , 7, "skins_grid", 0.80, 1.20)
|
||||
state:background(12.4, 1.2, 7.5 , 6.6, "bg_skins", "smart_inventory_background_border.png")
|
||||
grid_skins:onClick(function(self, state, index, player)
|
||||
local cur_skin = state.param.skins_list[index]
|
||||
if state.location.rootState.location.type ~= "inventory" and cur_skin._key:sub(1,17) == "character_creator" then
|
||||
state.location.rootState.obsolete = true -- other screen appears, obsolete the inventory session
|
||||
end
|
||||
skins.set_player_skin(player_obj, cur_skin)
|
||||
if smart_inventory.armor_mod then
|
||||
armor.textures[name].skin = cur_skin:get_texture()
|
||||
armor:set_player_armor(player_obj)
|
||||
end
|
||||
update_page(state)
|
||||
end)
|
||||
end
|
||||
|
||||
-- not visible update plugin for updates from outsite (API)
|
||||
state:element("code", { name = "update_hook" }):onSubmit(function(self, state)
|
||||
update_page(state)
|
||||
state.location.rootState:show()
|
||||
end)
|
||||
|
||||
update_page(state)
|
||||
end
|
||||
|
||||
smart_inventory.register_page({
|
||||
name = "player",
|
||||
icon = "player.png",
|
||||
tooltip = "Customize yourself",
|
||||
smartfs_callback = player_callback,
|
||||
sequence = 20,
|
||||
on_button_click = update_page
|
||||
})
|
||||
|
||||
-- register callback in 3d_armor for updates
|
||||
if smart_inventory.armor_mod and armor.register_on_update then
|
||||
|
||||
local function submit_update_hook(player)
|
||||
local name = player:get_player_name()
|
||||
local state = smart_inventory.get_page_state("player", name)
|
||||
if state then
|
||||
state:get("update_hook"):submit()
|
||||
end
|
||||
end
|
||||
|
||||
armor:register_on_update(submit_update_hook)
|
||||
|
||||
-- There is no callback in 3d_armor for wear change in on_hpchange implementation
|
||||
minetest.register_on_player_hpchange(function(player, hp_change)
|
||||
minetest.after(0, submit_update_hook, player)
|
||||
end)
|
||||
end
|
Before Width: | Height: | Size: 429 KiB |
Before Width: | Height: | Size: 229 KiB |
Before Width: | Height: | Size: 232 KiB |
Before Width: | Height: | Size: 143 KiB |
Before Width: | Height: | Size: 239 KiB |
|
@ -1,10 +0,0 @@
|
|||
#If enabled, the mod will show alternative human readable filterstrings if available.
|
||||
smart_inventory_friendly_group_names (Show “friendly” filter grouping names) bool true
|
||||
|
||||
#List of groups defined for special handling of "Shaped nodes" (Comma separated).
|
||||
#Items in this groups ignores the "not_in_inventory" group and are moved to separate "Shaped" category
|
||||
smart_inventory_shaped_groups (List of groups to be handled as separate) string carpet,door,fence,stair,slab,wall,micro,panel,slope,dye
|
||||
|
||||
#If enabled, the the mod does not replace other inventory mods.
|
||||
#The functionality is provided in a workbench.
|
||||
smart_inventory_workbench_mode (Use workbench instead of players inventory) bool false
|
|
@ -1,2 +0,0 @@
|
|||
The background border image goes where the skin button would normally go.
|
||||
Inside the bordered area should be put the fron texture of a skins head.
|
Before Width: | Height: | Size: 274 B |
Before Width: | Height: | Size: 274 B |
Before Width: | Height: | Size: 274 B |
Before Width: | Height: | Size: 310 B |
Before Width: | Height: | Size: 362 B |
Before Width: | Height: | Size: 442 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 310 B |
Before Width: | Height: | Size: 462 B |
Before Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 444 B |
Before Width: | Height: | Size: 368 B |
Before Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 431 B |
Before Width: | Height: | Size: 460 B |
Before Width: | Height: | Size: 318 B |
Before Width: | Height: | Size: 313 B |