summaryrefslogtreecommitdiff
path: root/init.lua
blob: a035056ebf1908a67ce7a8697ca0d1774a4eeb0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
local craftguide, datas, npp = {}, {}, 8*3

function craftguide:get_recipe(item)
	if item:sub(1,6) == "group:" then
		if item:sub(-4) == "wool" or item:sub(-3) == "dye" then
			item = item:sub(7)..":white"
		elseif minetest.registered_items["default:"..item:sub(7)] then
			item = item:gsub("group:", "default:")
		else for node, def in pairs(minetest.registered_items) do
			 if def.groups[item:match("[^,:]+$")] then item = node end
		     end
		end
	end
	return item
end

function craftguide:get_formspec(player_name, pagenum, recipe_num)
	local data = datas[player_name]
	local formspec = [[ size[8,6.6;]
			tablecolumns[color;text;color;text]
			tableoptions[background=#00000000;highlight=#00000000;border=false]
			button[5.4,0;0.8,0.95;prev;<]
			button[7.2,0;0.8,0.95;next;>]
			button[2.5,0.2;0.8,0.5;search;?]
			button[3.2,0.2;0.8,0.5;clear;X]
			tooltip[search;Search]
			tooltip[clear;Reset]
			table[6,0.18;1.1,0.5;pagenum;#FFFF00,]]..
			pagenum..",#FFFFFF,/ "..data.pagemax.."]"..
			"field[0.3,0.32;2.6,1;filter;;"..data.filter.."]"..
			default.gui_bg..default.gui_bg_img

	local first_item = (pagenum - 1) * npp
	for i = first_item, first_item + npp - 1 do
		local name = data.items[i + 1]
		if not name then break end -- last page

		local X = i % 8
		local Y = ((i % npp - X) / 8) + 1

		formspec = formspec.."item_image_button["..X..","..Y..";1,1;"..
					name..";"..name..";]"
	end

	if data.item and minetest.registered_items[data.item] then
		local recipes = minetest.get_all_craft_recipes(data.item)
		if recipe_num > #recipes then recipe_num = 1 end

		if #recipes > 1 then formspec = formspec..
			[[ button[0,6;1.6,1;alternate;Alternate]
			label[0,5.5;Recipe ]]..recipe_num.." of "..#recipes.."]"
		end

		local type = recipes[recipe_num].type
		if type == "cooking" then formspec = formspec..
			"image[3.75,4.6;0.5,0.5;default_furnace_front.png]"
		end

		local items = recipes[recipe_num].items
		local width = recipes[recipe_num].width
		if width == 0 then width = math.min(3, #items) end
		-- Lua 5.3 removed `table.maxn`, use this alternative in case of breakage:
		-- https://github.com/kilbith/xdecor/blob/master/handlers/helpers.lua#L1
		local rows = math.ceil(table.maxn(items) / width)

		for i, v in pairs(items) do
			local X = (i-1) % width + 4.5
			local Y = math.floor((i-1) / width + (6 - math.min(2, rows)))
			local label = ""
			if v:sub(1,6) == "group:" then label = "\nG" end

			formspec = formspec.."item_image_button["..X..","..Y..";1,1;"..
					     self:get_recipe(v)..";"..self:get_recipe(v)..";"..label.."]"
		end

		local output = recipes[recipe_num].output
		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..";]"		     
	end

	data.formspec = formspec
	minetest.show_formspec(player_name, "xdecor:craftguide", formspec)
end

function craftguide:get_items(player_name)
	local items_list, data = {}, datas[player_name]
	for name, def in pairs(minetest.registered_items) do
		if not (def.groups.not_in_creative_inventory == 1) and
				minetest.get_craft_recipe(name).items and
				def.description and def.description ~= "" and
				(def.name:find(data.filter, 1, true) or
					def.description:lower():find(data.filter, 1, true)) then
			items_list[#items_list+1] = name
		end
	end

	table.sort(items_list)
	data.items = items_list
	data.size = #items_list
	data.pagemax = math.ceil(data.size / npp)
end

minetest.register_on_player_receive_fields(function(player, formname, fields)
	if formname ~= "xdecor:craftguide" then return end
	local player_name = player:get_player_name()
	local data = datas[player_name]
	local formspec = data.formspec
	local pagenum = tonumber(formspec:match("#FFFF00,(%d+)")) or 1

	if fields.clear then
		data.filter, data.item = "", nil
		craftguide:get_items(player_name)
		craftguide:get_formspec(player_name, 1, 1)
	elseif fields.alternate then
		local recipe_num = tonumber(formspec:match("Recipe%s(%d+)")) or 1
		recipe_num = recipe_num + 1
		craftguide:get_formspec(player_name, pagenum, recipe_num)
	elseif fields.search then
		data.filter = fields.filter:lower()
		craftguide:get_items(player_name)
		craftguide:get_formspec(player_name, 1, 1)
	elseif fields.prev or fields.next then
		if fields.prev then pagenum = pagenum - 1
		else pagenum = pagenum + 1 end
		if     pagenum > data.pagemax then pagenum = 1
		elseif pagenum == 0	      then pagenum = data.pagemax end
		craftguide:get_formspec(player_name, pagenum, 1)
	else for item in pairs(fields) do
		 if minetest.get_craft_recipe(item).items then
			data.item = item
			craftguide:get_formspec(player_name, pagenum, 1)
		 end
	     end
	end
end)

minetest.register_craftitem(":xdecor:crafting_guide", {
	description = "Crafting Guide",
	inventory_image = "crafting_guide.png",
	wield_image = "crafting_guide.png",
	stack_max = 1,
	groups = {book=1},
	on_use = function(itemstack, user)
		local player_name = user:get_player_name()
		if not datas[player_name] then
			datas[player_name] = {}
			datas[player_name].filter = ""
			craftguide:get_items(player_name)
			craftguide:get_formspec(player_name, 1, 1)
		else
			minetest.show_formspec(player_name, "xdecor:craftguide", datas[player_name].formspec)
		end
	end
})

minetest.register_craft({ 
	output = "xdecor:crafting_guide",
	type = "shapeless",
	recipe = {"default:book"}
})