mirror of
https://github.com/minetest-mods/craftguide.git
synced 2024-11-26 12:33:43 +01:00
Add optional Progressive Mode
The progressive mode is a Terraria-like crafting guide system that only list the items in the crafting guide for which you already have the ingredients in your inventory. The progressive mode is disabled by default and can be enabled with `craftguide_progressive_mode = true` in `minetest.conf`. Thanks to @kaeza and @Wuzzy2 for the idea. See discussion on https://github.com/minetest/minetest_game/issues/1435
This commit is contained in:
parent
e8508e1169
commit
864b43da2c
10
README.md
10
README.md
@ -1,8 +1,14 @@
|
|||||||
## Crafting Guide ##
|
## Crafting Guide ##
|
||||||
|
|
||||||
##### A simple and fast Crafting Guide that doesn't suck for Minetest.
|
#### A simple and fast Crafting Guide that doesn't suck for Minetest. ####
|
||||||
|
|
||||||
##### Usable with a book named *"Crafting Guide"*. #####
|
#### Usable with a book named *"Crafting Guide"*. ####
|
||||||
|
|
||||||
|
#### This crafting guide features two modes : Normal and Progressive. ####
|
||||||
|
The Progressive mode is a Terraria-like crafting guide system that only
|
||||||
|
list the items in the crafting guide for which you already have the ingredients
|
||||||
|
in your inventory. The progressive mode is disabled by default and can be enabled with
|
||||||
|
`craftguide_progressive_mode = true` in `minetest.conf`.
|
||||||
|
|
||||||
![Preview](http://i.imgur.com/xblp1Vs.png)
|
![Preview](http://i.imgur.com/xblp1Vs.png)
|
||||||
|
|
||||||
|
74
init.lua
74
init.lua
@ -1,5 +1,6 @@
|
|||||||
local craftguide, datas, npp = {}, {}, 8*3
|
local craftguide, datas, npp = {}, {}, 8*3
|
||||||
local min, ceil = math.min, math.ceil
|
local min, ceil, max = math.min, math.ceil, math.max
|
||||||
|
local progressive_mode = minetest.setting_getbool("craftguide_progressive_mode")
|
||||||
|
|
||||||
local group_stereotypes = {
|
local group_stereotypes = {
|
||||||
wool = "wool:white",
|
wool = "wool:white",
|
||||||
@ -11,7 +12,7 @@ local group_stereotypes = {
|
|||||||
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
|
mesecon_conductor_craftable = "mesecons:wire_00000000_off",
|
||||||
}
|
}
|
||||||
|
|
||||||
function craftguide:get_recipe(item)
|
function craftguide:group_to_item(item)
|
||||||
if item:sub(1,6) == "group:" then
|
if item:sub(1,6) == "group:" then
|
||||||
local short_itemstr = item:sub(7)
|
local short_itemstr = item:sub(7)
|
||||||
if group_stereotypes[short_itemstr] then
|
if group_stereotypes[short_itemstr] then
|
||||||
@ -52,8 +53,8 @@ end
|
|||||||
|
|
||||||
function craftguide:get_formspec(player_name)
|
function craftguide:get_formspec(player_name)
|
||||||
local data = datas[player_name]
|
local data = datas[player_name]
|
||||||
data.pagenum = data.pagenum or 1
|
data.pagenum = max(1, data.pagenum or 1)
|
||||||
data.recipe_num = data.recipe_num or 1
|
data.pagemax = max(1, data.pagemax or 1)
|
||||||
|
|
||||||
local formspec = [[ size[8,6.6;]
|
local formspec = [[ size[8,6.6;]
|
||||||
button[2.5,0.2;0.8,0.5;search;?]
|
button[2.5,0.2;0.8,0.5;search;?]
|
||||||
@ -69,9 +70,13 @@ function craftguide:get_formspec(player_name)
|
|||||||
minetest.formspec_escape(data.filter).."]"..
|
minetest.formspec_escape(data.filter).."]"..
|
||||||
default.gui_bg..default.gui_bg_img
|
default.gui_bg..default.gui_bg_img
|
||||||
|
|
||||||
|
if not next(data.items) then
|
||||||
|
formspec = formspec.."label[2.9,2;No item to show]"
|
||||||
|
end
|
||||||
|
|
||||||
local first_item = (data.pagenum - 1) * npp
|
local first_item = (data.pagenum - 1) * npp
|
||||||
for i = first_item, first_item + npp - 1 do
|
for i = first_item, first_item + npp - 1 do
|
||||||
local name = data.items[i + 1]
|
local name = data.items[i+1]
|
||||||
if not name then break end -- last page
|
if not name then break end -- last page
|
||||||
local X = i % 8
|
local X = i % 8
|
||||||
local Y = ((i % npp - X) / 8) + 1
|
local Y = ((i % npp - X) / 8) + 1
|
||||||
@ -81,8 +86,16 @@ function craftguide:get_formspec(player_name)
|
|||||||
|
|
||||||
if data.item and minetest.registered_items[data.item] then
|
if data.item and minetest.registered_items[data.item] then
|
||||||
local recipes = minetest.get_all_craft_recipes(data.item)
|
local recipes = minetest.get_all_craft_recipes(data.item)
|
||||||
if data.recipe_num > #recipes then data.recipe_num = 1 end
|
data.recipe_num = data.recipe_num or 1
|
||||||
|
|
||||||
|
if progressive_mode then
|
||||||
|
local T = self:recipe_in_inv(player_name, data.item)
|
||||||
|
for i=#T, 1, -1 do
|
||||||
|
if not T[i] then table.remove(recipes, i) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if data.recipe_num > #recipes then data.recipe_num = 1 end
|
||||||
if #recipes > 1 then formspec = formspec..
|
if #recipes > 1 then formspec = formspec..
|
||||||
[[ button[0,6;2,1;alternate;Alternate]
|
[[ button[0,6;2,1;alternate;Alternate]
|
||||||
label[0,5.5;Recipe ]]..data.recipe_num.." of "..#recipes.."]"
|
label[0,5.5;Recipe ]]..data.recipe_num.." of "..#recipes.."]"
|
||||||
@ -105,7 +118,7 @@ function craftguide:get_formspec(player_name)
|
|||||||
local Y = ceil(i / width + (5 - min(2, rows)))
|
local Y = ceil(i / width + (5 - min(2, rows)))
|
||||||
local groups = self:extract_groups(v)
|
local groups = self:extract_groups(v)
|
||||||
local label = (groups and "\nG") or ""
|
local label = (groups and "\nG") or ""
|
||||||
local item = self:get_recipe(v)
|
local item = self:group_to_item(v)
|
||||||
local tooltip = self:get_tooltip(item, recipe_type, width, groups)
|
local tooltip = self:get_tooltip(item, recipe_type, width, groups)
|
||||||
|
|
||||||
formspec = formspec.."item_image_button["..X..","..Y..";1,1;"..
|
formspec = formspec.."item_image_button["..X..","..Y..";1,1;"..
|
||||||
@ -114,22 +127,51 @@ function craftguide:get_formspec(player_name)
|
|||||||
|
|
||||||
local output = recipes[data.recipe_num].output
|
local output = recipes[data.recipe_num].output
|
||||||
formspec = formspec..[[ image[3.5,5;1,1;gui_furnace_arrow_bg.png^[transformR90]
|
formspec = formspec..[[ image[3.5,5;1,1;gui_furnace_arrow_bg.png^[transformR90]
|
||||||
item_image_button[2.5,5;1,1;]]..output..";"..data.item..";]"
|
item_image_button[2.5,5;1,1;]]..output..";"..data.item..";]"
|
||||||
end
|
end
|
||||||
|
|
||||||
data.formspec = formspec
|
data.formspec = formspec
|
||||||
minetest.show_formspec(player_name, "craftguide:book", formspec)
|
minetest.show_formspec(player_name, "craftguide:book", formspec)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function has_item(T)
|
||||||
|
for i=1, #T do
|
||||||
|
if T[i] then return true end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function craftguide:recipe_in_inv(player_name, item_name)
|
||||||
|
local player = minetest.get_player_by_name(player_name)
|
||||||
|
local inv = player:get_inventory()
|
||||||
|
local recipes = minetest.get_all_craft_recipes(item_name) or {}
|
||||||
|
local T = {}
|
||||||
|
|
||||||
|
for i=1, #recipes do
|
||||||
|
T[i] = true
|
||||||
|
for _, item in pairs(recipes[i].items) do
|
||||||
|
if not inv:contains_item("main", self:group_to_item(item)) then
|
||||||
|
T[i] = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return T, has_item(T)
|
||||||
|
end
|
||||||
|
|
||||||
function craftguide:get_items(player_name)
|
function craftguide:get_items(player_name)
|
||||||
local items_list, data = {}, datas[player_name]
|
local items_list, data = {}, datas[player_name]
|
||||||
for name, def in pairs(minetest.registered_items) do
|
for name, def in pairs(minetest.registered_items) do
|
||||||
if not (def.groups.not_in_creative_inventory == 1) and
|
if not (def.groups.not_in_creative_inventory == 1) and
|
||||||
minetest.get_craft_recipe(name).items and
|
minetest.get_craft_recipe(name).items and
|
||||||
def.description and def.description ~= "" and
|
def.description and def.description ~= "" and
|
||||||
(def.name:find(data.filter, 1, true) or
|
(def.name:find(data.filter, 1, true) or
|
||||||
def.description:lower():find(data.filter, 1, true)) then
|
def.description:lower():find(data.filter, 1, true)) then
|
||||||
items_list[#items_list+1] = name
|
|
||||||
|
if progressive_mode then
|
||||||
|
local _, has_item = self:recipe_in_inv(player_name, name)
|
||||||
|
if has_item then items_list[#items_list+1] = name end
|
||||||
|
else
|
||||||
|
items_list[#items_list+1] = name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -165,6 +207,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
craftguide:get_formspec(player_name)
|
craftguide:get_formspec(player_name)
|
||||||
else for item in pairs(fields) do
|
else for item in pairs(fields) do
|
||||||
if minetest.get_craft_recipe(item).items then
|
if minetest.get_craft_recipe(item).items then
|
||||||
|
if progressive_mode then
|
||||||
|
local _, has_item = craftguide:recipe_in_inv(player_name, item)
|
||||||
|
if not has_item then return end
|
||||||
|
end
|
||||||
data.item = item
|
data.item = item
|
||||||
data.recipe_num = 1
|
data.recipe_num = 1
|
||||||
craftguide:get_formspec(player_name)
|
craftguide:get_formspec(player_name)
|
||||||
@ -181,7 +227,7 @@ minetest.register_craftitem("craftguide:book", {
|
|||||||
groups = {book=1},
|
groups = {book=1},
|
||||||
on_use = function(itemstack, user)
|
on_use = function(itemstack, user)
|
||||||
local player_name = user:get_player_name()
|
local player_name = user:get_player_name()
|
||||||
if not datas[player_name] then
|
if progressive_mode or not datas[player_name] then
|
||||||
datas[player_name] = {}
|
datas[player_name] = {}
|
||||||
datas[player_name].filter = ""
|
datas[player_name].filter = ""
|
||||||
craftguide:get_items(player_name)
|
craftguide:get_items(player_name)
|
||||||
|
Loading…
Reference in New Issue
Block a user