Support for sfinv!

This commit is contained in:
Jean-Patrick Guerrero 2018-11-11 22:24:48 +01:00
parent 8b309106c3
commit 39ed2c2c45
6 changed files with 182 additions and 106 deletions

@ -4,5 +4,6 @@ allow_defined_top = true
read_globals = { read_globals = {
"minetest", "minetest",
"default", "default",
"sfinv",
"sfinv_buttons", "sfinv_buttons",
} }

@ -1,4 +1,4 @@
« Copyright © 2015-2017, Jean-Patrick Guerrero <jeanpatrick.guerrero@gmail.com> « Copyright © 2015-2018, Jean-Patrick Guerrero <jeanpatrick.guerrero@gmail.com>
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: 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:

@ -1,14 +1,15 @@
## ![Preview1](http://i.imgur.com/fIPNYkb.png) Crafting Guide ## ## ![Preview1](http://i.imgur.com/fIPNYkb.png) Crafting Guide ##
#### A Crafting Guide for Minetest that doesn't suck. #### #### `craftguide` is the most comprehensive crafting guide on Minetest. ####
#### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. ####
#### `craftguide` is the most comprehensive mod of its category. #### #### This crafting guide is usable with a blue book named *"Crafting Guide"* ####
#### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details and comparisons. ####
#### This crafting guide is usable with a blue book named *"Crafting Guide"*. ####
#### This crafting guide features two modes : Standard and Progressive. #### #### This crafting guide features two modes : Standard and Progressive. ####
The Progressive mode is a Terraria-like system that only shows recipes you can craft from items in inventory. The Progressive mode is a Terraria-like system that only shows recipes you can craft from items in inventory.
The progressive mode can be enabled with `craftguide_progressive_mode = true` in `minetest.conf`. The progressive mode can be enabled with `craftguide_progressive_mode = true` in `minetest.conf`.
`craftguide` is also integrated in `sfinv` (Minetest Game inventory) when you enable it with
`craftguide_sfinv_only = true` in `minetest.conf`.
![Preview2](http://i.imgur.com/3q7rVSo.png) ![Preview2](http://i.imgur.com/3q7rVSo.png)

@ -1,2 +1,3 @@
sfinv?
sfinv_buttons? sfinv_buttons?
intllib? intllib?

269
init.lua

@ -1,5 +1,8 @@
local craftguide, datas, mt = {}, {searches = {}}, minetest local craftguide, datas, mt = {}, {searches = {}}, minetest
local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode") local progressive_mode = mt.settings:get_bool("craftguide_progressive_mode")
local sfinv_only = mt.settings:get_bool("craftguide_sfinv_only")
local get_recipe, get_recipes = mt.get_craft_recipe, mt.get_all_craft_recipes local get_recipe, get_recipes = mt.get_craft_recipe, mt.get_all_craft_recipes
local get_result, show_formspec = mt.get_craft_result, mt.show_formspec local get_result, show_formspec = mt.get_craft_result, mt.show_formspec
local reg_items = mt.registered_items local reg_items = mt.registered_items
@ -14,6 +17,7 @@ craftguide.intllib = S
-- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1 -- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1
local remove, maxn, sort = table.remove, table.maxn, table.sort local remove, maxn, sort = table.remove, table.maxn, table.sort
local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil
local unpack = unpack
local DEFAULT_SIZE = 10 local DEFAULT_SIZE = 10
local MIN_LIMIT, MAX_LIMIT = 9, 12 local MIN_LIMIT, MAX_LIMIT = 9, 12
@ -105,8 +109,9 @@ function craftguide:get_recipe(iY, xoffset, recipe_num, recipes, show_usage)
local formspec, recipes_total = "", #recipes local formspec, recipes_total = "", #recipes
if recipes_total > 1 then if recipes_total > 1 then
formspec = formspec .. formspec = formspec ..
"button[0," .. (iY + 3.3) .. ";2,1;alternate;" .. S("Alternate") .. "]" .. "button[0," .. (iY + (sfinv_only and 3.8 or 3.3)) ..
"label[0," .. (iY + 2.8) .. ";" .. ";2,1;alternate;" .. S("Alternate") .. "]" ..
"label[0," .. (iY + (sfinv_only and 3.3 or 2.8)) .. ";" ..
(show_usage and S("Usage") or S("Recipe")) .. " " .. (show_usage and S("Usage") or S("Recipe")) .. " " ..
S("@1 of @2", recipe_num, recipes_total) .. "]" S("@1 of @2", recipe_num, recipes_total) .. "]"
end end
@ -118,7 +123,7 @@ function craftguide:get_recipe(iY, xoffset, recipe_num, recipes, show_usage)
if recipe_type == "cooking" or (recipe_type == "normal" and width == 0) then if recipe_type == "cooking" or (recipe_type == "normal" and width == 0) then
local icon = recipe_type == "cooking" and "furnace" or "shapeless" local icon = recipe_type == "cooking" and "furnace" or "shapeless"
formspec = formspec .. formspec = formspec ..
"image[" .. (xoffset - 0.8) .. "," .. (iY + 1.7) .. "image[" .. (xoffset - 0.8) .. "," .. (iY + (sfinv_only and 2.2 or 1.7)) ..
";0.5,0.5;craftguide_" .. icon .. ".png]" ";0.5,0.5;craftguide_" .. icon .. ".png]"
end end
@ -150,7 +155,8 @@ function craftguide:get_recipe(iY, xoffset, recipe_num, recipes, show_usage)
local tltip = self:get_tooltip(item_r, recipe_type, width, groups) local tltip = self:get_tooltip(item_r, recipe_type, width, groups)
formspec = formspec .. formspec = formspec ..
"item_image_button[" .. X .. "," .. (Y + 0.2) .. ";" .. "item_image_button[" .. X .. "," ..
(Y + (sfinv_only and 0.7 or 0.2)) .. ";" ..
btn_size .. "," .. btn_size .. ";" .. item_r .. btn_size .. "," .. btn_size .. ";" .. item_r ..
";" .. item_r .. ";" .. label .. "]" .. tltip ";" .. item_r .. ";" .. label .. "]" .. tltip
end end
@ -158,16 +164,17 @@ function craftguide:get_recipe(iY, xoffset, recipe_num, recipes, show_usage)
local output = recipes[recipe_num].output local output = recipes[recipe_num].output
return formspec .. return formspec ..
"image[" .. (xoffset - 1) .. "," .. (iY + 2.35) .. "image[" .. (xoffset - 1) .. "," .. (iY + (sfinv_only and 2.85 or 2.35)) ..
";0.9,0.7;craftguide_arrow.png]" .. ";0.9,0.7;craftguide_arrow.png]" ..
"item_image_button[" .. (xoffset - 2) .. "," .. (iY + 2.2) .. ";1,1;" .. "item_image_button[" .. (xoffset - 2) .. "," ..
(iY + (sfinv_only and 2.7 or 2.2)) .. ";1,1;" ..
output .. ";" .. output .. ";]" .. output .. ";" .. output .. ";]" ..
self:get_tooltip(output:match("%S+")) self:get_tooltip(output:match("%S+"))
end end
function craftguide:get_formspec(player_name, is_fuel) function craftguide:get_formspec(player_name, is_fuel)
local data = datas[player_name] local data = datas[player_name]
local iY = data.iX - 5 local iY = sfinv_only and 4 or data.iX - 5
local ipp = data.iX * iY local ipp = data.iX * iY
if not data.items then if not data.items then
@ -176,27 +183,31 @@ function craftguide:get_formspec(player_name, is_fuel)
data.pagemax = max(1, ceil(#data.items / ipp)) data.pagemax = max(1, ceil(#data.items / ipp))
local formspec = "size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]" .. [[ local formspec = ""
background[1,1;1,1;craftguide_bg.png;true] if not sfinv_only then
formspec = formspec ..
"size[" .. (data.iX - 0.35) .. "," .. (iY + 4) .. ";]" ..
"background[1,1;1,1;craftguide_bg.png;true]" ..
"tooltip[size_inc;" .. S("Increase window size") .. "]" ..
"tooltip[size_dec;" .. S("Decrease window size") .. "]" ..
"button[" .. (data.iX * 0.48) .. ",-0.02;0.7,1;size_inc;+]" ..
"button[" .. ((data.iX * 0.48) + 0.5) .. ",-0.02;0.7,1;size_dec;-]"
end
formspec = formspec .. [[
button[2.4,0.23;0.8,0.5;search;?] button[2.4,0.23;0.8,0.5;search;?]
button[3.05,0.23;0.8,0.5;clear;X] button[3.05,0.23;0.8,0.5;clear;X]
field_close_on_enter[filter;false] field_close_on_enter[filter;false]
]] .. ]] ..
"tooltip[search;" .. S("Search") .. "]" .. "tooltip[search;" .. S("Search") .. "]" ..
"tooltip[clear;" .. S("Reset") .. "]" .. "tooltip[clear;" .. S("Reset") .. "]" ..
"tooltip[size_inc;" .. S("Increase window size") .. "]" ..
"tooltip[size_dec;" .. S("Decrease window size") .. "]" ..
"tooltip[prev;" .. S("Previous page") .. "]" .. "tooltip[prev;" .. S("Previous page") .. "]" ..
"tooltip[next;" .. S("Next page") .. "]" .. "tooltip[next;" .. S("Next page") .. "]" ..
"button[" .. (data.iX * 0.48) .. ",-0.02;0.7,1;size_inc;+]" ..
"button[" .. ((data.iX * 0.48) + 0.5) ..
",-0.02;0.7,1;size_dec;-]" ..
"button[" .. (data.iX - 3.1) .. ",0;0.8,0.95;prev;<]" .. "button[" .. (data.iX - 3.1) .. ",0;0.8,0.95;prev;<]" ..
"label[" .. (data.iX - 2.2) .. ",0.18;" .. "label[" .. (data.iX - 2.2) .. ",0.18;" ..
colorize(data.pagenum) .. " / " .. data.pagemax .. "]" .. colorize(data.pagenum) .. " / " .. data.pagemax .. "]" ..
"button[" .. (data.iX - 1.2) .. ",0;0.8,0.95;next;>]" .. "button[" .. (data.iX - 1.2) .. ",0;0.8,0.95;next;>]" ..
"field[0.3,0.32;2.5,1;filter;;" .. "field[0.3,0.32;2.5,1;filter;;" .. mt.formspec_escape(data.filter) .. "]"
mt.formspec_escape(data.filter) .. "]"
local even_num = data.iX % 2 == 0 local even_num = data.iX % 2 == 0
local xoffset = data.iX / 2 + (even_num and 0.5 or 0) local xoffset = data.iX / 2 + (even_num and 0.5 or 0)
@ -240,7 +251,12 @@ function craftguide:get_formspec(player_name, is_fuel)
end end
data.formspec = formspec data.formspec = formspec
show_formspec(player_name, "craftguide", formspec)
if sfinv_only then
return formspec
else
show_formspec(player_name, "craftguide", formspec)
end
end end
local function player_has_item(T) local function player_has_item(T)
@ -390,11 +406,32 @@ function craftguide:get_item_usages(item)
return usages return usages
end end
mt.register_on_player_receive_fields(function(player, formname, fields) local function get_fields(player, ...)
local args = {...}
local formname, fields
if #args == 1 then
formname = "craftguide"
fields = args[1]
else
formname, fields = unpack(args)
end
if formname ~= "craftguide" then return end if formname ~= "craftguide" then return end
local player_name = player:get_player_name() local player_name = player:get_player_name()
local data = datas[player_name] local data = datas[player_name]
local show_fs = function(is_fuel)
local context = sfinv.get_or_create_context(player)
context.fuel = is_fuel
if sfinv_only then
sfinv.set_player_inventory_formspec(player, context)
else
craftguide:get_formspec(player_name, is_fuel)
end
end
if fields.clear then if fields.clear then
data.show_usage = nil data.show_usage = nil
data.filter = "" data.filter = ""
@ -403,7 +440,7 @@ mt.register_on_player_receive_fields(function(player, formname, fields)
data.rnum = 1 data.rnum = 1
data.items = progressive_mode and data.init_filter_items or datas.init_items data.items = progressive_mode and data.init_filter_items or datas.init_items
craftguide:get_formspec(player_name) show_fs()
elseif fields.alternate then elseif fields.alternate then
local num local num
@ -414,14 +451,14 @@ mt.register_on_player_receive_fields(function(player, formname, fields)
end end
data.rnum = num and data.rnum + 1 or 1 data.rnum = num and data.rnum + 1 or 1
craftguide:get_formspec(player_name) show_fs()
elseif (fields.key_enter_field == "filter" or fields.search) and elseif (fields.key_enter_field == "filter" or fields.search) and
fields.filter ~= "" then fields.filter ~= "" then
data.filter = fields.filter:lower() data.filter = fields.filter:lower()
data.pagenum = 1 data.pagenum = 1
craftguide:get_filter_items(data, player) craftguide:get_filter_items(data, player)
craftguide:get_formspec(player_name) show_fs()
elseif fields.prev or fields.next then elseif fields.prev or fields.next then
data.pagenum = data.pagenum - (fields.prev and 1 or -1) data.pagenum = data.pagenum - (fields.prev and 1 or -1)
@ -432,13 +469,13 @@ mt.register_on_player_receive_fields(function(player, formname, fields)
data.pagenum = data.pagemax data.pagenum = data.pagemax
end end
craftguide:get_formspec(player_name) show_fs()
elseif (fields.size_inc and data.iX < MAX_LIMIT) or elseif (fields.size_inc and data.iX < MAX_LIMIT) or
(fields.size_dec and data.iX > MIN_LIMIT) then (fields.size_dec and data.iX > MIN_LIMIT) then
data.pagenum = 1 data.pagenum = 1
data.iX = data.iX - (fields.size_dec and 1 or -1) data.iX = data.iX - (fields.size_dec and 1 or -1)
craftguide:get_formspec(player_name) show_fs()
else for item in pairs(fields) do else for item in pairs(fields) do
if item:find(":") then if item:find(":") then
@ -459,7 +496,7 @@ mt.register_on_player_receive_fields(function(player, formname, fields)
data.rnum = 1 data.rnum = 1
end end
craftguide:get_formspec(player_name) show_fs()
else else
if progressive_mode then if progressive_mode then
local inv = player:get_inventory() local inv = player:get_inventory()
@ -474,92 +511,126 @@ mt.register_on_player_receive_fields(function(player, formname, fields)
data.rnum = 1 data.rnum = 1
data.show_usage = nil data.show_usage = nil
craftguide:get_formspec(player_name, is_fuel) show_fs(is_fuel)
end end
end end
end end
end end
end)
function craftguide:on_use(itemstack, user)
if not datas.init_items then
self:get_init_items()
end
local player_name = user:get_player_name()
local data = datas[player_name]
if progressive_mode or not data then
datas[player_name] = {filter = "", pagenum = 1, iX = DEFAULT_SIZE}
if progressive_mode then
self:get_filter_items(datas[player_name], user)
end
self:get_formspec(player_name)
else
show_formspec(player_name, "craftguide", data.formspec)
end
end end
mt.register_craftitem("craftguide:book", { if sfinv_only then
description = S("Crafting Guide"), sfinv.register_page("craftguide:craftguide", {
inventory_image = "craftguide_book.png", title = "Craft Guide",
wield_image = "craftguide_book.png", get = function(self, player, context)
stack_max = 1, local player_name = player:get_player_name()
groups = {book = 1}, return sfinv.make_formspec(
on_use = function(itemstack, user) player,
craftguide:on_use(itemstack, user) context,
craftguide:get_formspec(player_name, context.fuel)
)
end,
on_enter = function(self, player, context)
if not datas.init_items then
craftguide:get_init_items()
end
local player_name = player:get_player_name()
local data = datas[player_name]
if progressive_mode or not data then
datas[player_name] = {filter = "", pagenum = 1, iX = 8}
if progressive_mode then
craftguide:get_filter_items(datas[player_name], player)
end
end
end,
on_player_receive_fields = function(self, player, context, fields)
get_fields(player, fields)
end,
})
else
mt.register_on_player_receive_fields(get_fields)
function craftguide:on_use(itemstack, user)
if not datas.init_items then
self:get_init_items()
end
local player_name = user:get_player_name()
local data = datas[player_name]
if progressive_mode or not data then
datas[player_name] = {filter = "", pagenum = 1, iX = DEFAULT_SIZE}
if progressive_mode then
self:get_filter_items(datas[player_name], user)
end
self:get_formspec(player_name)
else
show_formspec(player_name, "craftguide", data.formspec)
end
end end
})
mt.register_node("craftguide:sign", { mt.register_craftitem("craftguide:book", {
description = S("Crafting Guide Sign"), description = S("Crafting Guide"),
drawtype = "nodebox", inventory_image = "craftguide_book.png",
tiles = {"craftguide_sign.png"}, wield_image = "craftguide_book.png",
inventory_image = "craftguide_sign_inv.png", stack_max = 1,
wield_image = "craftguide_sign_inv.png", groups = {book = 1},
paramtype = "light", on_use = function(itemstack, user)
paramtype2 = "wallmounted", craftguide:on_use(itemstack, user)
sunlight_propagates = true, end
groups = {wood = 1, oddly_breakable_by_hand = 1, flammable = 3}, })
node_box = {
type = "wallmounted",
wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125},
wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Crafting Guide Sign"))
end,
on_rightclick = function(pos, node, user, itemstack)
craftguide:on_use(itemstack, user)
end
})
mt.register_craft({ mt.register_node("craftguide:sign", {
output = "craftguide:book", description = S("Crafting Guide Sign"),
type = "shapeless", drawtype = "nodebox",
recipe = {"default:book"} tiles = {"craftguide_sign.png"},
}) inventory_image = "craftguide_sign_inv.png",
wield_image = "craftguide_sign_inv.png",
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
groups = {wood = 1, oddly_breakable_by_hand = 1, flammable = 3},
node_box = {
type = "wallmounted",
wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125},
wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Crafting Guide Sign"))
end,
on_rightclick = function(pos, node, user, itemstack)
craftguide:on_use(itemstack, user)
end
})
mt.register_craft({ mt.register_craft({
type = "fuel", output = "craftguide:book",
recipe = "craftguide:book", type = "shapeless",
burntime = 3 recipe = {"default:book"}
}) })
mt.register_craft({ mt.register_craft({
output = "craftguide:sign", type = "fuel",
type = "shapeless", recipe = "craftguide:book",
recipe = {"default:sign_wall_wood"} burntime = 3
}) })
mt.register_craft({ mt.register_craft({
type = "fuel", output = "craftguide:sign",
recipe = "craftguide:sign", type = "shapeless",
burntime = 10 recipe = {"default:sign_wall_wood"}
}) })
mt.register_craft({
type = "fuel",
recipe = "craftguide:sign",
burntime = 10
})
end
if rawget(_G, "sfinv_buttons") then if rawget(_G, "sfinv_buttons") then
sfinv_buttons.register_button("craftguide", { sfinv_buttons.register_button("craftguide", {
@ -572,8 +643,6 @@ if rawget(_G, "sfinv_buttons") then
}) })
end end
mt.register_alias("xdecor:crafting_guide", "craftguide:book")
--[[ Custom recipes (>3x3) test code --[[ Custom recipes (>3x3) test code
mt.register_craftitem("craftguide:custom_recipe_test", { mt.register_craftitem("craftguide:custom_recipe_test", {

4
settingtypes.txt Normal file

@ -0,0 +1,4 @@
#For enabling some options of craftguide.
craftguide_progressive_mode (Progressive Mode) bool false
craftguide_sfinv_only (Sfinv only) bool false