Compare commits
	
		
			54 Commits
		
	
	
		
			1.14
			...
			4cc44d004e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4cc44d004e | ||
|  | 584c215aee | ||
|  | 5b91f9f171 | ||
|  | 54e6406e53 | ||
|  | 917dd8714f | ||
|  | 6ef7dda7de | ||
|  | a3c41cbd8d | ||
|  | 3866c41ab9 | ||
|  | e2c13c4d27 | ||
|  | a7d5653d8f | ||
|  | efe7434dd4 | ||
|  | df26d31a2d | ||
|  | 50d19faa48 | ||
|  | d93f5b0cf2 | ||
|  | f83bc9cccf | ||
|  | f88e0412fc | ||
|  | 6e6ff93d29 | ||
|  | 2fd3604cac | ||
|  | 96f9c85c77 | ||
|  | 9412ac740a | ||
|  | f2a5c4255e | ||
|  | d903aaca89 | ||
|  | c30db91662 | ||
|  | 1fb7790c4e | ||
|  | 74785bca5e | ||
|  | 7ea6899b06 | ||
|  | 9a0e36d884 | ||
|  | 9890d8a669 | ||
|  | 98f8499103 | ||
|  | d57cb7865b | ||
|  | 0b37b2bb2f | ||
|  | 701c7ae690 | ||
|  | 14c1372550 | ||
|  | 4a85acec9a | ||
|  | fa1e330856 | ||
|  | 89979a8610 | ||
|  | 2771ec12f5 | ||
|  | bba7dd81b9 | ||
|  | 1ebc1eab68 | ||
|  | 84a7377ed0 | ||
|  | c008f5097d | ||
|  | bfa7f4d631 | ||
|  | 3a0a2c032d | ||
|  | bfdb67783b | ||
|  | 00dcea5c50 | ||
|  | 361c64e51c | ||
|  | c0823faad3 | ||
|  | e6d1857799 | ||
|  | 95e1aea493 | ||
|  | 1980fefa50 | ||
|  | 835ab3ba36 | ||
|  | b596a0d10c | ||
|  | a51fe10c92 | ||
|  | 24115a0d84 | 
| @@ -1,5 +1,7 @@ | |||||||
| #  Crafting Guide | #  Crafting Guide | ||||||
|  |  | ||||||
|  | [](https://content.minetest.net/packages/jp/craftguide/) [](https://content.minetest.net/packages/jp/craftguide/) | ||||||
|  |  | ||||||
| #### `craftguide` is the most comprehensive crafting guide on Minetest. | #### `craftguide` is the most comprehensive crafting guide on Minetest. | ||||||
| #### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. | #### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										495
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						| @@ -7,6 +7,7 @@ local searches      = {} | |||||||
| local recipes_cache = {} | local recipes_cache = {} | ||||||
| local usages_cache  = {} | local usages_cache  = {} | ||||||
| local fuel_cache    = {} | local fuel_cache    = {} | ||||||
|  | local replacements  = {fuel = {}} | ||||||
| local toolrepair | local toolrepair | ||||||
|  |  | ||||||
| local progressive_mode = core.settings:get_bool "craftguide_progressive_mode" | local progressive_mode = core.settings:get_bool "craftguide_progressive_mode" | ||||||
| @@ -22,6 +23,7 @@ local reg_aliases = core.registered_aliases | |||||||
| local log = core.log | local log = core.log | ||||||
| local after = core.after | local after = core.after | ||||||
| local clr = core.colorize | local clr = core.colorize | ||||||
|  | local sound_play = core.sound_play | ||||||
| local parse_json = core.parse_json | local parse_json = core.parse_json | ||||||
| local write_json = core.write_json | local write_json = core.write_json | ||||||
| local chat_send = core.chat_send_player | local chat_send = core.chat_send_player | ||||||
| @@ -30,6 +32,7 @@ local globalstep = core.register_globalstep | |||||||
| local on_shutdown = core.register_on_shutdown | local on_shutdown = core.register_on_shutdown | ||||||
| local get_players = core.get_connected_players | local get_players = core.get_connected_players | ||||||
| local get_craft_result = core.get_craft_result | local get_craft_result = core.get_craft_result | ||||||
|  | local translate = minetest.get_translated_string | ||||||
| local on_joinplayer = core.register_on_joinplayer | local on_joinplayer = core.register_on_joinplayer | ||||||
| local get_all_recipes = core.get_all_craft_recipes | local get_all_recipes = core.get_all_craft_recipes | ||||||
| local register_command = core.register_chatcommand | local register_command = core.register_chatcommand | ||||||
| @@ -38,7 +41,6 @@ local slz, dslz = core.serialize, core.deserialize | |||||||
| local on_mods_loaded = core.register_on_mods_loaded | local on_mods_loaded = core.register_on_mods_loaded | ||||||
| local on_leaveplayer = core.register_on_leaveplayer | local on_leaveplayer = core.register_on_leaveplayer | ||||||
| local get_player_info = core.get_player_information | local get_player_info = core.get_player_information | ||||||
| local get_translation = minetest.get_translated_string |  | ||||||
| local on_receive_fields = core.register_on_player_receive_fields | local on_receive_fields = core.register_on_player_receive_fields | ||||||
|  |  | ||||||
| local ESC = core.formspec_escape | local ESC = core.formspec_escape | ||||||
| @@ -75,25 +77,25 @@ local POLL_FREQ = 0.25 | |||||||
| local HUD_TIMER_MAX = 1.5 | local HUD_TIMER_MAX = 1.5 | ||||||
|  |  | ||||||
| local PNG = { | local PNG = { | ||||||
| 	bg        = "craftguide_bg.png", | 	bg = "craftguide_bg.png", | ||||||
| 	bg_full   = "craftguide_bg_full.png", | 	bg_full = "craftguide_bg_full.png", | ||||||
| 	search    = "craftguide_search_icon.png", | 	search = "craftguide_search_icon.png", | ||||||
| 	clear     = "craftguide_clear_icon.png", | 	clear = "craftguide_clear_icon.png", | ||||||
| 	prev      = "craftguide_next_icon.png^\\[transformFX", | 	prev = "craftguide_next_icon.png^\\[transformFX", | ||||||
| 	next      = "craftguide_next_icon.png", | 	next = "craftguide_next_icon.png", | ||||||
| 	arrow     = "craftguide_arrow.png", | 	arrow = "craftguide_arrow.png", | ||||||
| 	fire      = "craftguide_fire.png", | 	fire = "craftguide_fire.png", | ||||||
| 	fire_anim = "craftguide_fire_anim.png", | 	fire_anim = "craftguide_fire_anim.png", | ||||||
| 	book      = "craftguide_book.png", | 	book = "craftguide_book.png", | ||||||
| 	sign      = "craftguide_sign.png", | 	sign = "craftguide_sign.png", | ||||||
| 	nothing   = "craftguide_no.png", | 	nothing = "craftguide_no.png", | ||||||
| 	selected  = "craftguide_selected.png", | 	selected = "craftguide_selected.png", | ||||||
| 	furnace_anim = "craftguide_furnace_anim.png", | 	furnace_anim = "craftguide_furnace_anim.png", | ||||||
|  |  | ||||||
| 	search_hover = "craftguide_search_icon_hover.png", | 	search_hover = "craftguide_search_icon_hover.png", | ||||||
| 	clear_hover  = "craftguide_clear_icon_hover.png", | 	clear_hover = "craftguide_clear_icon_hover.png", | ||||||
| 	prev_hover   = "craftguide_next_icon_hover.png^\\[transformFX", | 	prev_hover = "craftguide_next_icon_hover.png^\\[transformFX", | ||||||
| 	next_hover   = "craftguide_next_icon_hover.png", | 	next_hover = "craftguide_next_icon_hover.png", | ||||||
| } | } | ||||||
|  |  | ||||||
| local FMT = { | local FMT = { | ||||||
| @@ -102,6 +104,7 @@ local FMT = { | |||||||
| 	image = "image[%f,%f;%f,%f;%s]", | 	image = "image[%f,%f;%f,%f;%s]", | ||||||
| 	button = "button[%f,%f;%f,%f;%s;%s]", | 	button = "button[%f,%f;%f,%f;%s;%s]", | ||||||
| 	tooltip = "tooltip[%f,%f;%f,%f;%s]", | 	tooltip = "tooltip[%f,%f;%f,%f;%s]", | ||||||
|  | 	hypertext = "hypertext[%f,%f;%f,%f;;%s]", | ||||||
| 	item_image = "item_image[%f,%f;%f,%f;%s]", | 	item_image = "item_image[%f,%f;%f,%f;%s]", | ||||||
| 	image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", | 	image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", | ||||||
| 	animated_image = "animated_image[%f,%f;%f,%f;;%s;%u;%u]", | 	animated_image = "animated_image[%f,%f;%f,%f;;%s;%u;%u]", | ||||||
| @@ -109,6 +112,31 @@ local FMT = { | |||||||
| 	arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s]", | 	arrow = "image_button[%f,%f;0.8,0.8;%s;%s;;;false;%s]", | ||||||
| } | } | ||||||
|  |  | ||||||
|  | local styles = fmt([[ | ||||||
|  | 	style[filter;border=false] | ||||||
|  | 	style_type[label,field;font_size=16] | ||||||
|  | 	style_type[image_button;border=false] | ||||||
|  | 	style_type[button;border=false;font=bold;font_size=18] | ||||||
|  | 	style_type[item_image_button;border=false;bgimg_hovered=%s;bgimg_pressed=%s] | ||||||
|  | 	style[search;fgimg=%s;fgimg_hovered=%s] | ||||||
|  | 	style[clear;fgimg=%s;fgimg_hovered=%s] | ||||||
|  | 	style[prev_page;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] | ||||||
|  | 	style[next_page;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] | ||||||
|  | 	style[prev_recipe;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] | ||||||
|  | 	style[next_recipe;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] | ||||||
|  | 	style[prev_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] | ||||||
|  | 	style[next_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] | ||||||
|  | ]], | ||||||
|  | PNG.selected, PNG.selected, | ||||||
|  | PNG.search, PNG.search_hover, | ||||||
|  | PNG.clear, PNG.clear_hover, | ||||||
|  | PNG.prev, PNG.prev_hover, PNG.prev_hover, | ||||||
|  | PNG.next, PNG.next_hover, PNG.next_hover, | ||||||
|  | PNG.prev, PNG.prev_hover, PNG.prev_hover, | ||||||
|  | PNG.next, PNG.next_hover, PNG.next_hover, | ||||||
|  | PNG.prev, PNG.prev_hover, PNG.prev_hover, | ||||||
|  | PNG.next, PNG.next_hover, PNG.next_hover) | ||||||
|  |  | ||||||
| local function get_lang_code(name) | local function get_lang_code(name) | ||||||
| 	local info = get_player_info(name) | 	local info = get_player_info(name) | ||||||
| 	return info and info.lang_code | 	return info and info.lang_code | ||||||
| @@ -144,6 +172,11 @@ craftguide.group_stereotypes = { | |||||||
| 	wool = "wool:white", | 	wool = "wool:white", | ||||||
| 	wood = "default:wood", | 	wood = "default:wood", | ||||||
| 	tree = "default:tree", | 	tree = "default:tree", | ||||||
|  | 	sand = "default:sand", | ||||||
|  | 	glass = "default:glass", | ||||||
|  | 	stick = "default:stick", | ||||||
|  | 	stone = "default:stone", | ||||||
|  | 	leaves = "default:leaves", | ||||||
| 	coal = "default:coal_lump", | 	coal = "default:coal_lump", | ||||||
| 	vessel = "vessels:glass_bottle", | 	vessel = "vessels:glass_bottle", | ||||||
| 	flower = "flowers:dandelion_yellow", | 	flower = "flowers:dandelion_yellow", | ||||||
| @@ -152,18 +185,20 @@ craftguide.group_stereotypes = { | |||||||
| } | } | ||||||
|  |  | ||||||
| local group_names = { | local group_names = { | ||||||
| 	carpet = S"Any carpet", |  | ||||||
| 	coal = S"Any coal", |  | ||||||
| 	dye = S"Any dye", | 	dye = S"Any dye", | ||||||
| 	flower = S"Any flower", | 	coal = S"Any coal", | ||||||
| 	mushroom = S"Any mushroom", |  | ||||||
| 	sand = S"Any sand", | 	sand = S"Any sand", | ||||||
| 	stick = S"Any stick", | 	tree = S"Any tree", | ||||||
| 	stone = S"Any kind of stone block", |  | ||||||
| 	tree  = S"Any tree", |  | ||||||
| 	vessel = S"Any vessel", |  | ||||||
| 	wool = S"Any wool", | 	wool = S"Any wool", | ||||||
|  | 	glass = S"Any glass", | ||||||
|  | 	stick = S"Any stick", | ||||||
|  | 	stone = S"Any stone", | ||||||
|  | 	carpet = S"Any carpet", | ||||||
|  | 	flower = S"Any flower", | ||||||
|  | 	leaves = S"Any leaves", | ||||||
|  | 	vessel = S"Any vessel", | ||||||
| 	wood = S"Any wood planks", | 	wood = S"Any wood planks", | ||||||
|  | 	mushroom = S"Any mushroom", | ||||||
|  |  | ||||||
| 	["color_red,flower"] = S"Any red flower", | 	["color_red,flower"] = S"Any red flower", | ||||||
| 	["color_blue,flower"] = S"Any blue flower", | 	["color_blue,flower"] = S"Any blue flower", | ||||||
| @@ -566,7 +601,12 @@ end | |||||||
| local function cache_fuel(item) | local function cache_fuel(item) | ||||||
| 	local burntime = get_burntime(item) | 	local burntime = get_burntime(item) | ||||||
| 	if burntime > 0 then | 	if burntime > 0 then | ||||||
| 		fuel_cache[item] = burntime | 		fuel_cache[item] = { | ||||||
|  | 			type = "fuel", | ||||||
|  | 			items = {item}, | ||||||
|  | 			burntime = burntime, | ||||||
|  | 			replacements = replacements.fuel[item], | ||||||
|  | 		} | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -612,79 +652,55 @@ local function cache_usages(item) | |||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if fuel_cache[item] then | 	if fuel_cache[item] then | ||||||
| 		local fuel = { | 		usages_cache[item] = table_merge(usages_cache[item] or {}, {fuel_cache[item]}) | ||||||
| 			type = "fuel", |  | ||||||
| 			items = {item}, |  | ||||||
| 			replacements = fuel_cache.replacements[item], |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		usages_cache[item] = table_merge(usages_cache[item] or {}, {fuel}) |  | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| local function drop_table(name, drop) | local function drop_table(name, drop) | ||||||
| 	local drop_sure, drop_maybe = {}, {} | 	local count_sure = 0 | ||||||
| 	local drop_items = drop.items or {} | 	local drop_items = drop.items or {} | ||||||
|  | 	local max_items = drop.max_items | ||||||
|  |  | ||||||
| 	for i = 1, #drop_items do | 	for i = 1, #drop_items do | ||||||
| 		local di = drop_items[i] | 		local di = drop_items[i] | ||||||
|  | 		local valid_rarity = di.rarity and di.rarity > 1 | ||||||
|  |  | ||||||
| 		for j = 1, #di.items do | 		if di.rarity or not max_items or | ||||||
| 			local dstack = ItemStack(di.items[j]) | 				(max_items and not di.rarity and count_sure < max_items) then | ||||||
| 			local dname  = dstack:get_name() | 			for j = 1, #di.items do | ||||||
| 			local dcount = dstack:get_count() | 				local dstack = ItemStack(di.items[j]) | ||||||
|  | 				local dname  = dstack:get_name() | ||||||
|  | 				local dcount = dstack:get_count() | ||||||
|  | 				local empty  = dstack:is_empty() | ||||||
|  |  | ||||||
| 			if not dstack:is_empty() and (dname ~= name or | 				if not empty and (dname ~= name or | ||||||
| 					(dname == name and dcount > 1)) then | 						(dname == name and dcount > 1)) then | ||||||
| 				if #di.items == 1 and (not di.rarity or di.rarity <= 1) then | 					local rarity = valid_rarity and di.rarity | ||||||
| 					if drop_sure[dname] then |  | ||||||
| 						if dcount > drop_sure[dname].output then |  | ||||||
| 							dcount = dcount + drop_sure[dname].output |  | ||||||
| 						else |  | ||||||
| 							dcount = drop_sure[dname].output |  | ||||||
| 						end |  | ||||||
| 					end |  | ||||||
|  |  | ||||||
| 					drop_sure[dname] = { | 					craftguide.register_craft{ | ||||||
| 						output = dcount, | 						type   = rarity and "digging_chance" or "digging", | ||||||
| 						tools  = di.tools, | 						items  = {name}, | ||||||
| 					} | 						output = fmt("%s %u", dname, dcount), | ||||||
| 				else | 						rarity = rarity, | ||||||
| 					drop_maybe[#drop_maybe + 1] = { |  | ||||||
| 						item   = dname, |  | ||||||
| 						output = dcount, |  | ||||||
| 						rarity = di.rarity, |  | ||||||
| 						tools  = di.tools, | 						tools  = di.tools, | ||||||
| 					} | 					} | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	for item, data in pairs(drop_sure) do | 		if not di.rarity then | ||||||
| 		craftguide.register_craft{ | 			count_sure = count_sure + 1 | ||||||
| 			type   = "digging", | 		end | ||||||
| 			items  = {name}, |  | ||||||
| 			output = fmt("%s %u", item, data.output), |  | ||||||
| 			tools  = data.tools, |  | ||||||
| 		} |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	for _, data in ipairs(drop_maybe) do |  | ||||||
| 		craftguide.register_craft{ |  | ||||||
| 			type   = "digging_chance", |  | ||||||
| 			items  = {name}, |  | ||||||
| 			output = fmt("%s %u", data.item, data.output), |  | ||||||
| 			rarity = data.rarity, |  | ||||||
| 			tools  = data.tools, |  | ||||||
| 		} |  | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| local function cache_drops(name, drop) | local function cache_drops(name, drop) | ||||||
| 	if true_str(drop) then | 	if true_str(drop) then | ||||||
| 		local dstack = ItemStack(drop) | 		local dstack = ItemStack(drop) | ||||||
| 		if not dstack:is_empty() and dstack:get_name() ~= name then | 		local dname  = dstack:get_name() | ||||||
|  | 		local empty  = dstack:is_empty() | ||||||
|  |  | ||||||
|  | 		if not empty and dname ~= name then | ||||||
| 			craftguide.register_craft{ | 			craftguide.register_craft{ | ||||||
| 				type = "digging", | 				type = "digging", | ||||||
| 				items = {name}, | 				items = {name}, | ||||||
| @@ -697,14 +713,35 @@ local function cache_drops(name, drop) | |||||||
| end | end | ||||||
|  |  | ||||||
| local function cache_recipes(item) | local function cache_recipes(item) | ||||||
| 	item = reg_aliases[item] or item | 	local recipes = get_all_recipes(item) | ||||||
| 	local def = reg_items[item] |  | ||||||
| 	if not def then return end |  | ||||||
| 	local recipes = get_all_recipes(item) or {} |  | ||||||
|  |  | ||||||
| 	for i = 1, #recipes do | 	if replacements[item] then | ||||||
| 		recipes_cache[item] = table_merge(recipes_cache[item] or {}, recipes[i]) | 		local _recipes = {} | ||||||
|  |  | ||||||
|  | 		for k, v in ipairs(recipes or {}) do | ||||||
|  | 			_recipes[#recipes + 1 - k] = v | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		local shift = 0 | ||||||
|  | 		local size_rpl = maxn(replacements[item]) | ||||||
|  | 		local size_rcp = #_recipes | ||||||
|  |  | ||||||
|  | 		if size_rpl > size_rcp then | ||||||
|  | 			shift = size_rcp - size_rpl | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		for k, v in pairs(replacements[item]) do | ||||||
|  | 			k = k + shift | ||||||
|  |  | ||||||
|  | 			if _recipes[k] then | ||||||
|  | 				_recipes[k].replacements = v | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		recipes = _recipes | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
|  | 	recipes_cache[item] = recipes | ||||||
| end | end | ||||||
|  |  | ||||||
| local function get_recipes(item, data, player) | local function get_recipes(item, data, player) | ||||||
| @@ -741,21 +778,17 @@ end | |||||||
| local function groups_to_items(groups, get_all) | local function groups_to_items(groups, get_all) | ||||||
| 	if not get_all and #groups == 1 then | 	if not get_all and #groups == 1 then | ||||||
| 		local group = groups[1] | 		local group = groups[1] | ||||||
| 		local def_gr = "default:" .. group | 		local stereotype = craftguide.group_stereotypes[group] | ||||||
| 		local stereotypes = craftguide.group_stereotypes | 		local def = reg_items[stereotype] | ||||||
| 		local stereotype = stereotypes and stereotypes[group] |  | ||||||
| 		stereotype = reg_items[stereotype] and stereotype |  | ||||||
|  |  | ||||||
| 		if stereotype then | 		if def and show_item(def) then | ||||||
| 			return stereotype | 			return stereotype | ||||||
| 		elseif reg_items[def_gr] then |  | ||||||
| 			return def_gr |  | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local names = {} | 	local names = {} | ||||||
| 	for name, def in pairs(reg_items) do | 	for name, def in pairs(reg_items) do | ||||||
| 		if item_has_groups(def.groups, groups) then | 		if show_item(def) and item_has_groups(def.groups, groups) then | ||||||
| 			if get_all then | 			if get_all then | ||||||
| 				names[#names + 1] = name | 				names[#names + 1] = name | ||||||
| 			else | 			else | ||||||
| @@ -785,8 +818,20 @@ local function is_fav(favs, query_item) | |||||||
| 	return fav, i | 	return fav, i | ||||||
| end | end | ||||||
|  |  | ||||||
| local function str_newline(str) | local function weird_desc(str) | ||||||
| 	return find(str, "\n") | 	return not true_str(str) or find(str, "[\\]*") or not find(str, "%u") | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local function toupper(str) | ||||||
|  | 	return str:gsub("%f[%w]%l", upper):gsub("_", " ") | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local function strip_newline(str) | ||||||
|  | 	return match(str, "[^\n]*") | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local function strip_prefix(str) | ||||||
|  | 	return match(str, ".*@.*%)(.*)()") or str | ||||||
| end | end | ||||||
|  |  | ||||||
| local function get_desc(item, lang_code) | local function get_desc(item, lang_code) | ||||||
| @@ -797,10 +842,21 @@ local function get_desc(item, lang_code) | |||||||
| 	local def = reg_items[item] | 	local def = reg_items[item] | ||||||
|  |  | ||||||
| 	if def then | 	if def then | ||||||
| 		if true_str(def.description) then | 		local desc = def.description | ||||||
| 			return match(get_translation(lang_code, def.description), "[^\n]*") | 		if true_str(desc) then | ||||||
|  | 			desc = translate(lang_code, desc) | ||||||
|  | 			desc = desc:trim() | ||||||
|  | 			desc = strip_newline(desc) | ||||||
|  | 			desc = strip_prefix(desc) | ||||||
|  |  | ||||||
|  | 			if not find(desc, "%u") then | ||||||
|  | 				desc = toupper(desc) | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			return desc | ||||||
|  |  | ||||||
| 		elseif true_str(item) then | 		elseif true_str(item) then | ||||||
| 			return match(item, ":.*"):gsub("%W%l", upper):sub(2):gsub("_", " ") | 			return toupper(match(item, ":(.*)")) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| @@ -841,13 +897,13 @@ local function get_tooltip(item, info, lang_code) | |||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if info.replace then | 	if info.replace then | ||||||
| 		for i = 1, #info.replace do | 		for i = 1, #info.replace.items do | ||||||
| 			local rpl = info.replace[i] | 			local rpl = match(info.replace.items[i], "%S+") | ||||||
| 			local desc = clr("#ff0", get_desc(rpl, lang_code)) | 			local desc = clr("#ff0", get_desc(rpl, lang_code)) | ||||||
|  |  | ||||||
| 			if info.cooktime then | 			if info.replace.type == "cooking" then | ||||||
| 				tooltip = add(S("Replaced by @1 on smelting", desc)) | 				tooltip = add(S("Replaced by @1 on smelting", desc)) | ||||||
| 			elseif info.burntime then | 			elseif info.replace.type == "fuel" then | ||||||
| 				tooltip = add(S("Replaced by @1 on burning", desc)) | 				tooltip = add(S("Replaced by @1 on burning", desc)) | ||||||
| 			else | 			else | ||||||
| 				tooltip = add(S("Replaced by @1 on crafting", desc)) | 				tooltip = add(S("Replaced by @1 on crafting", desc)) | ||||||
| @@ -913,39 +969,40 @@ local function get_output_fs(lang_code, fs, rcp, shapeless, right, btn_size, _bt | |||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local arrow_X = right + (_btn_size or ITEM_BTN_SIZE) | 	local arrow_X = right + (_btn_size or ITEM_BTN_SIZE) | ||||||
| 	local output_X = arrow_X + 0.9 | 	local X = arrow_X + 0.9 | ||||||
| 	local Y = YOFFSET + (sfinv_only and 2 or 0) + spacing | 	local Y = YOFFSET + (sfinv_only and 2 or 0) + spacing | ||||||
|  |  | ||||||
| 	fs[#fs + 1] = fmt(FMT.image, arrow_X, Y + 0.2, 0.9, 0.7, PNG.arrow) | 	fs[#fs + 1] = fmt(FMT.image, arrow_X, Y + 0.2, 0.9, 0.7, PNG.arrow) | ||||||
|  |  | ||||||
| 	if rcp.type == "fuel" then | 	if rcp.type == "fuel" then | ||||||
| 		fs[#fs + 1] = fmt(FMT.animated_image, output_X, Y, | 		fs[#fs + 1] = fmt(FMT.animated_image, X, Y, | ||||||
| 			ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.fire_anim, 8, 180) | 			ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.fire_anim, 8, 180) | ||||||
| 	else | 	else | ||||||
| 		local item = rcp.output | 		local item = rcp.output | ||||||
| 		item = clean_name(item) | 		item = clean_name(item) | ||||||
| 		local name = match(item, "%S*") | 		local name = match(item, "%S*") | ||||||
|  |  | ||||||
| 		fs[#fs + 1] = fmt(FMT.image, output_X, Y, | 		fs[#fs + 1] = fmt(FMT.image, X, Y, | ||||||
| 			ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.selected) | 			ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.selected) | ||||||
|  |  | ||||||
| 		local _name = sfinv_only and name or fmt("_%s", name) | 		local _name = sfinv_only and name or fmt("_%s", name) | ||||||
|  |  | ||||||
| 		fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", | 		fs[#fs + 1] = fmt("item_image_button[%f,%f;%f,%f;%s;%s;%s]", | ||||||
| 			output_X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, item, _name, "") | 			X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, item, _name, "") | ||||||
|  |  | ||||||
| 		local def = reg_items[name] | 		local def = reg_items[name] | ||||||
| 		local unknown = not def or nil | 		local unknown = not def or nil | ||||||
| 		local weird_desc = name ~= "" and def and | 		local desc = def and def.description | ||||||
| 			(not true_str(def.description) or str_newline(def.description)) or nil | 		local weird = name ~= "" and desc and weird_desc(desc) or nil | ||||||
|  | 		local burntime = fuel_cache[name] and fuel_cache[name].burntime | ||||||
|  |  | ||||||
| 		local infos = { | 		local infos = { | ||||||
| 			unknown    = unknown, | 			unknown  = unknown, | ||||||
| 			weird_desc = weird_desc, | 			weird    = weird, | ||||||
| 			burntime   = fuel_cache[name], | 			burntime = burntime, | ||||||
| 			repair     = repairable(name), | 			repair   = repairable(name), | ||||||
| 			rarity     = rcp.rarity, | 			rarity   = rcp.rarity, | ||||||
| 			tools      = rcp.tools, | 			tools    = rcp.tools, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if next(infos) then | 		if next(infos) then | ||||||
| @@ -954,11 +1011,11 @@ local function get_output_fs(lang_code, fs, rcp, shapeless, right, btn_size, _bt | |||||||
|  |  | ||||||
| 		if infos.burntime then | 		if infos.burntime then | ||||||
| 			fs[#fs + 1] = fmt(FMT.image, | 			fs[#fs + 1] = fmt(FMT.image, | ||||||
| 				output_X + 1, YOFFSET + (sfinv_only and 2 or 0.1) + spacing, | 				X + 1, YOFFSET + (sfinv_only and 2 or 0.1) + spacing, | ||||||
| 				0.6, 0.4, PNG.arrow) | 				0.6, 0.4, PNG.arrow) | ||||||
|  |  | ||||||
| 			fs[#fs + 1] = fmt(FMT.animated_image, | 			fs[#fs + 1] = fmt(FMT.animated_image, | ||||||
| 				output_X + 1.6, YOFFSET + (sfinv_only and 1.85 or 0) + spacing, | 				X + 1.6, YOFFSET + (sfinv_only and 1.85 or 0) + spacing, | ||||||
| 				0.6, 0.6, PNG.fire_anim, 8, 180) | 				0.6, 0.6, PNG.fire_anim, 8, 180) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| @@ -1026,14 +1083,23 @@ local function get_grid_fs(lang_code, fs, rcp, spacing) | |||||||
| 		local label = groups and "\nG" or "" | 		local label = groups and "\nG" or "" | ||||||
| 		local replace | 		local replace | ||||||
|  |  | ||||||
| 		if rcp.replacements then | 		for j = 1, #(rcp.replacements or {}) do | ||||||
| 			replace = {} | 			local replacement = rcp.replacements[j] | ||||||
| 			label = fmt("%s%s\nR", label ~= "" and "\n" or "", label) | 			if replacement[1] == name then | ||||||
|  | 				replace = replace or {type = rcp.type, items = {}} | ||||||
|  |  | ||||||
| 			for j = 1, #rcp.replacements do | 				local added | ||||||
| 				local replacement = rcp.replacements[j] |  | ||||||
| 				if replacement[1] == name then | 				for _, v in ipairs(replace.items) do | ||||||
| 					replace[#replace + 1] = replacement[2] | 					if replacement[2] == v then | ||||||
|  | 						added = true | ||||||
|  | 						break | ||||||
|  | 					end | ||||||
|  | 				end | ||||||
|  |  | ||||||
|  | 				if not added then | ||||||
|  | 					label = fmt("%s%s\nR", label ~= "" and "\n" or "", label) | ||||||
|  | 					replace.items[#replace.items + 1] = replacement[2] | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| @@ -1044,26 +1110,35 @@ local function get_grid_fs(lang_code, fs, rcp, spacing) | |||||||
| 			fs[#fs + 1] = fmt(FMT.image, X, Y, btn_size, btn_size, PNG.selected) | 			fs[#fs + 1] = fmt(FMT.image, X, Y, btn_size, btn_size, PNG.selected) | ||||||
| 		end | 		end | ||||||
|  |  | ||||||
|  | 		local btn_name = "" | ||||||
|  |  | ||||||
|  | 		if groups then | ||||||
|  | 			btn_name = fmt("group|%s|%s", groups[1], item) | ||||||
|  | 		elseif item ~= "" then | ||||||
|  | 			btn_name = item | ||||||
|  | 		end | ||||||
|  |  | ||||||
| 		fs[#fs + 1] = fmt(FMT.item_image_button, | 		fs[#fs + 1] = fmt(FMT.item_image_button, | ||||||
| 			X, Y, btn_size, btn_size, item, item, label) | 			X, Y, btn_size, btn_size, item, btn_name, label) | ||||||
|  |  | ||||||
| 		local def = reg_items[name] | 		local def = reg_items[name] | ||||||
| 		local unknown = not def or nil | 		local unknown = not def or nil | ||||||
| 		unknown = not groups and unknown or nil | 		unknown = not groups and unknown or nil | ||||||
| 		local weird_desc = name ~= "" and def and | 		local desc = def and def.description | ||||||
| 			(not true_str(def.description) or str_newline(def.description)) or nil | 		local weird = name ~= "" and desc and weird_desc(desc) or nil | ||||||
|  | 		local burntime = fuel_cache[name] and fuel_cache[name].burntime | ||||||
|  |  | ||||||
| 		local infos = { | 		local infos = { | ||||||
| 			unknown    = unknown, | 			unknown  = unknown, | ||||||
| 			weird_desc = weird_desc, | 			weird    = weird, | ||||||
| 			groups     = groups, | 			groups   = groups, | ||||||
| 			burntime   = fuel_cache[name], | 			burntime = burntime, | ||||||
| 			cooktime   = cooktime, | 			cooktime = cooktime, | ||||||
| 			replace    = replace, | 			replace  = replace, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if next(infos) then | 		if next(infos) then | ||||||
| 			fs[#fs + 1] = get_tooltip(item, infos, lang_code) | 			fs[#fs + 1] = get_tooltip(btn_name, infos, lang_code) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| @@ -1088,8 +1163,9 @@ local function get_rcp_lbl(lang_code, show_usages, unum, rnum, fs, panel, spacin | |||||||
| 			ES("Recipe @1 of @2", rnum, rn) | 			ES("Recipe @1 of @2", rnum, rn) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	lbl = get_translation(lang_code, lbl) | 	lbl = translate(lang_code, lbl) | ||||||
| 	local shift = min(0.9, abs(13 - max(13, #lbl)) * 0.1) | 	local lbl_len = #lbl:gsub("[\128-\191]", "") -- Count chars, not bytes in UTF-8 strings | ||||||
|  | 	local shift = min(0.9, abs(13 - max(13, lbl_len)) * 0.1) | ||||||
|  |  | ||||||
| 	fs[#fs + 1] = fmt(FMT.label, | 	fs[#fs + 1] = fmt(FMT.label, | ||||||
| 		XOFFSET + (sfinv_only and 2.3 or 1.6) - shift, | 		XOFFSET + (sfinv_only and 2.3 or 1.6) - shift, | ||||||
| @@ -1102,13 +1178,6 @@ local function get_rcp_lbl(lang_code, show_usages, unum, rnum, fs, panel, spacin | |||||||
| 		local x_arrow = XOFFSET + (sfinv_only and 1.7 or 1) | 		local x_arrow = XOFFSET + (sfinv_only and 1.7 or 1) | ||||||
| 		local y_arrow = YOFFSET + (sfinv_only and 3.3 or 1.4 + spacing) | 		local y_arrow = YOFFSET + (sfinv_only and 3.3 or 1.4 + spacing) | ||||||
|  |  | ||||||
| 		fs[#fs + 1] = fmt([[ |  | ||||||
| 			style[%s;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] |  | ||||||
| 			style[%s;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] |  | ||||||
| 		]], |  | ||||||
| 		prev_name, PNG.prev, PNG.prev_hover, PNG.prev_hover, |  | ||||||
| 		next_name, PNG.next, PNG.next_hover, PNG.next_hover) |  | ||||||
|  |  | ||||||
| 		fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), | 		fs[#fs + 1] = fmt(mul_elem(FMT.arrow, 2), | ||||||
| 			x_arrow - shift, y_arrow, PNG.prev, prev_name, "", | 			x_arrow - shift, y_arrow, PNG.prev, prev_name, "", | ||||||
| 			x_arrow + 1.8,   y_arrow, PNG.next, next_name, "") | 			x_arrow + 1.8,   y_arrow, PNG.next, next_name, "") | ||||||
| @@ -1124,8 +1193,8 @@ local function get_title_fs(query_item, lang_code, favs, fs, spacing) | |||||||
| 	local t_desc = query_item | 	local t_desc = query_item | ||||||
| 	t_desc = #t_desc > 40 and fmt("%s...", sub(t_desc, 1, 37)) or t_desc | 	t_desc = #t_desc > 40 and fmt("%s...", sub(t_desc, 1, 37)) or t_desc | ||||||
|  |  | ||||||
| 	fs[#fs + 1] = fmt("hypertext[9.05,%f;5.85,1.2;item_title;%s]", | 	fs[#fs + 1] = fmt(FMT.hypertext, | ||||||
| 		spacing - 0.1, | 		9.05, spacing - 0.1, 5.85, 1.2, | ||||||
| 		fmt("<item name=%s float=right width=64 height=64 rotate=yes>" .. | 		fmt("<item name=%s float=right width=64 height=64 rotate=yes>" .. | ||||||
| 		    "<big><b>%s</b></big>\n<style color=#7bf font=mono>%s</style>", | 		    "<big><b>%s</b></big>\n<style color=#7bf font=mono>%s</style>", | ||||||
| 			query_item, desc, t_desc)) | 			query_item, desc, t_desc)) | ||||||
| @@ -1160,11 +1229,11 @@ end | |||||||
| local function get_panels(lang_code, query_item, recipes, usages, show_usages, | local function get_panels(lang_code, query_item, recipes, usages, show_usages, | ||||||
| 			  favs, unum, rnum, fs) | 			  favs, unum, rnum, fs) | ||||||
|  |  | ||||||
| 	local _title    = {name = "title", height = 1.2} | 	local _title   = {name = "title", height = 1.2} | ||||||
| 	local _favs     = {name = "favs",  height = 1.91} | 	local _favs    = {name = "favs",  height = 1.91} | ||||||
| 	local _recipes  = {name = "recipes", rcp = recipes, height = 3.5} | 	local _recipes = {name = "recipes", rcp = recipes, height = 3.5} | ||||||
| 	local _usages   = {name = "usages",  rcp = usages,  height = 3.5} | 	local _usages  = {name = "usages",  rcp = usages,  height = 3.5} | ||||||
| 	local panels    = {_title, _recipes, _usages, _favs} | 	local panels   = {_title, _recipes, _usages, _favs} | ||||||
|  |  | ||||||
| 	if sfinv_only then | 	if sfinv_only then | ||||||
| 		panels = {show_usages and _usages or _recipes} | 		panels = {show_usages and _usages or _recipes} | ||||||
| @@ -1194,13 +1263,12 @@ local function get_panels(lang_code, query_item, recipes, usages, show_usages, | |||||||
| 			-0.2 + spacing, panel.height, PNG.bg_full, 10) | 			-0.2 + spacing, panel.height, PNG.bg_full, 10) | ||||||
|  |  | ||||||
| 		if recipe_or_usage and not rn then | 		if recipe_or_usage and not rn then | ||||||
| 			local X = XOFFSET - 0.7 | 			local lbl = is_recipe and ES"No recipes" or ES"No usages" | ||||||
| 			local Y = YOFFSET - 0.4 + spacing |  | ||||||
|  |  | ||||||
| 			fs[#fs + 1] = fmt(FMT.image, X, Y, 2, 2, PNG.nothing) | 			fs[#fs + 1] = fmt(FMT.hypertext, | ||||||
|  | 				8.29, YOFFSET + spacing + 0.3, 6.8, 1, | ||||||
| 			fs[#fs + 1] = fmt(FMT.tooltip, | 				fmt("<center><style size=20><b>%s</b></style></center>", | ||||||
| 				X, Y, 2, 2, is_recipe and ES"No recipes" or ES"No usages") | 					translate(lang_code, lbl))) | ||||||
|  |  | ||||||
| 		elseif panel.name == "title" then | 		elseif panel.name == "title" then | ||||||
| 			get_title_fs(query_item, lang_code, favs, fs, spacing) | 			get_title_fs(query_item, lang_code, favs, fs, spacing) | ||||||
| @@ -1240,29 +1308,15 @@ local function make_fs(data) | |||||||
| 			9 - 0.9, LINES + 0.4, PNG.bg_full, 10) | 			9 - 0.9, LINES + 0.4, PNG.bg_full, 10) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
|  | 	fs[#fs + 1] = styles | ||||||
|  |  | ||||||
| 	fs[#fs + 1] = fmt([[ | 	fs[#fs + 1] = fmt([[ | ||||||
| 		style[filter;border=false] |  | ||||||
| 		field[0.4,0.2;2.6,1;filter;;%s] | 		field[0.4,0.2;2.6,1;filter;;%s] | ||||||
| 		field_close_on_enter[filter;false] | 		field_close_on_enter[filter;false] | ||||||
| 		box[0,0;2.5,0.6;#bababa25] | 		box[0,0;2.5,0.6;#bababa25] | ||||||
| 	]], | 	]], | ||||||
| 	ESC(data.filter)) | 	ESC(data.filter)) | ||||||
|  |  | ||||||
| 	fs[#fs + 1] = fmt([[ |  | ||||||
| 		style_type[image_button;border=false] |  | ||||||
| 		style_type[item_image_button;border=false;bgimg_hovered=%s;bgimg_pressed=%s] |  | ||||||
| 		style[search;fgimg=%s;fgimg_hovered=%s] |  | ||||||
| 		style[clear;fgimg=%s;fgimg_hovered=%s] |  | ||||||
| 		style[prev_page;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] |  | ||||||
| 		style[next_page;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] |  | ||||||
| 		style[pagenum;border=false] |  | ||||||
| 	]], |  | ||||||
| 	PNG.selected, PNG.selected, |  | ||||||
| 	PNG.search, PNG.search_hover, |  | ||||||
| 	PNG.clear, PNG.clear_hover, |  | ||||||
| 	PNG.prev, PNG.prev_hover, PNG.prev_hover, |  | ||||||
| 	PNG.next, PNG.next_hover, PNG.next_hover) |  | ||||||
|  |  | ||||||
| 	fs[#fs + 1] = fmt(mul_elem(FMT.image_button, 2), | 	fs[#fs + 1] = fmt(mul_elem(FMT.image_button, 2), | ||||||
| 		2.6, -0.06, 0.85, 0.85, "", "search", "", | 		2.6, -0.06, 0.85, 0.85, "", "search", "", | ||||||
| 		3.3, -0.06, 0.85, 0.85, "", "clear", "") | 		3.3, -0.06, 0.85, 0.85, "", "clear", "") | ||||||
| @@ -1286,15 +1340,16 @@ local function make_fs(data) | |||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if #data.items == 0 then | 	if #data.items == 0 then | ||||||
| 		local no_item = ES"No item to show" | 		local lbl = ES"No item to show" | ||||||
| 		local pos = 3 |  | ||||||
|  |  | ||||||
| 		if next(recipe_filters) and #init_items > 0 and data.filter == "" then | 		if next(recipe_filters) and #init_items > 0 and data.filter == "" then | ||||||
| 			no_item = ES"Collect items to reveal more recipes" | 			lbl = ES"Collect items to reveal more recipes" | ||||||
| 			pos = pos - 1 |  | ||||||
| 		end | 		end | ||||||
|  |  | ||||||
| 		fs[#fs + 1] = fmt(FMT.label, pos, 2, no_item) | 		fs[#fs + 1] = fmt(FMT.hypertext, | ||||||
|  | 			0.05, 3, 8.29, 1, | ||||||
|  | 			fmt("<center><style size=20><b>%s</b></style></center>", | ||||||
|  | 				translate(data.lang_code, lbl))) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local first_item = (data.pagenum - 1) * IPP | 	local first_item = (data.pagenum - 1) * IPP | ||||||
| @@ -1306,7 +1361,7 @@ local function make_fs(data) | |||||||
| 		local X = i % ROWS | 		local X = i % ROWS | ||||||
| 		local Y = (i % IPP - X) / ROWS + 1 | 		local Y = (i % IPP - X) / ROWS + 1 | ||||||
| 		X = X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05 | 		X = X - (X * (sfinv_only and 0.12 or 0.14)) - 0.05 | ||||||
| 		Y = Y - (Y * 0.1) - 0.1 | 		Y = Y - (Y * 0.08) - 0.15 | ||||||
|  |  | ||||||
| 		if data.query_item == item then | 		if data.query_item == item then | ||||||
| 			fs[#fs + 1] = fmt(FMT.image, X, Y, 1, 1, PNG.selected) | 			fs[#fs + 1] = fmt(FMT.image, X, Y, 1, 1, PNG.selected) | ||||||
| @@ -1368,8 +1423,8 @@ local function search(data) | |||||||
|  |  | ||||||
| 	for i = 1, #data.items_raw do | 	for i = 1, #data.items_raw do | ||||||
| 		local item = data.items_raw[i] | 		local item = data.items_raw[i] | ||||||
| 		local def  = reg_items[item] | 		local def = reg_items[item] | ||||||
| 		local desc = (def and def.description) and lower(def.description) or "" | 		local desc = lower(translate(data.lang_code, def and def.description)) or "" | ||||||
| 		local search_in = fmt("%s %s", item, desc) | 		local search_in = fmt("%s %s", item, desc) | ||||||
| 		local to_add | 		local to_add | ||||||
|  |  | ||||||
| @@ -1419,13 +1474,12 @@ craftguide.add_search_filter("groups", function(item, groups) | |||||||
| end) | end) | ||||||
|  |  | ||||||
| --[[	As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not | --[[	As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not | ||||||
| 	return the replacements and toolrepair, we have to override | 	return the fuel, replacements and toolrepair recipes, we have to | ||||||
| 	`core.register_craft` and do some reverse engineering. | 	override `core.register_craft` and do some reverse engineering. | ||||||
| 	See engine's issues #4901 and #8920.	]] | 	See engine's issues #4901, #5745 and #8920.	]] | ||||||
|  |  | ||||||
| fuel_cache.replacements = {} |  | ||||||
|  |  | ||||||
| local old_register_craft = core.register_craft | local old_register_craft = core.register_craft | ||||||
|  | local rcp_num = {} | ||||||
|  |  | ||||||
| core.register_craft = function(def) | core.register_craft = function(def) | ||||||
| 	old_register_craft(def) | 	old_register_craft(def) | ||||||
| @@ -1446,48 +1500,16 @@ core.register_craft = function(def) | |||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	for i = 1, #output do | 	for i = 1, #output do | ||||||
| 		local name = output[i] | 		local item = output[i] | ||||||
|  | 		rcp_num[item] = (rcp_num[item] or 0) + 1 | ||||||
|  |  | ||||||
| 		if def.type ~= "fuel" then | 		if def.replacements then | ||||||
| 			def.items = {} | 			if def.type == "fuel" then | ||||||
| 		end | 				replacements.fuel[item] = def.replacements | ||||||
|  | 			else | ||||||
| 		if def.type == "fuel" then | 				replacements[item] = replacements[item] or {} | ||||||
| 			fuel_cache[name] = def.burntime | 				replacements[item][rcp_num[item]] = def.replacements | ||||||
| 			fuel_cache.replacements[name] = def.replacements |  | ||||||
|  |  | ||||||
| 		elseif def.type == "cooking" then |  | ||||||
| 			def.width = def.cooktime |  | ||||||
| 			def.cooktime = nil |  | ||||||
| 			def.items[1] = def.recipe |  | ||||||
|  |  | ||||||
| 		elseif def.type == "shapeless" then |  | ||||||
| 			def.width = 0 |  | ||||||
| 			for j = 1, #def.recipe do |  | ||||||
| 				def.items[#def.items + 1] = def.recipe[j] |  | ||||||
| 			end | 			end | ||||||
| 		else |  | ||||||
| 			def.width = #def.recipe[1] |  | ||||||
| 			local c = 0 |  | ||||||
|  |  | ||||||
| 			for j = 1, #def.recipe do |  | ||||||
| 				if def.recipe[j] then |  | ||||||
| 					for h = 1, def.width do |  | ||||||
| 						c = c + 1 |  | ||||||
| 						local it = def.recipe[j][h] |  | ||||||
|  |  | ||||||
| 						if it and it ~= "" then |  | ||||||
| 							def.items[c] = it |  | ||||||
| 						end |  | ||||||
| 					end |  | ||||||
| 				end |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		if def.type ~= "fuel" then |  | ||||||
| 			def.recipe = nil |  | ||||||
| 			recipes_cache[name] = recipes_cache[name] or {} |  | ||||||
| 			insert(recipes_cache[name], 1, def) |  | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
| @@ -1498,10 +1520,7 @@ core.clear_craft = function(def) | |||||||
| 	old_clear_craft(def) | 	old_clear_craft(def) | ||||||
|  |  | ||||||
| 	if true_str(def) then | 	if true_str(def) then | ||||||
| 		def = match(def, "%S*") | 		return -- TODO | ||||||
| 		recipes_cache[def] = nil |  | ||||||
| 		fuel_cache[def] = nil |  | ||||||
|  |  | ||||||
| 	elseif is_table(def) then | 	elseif is_table(def) then | ||||||
| 		return -- TODO | 		return -- TODO | ||||||
| 	end | 	end | ||||||
| @@ -1550,9 +1569,15 @@ local function get_init_items() | |||||||
|  |  | ||||||
| 	for name, def in pairs(reg_items) do | 	for name, def in pairs(reg_items) do | ||||||
| 		if name ~= "" and show_item(def) then | 		if name ~= "" and show_item(def) then | ||||||
| 			cache_recipes(name) |  | ||||||
| 			cache_drops(name, def.drop) | 			cache_drops(name, def.drop) | ||||||
| 			cache_fuel(name) |  | ||||||
|  | 			if not fuel_cache[name] then | ||||||
|  | 				cache_fuel(name) | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			if not recipes_cache[name] then | ||||||
|  | 				cache_recipes(name) | ||||||
|  | 			end | ||||||
|  |  | ||||||
| 			_preselect[name] = true | 			_preselect[name] = true | ||||||
| 		end | 		end | ||||||
| @@ -1576,7 +1601,6 @@ local function get_init_items() | |||||||
| 		local post_data = { | 		local post_data = { | ||||||
| 			recipes = recipes_cache, | 			recipes = recipes_cache, | ||||||
| 			usages  = usages_cache, | 			usages  = usages_cache, | ||||||
| 			fuel    = fuel_cache, |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		http.fetch_async{ | 		http.fetch_async{ | ||||||
| @@ -1621,9 +1645,14 @@ on_joinplayer(function(player) | |||||||
| end) | end) | ||||||
|  |  | ||||||
| local function fields(player, _f) | local function fields(player, _f) | ||||||
|  | 	if _f.quit then return end | ||||||
| 	local name = player:get_player_name() | 	local name = player:get_player_name() | ||||||
| 	local data = pdata[name] | 	local data = pdata[name] | ||||||
|  |  | ||||||
|  | 	if not _f.key_enter_field then | ||||||
|  | 		sound_play("craftguide_click", {to_player = name, gain = 0.2}) | ||||||
|  | 	end | ||||||
|  |  | ||||||
| 	if _f.clear then | 	if _f.clear then | ||||||
| 		reset_data(data) | 		reset_data(data) | ||||||
|  |  | ||||||
| @@ -1682,6 +1711,8 @@ local function fields(player, _f) | |||||||
| 			item = sub(item, 1, -5) | 			item = sub(item, 1, -5) | ||||||
| 		elseif sub(item, 1, 1) == "_" then | 		elseif sub(item, 1, 1) == "_" then | ||||||
| 			item = sub(item, 2) | 			item = sub(item, 2) | ||||||
|  | 		elseif sub(item, 1, 6) == "group|" then | ||||||
|  | 			item = match(item, "([%w:_]+)$") | ||||||
| 		end | 		end | ||||||
|  |  | ||||||
| 		item = reg_aliases[item] or item | 		item = reg_aliases[item] or item | ||||||
| @@ -2007,8 +2038,8 @@ if progressive_mode then | |||||||
| 		local players = get_players() | 		local players = get_players() | ||||||
| 		for i = 1, #players do | 		for i = 1, #players do | ||||||
| 			local player = players[i] | 			local player = players[i] | ||||||
| 			local name   = player:get_player_name() | 			local name = player:get_player_name() | ||||||
| 			local data   = pdata[name] | 			local data = pdata[name] | ||||||
|  |  | ||||||
| 			local inv_items = get_inv_items(player) | 			local inv_items = get_inv_items(player) | ||||||
| 			local diff = array_diff(inv_items, data.inv_items) | 			local diff = array_diff(inv_items, data.inv_items) | ||||||
| @@ -2042,8 +2073,8 @@ if progressive_mode then | |||||||
| 		local players = get_players() | 		local players = get_players() | ||||||
| 		for i = 1, #players do | 		for i = 1, #players do | ||||||
| 			local player = players[i] | 			local player = players[i] | ||||||
| 			local name   = player:get_player_name() | 			local name = player:get_player_name() | ||||||
| 			local data   = pdata[name] | 			local data = pdata[name] | ||||||
|  |  | ||||||
| 			if data.show_hud ~= nil and singleplayer then | 			if data.show_hud ~= nil and singleplayer then | ||||||
| 				show_hud_success(player, data) | 				show_hud_success(player, data) | ||||||
| @@ -2096,7 +2127,7 @@ on_leaveplayer(function(player) | |||||||
| end) | end) | ||||||
|  |  | ||||||
| function craftguide.show(name, item, show_usages) | function craftguide.show(name, item, show_usages) | ||||||
| 	if not true_str(name)then | 	if not true_str(name) then | ||||||
| 		return err "craftguide.show(): player name missing" | 		return err "craftguide.show(): player name missing" | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ Craft Guide=Guide de recettes | |||||||
| Crafting Guide=Guide de recettes | Crafting Guide=Guide de recettes | ||||||
| Crafting Guide Sign=Guide de recettes | Crafting Guide Sign=Guide de recettes | ||||||
| Bookmarks=Favoris | Bookmarks=Favoris | ||||||
| Usage @1 of @2=Usage @1 de @2 | Usage @1 of @2=Usage @1 sur @2 | ||||||
| Recipe @1 of @2=Recette @1 de @2 | Recipe @1 of @2=Recette @1 sur @2 | ||||||
| No recipes=Pas de recettes | No recipes=Pas de recettes | ||||||
| No usages=Pas d'usages | No usages=Pas d'usages | ||||||
| Burning time: @1=Temps de combustion : @1 | Burning time: @1=Temps de combustion : @1 | ||||||
| @@ -53,7 +53,7 @@ No item to show=Aucun item à afficher | |||||||
| Collect items to reveal more recipes=Collecte des items pour révéler plus de recettes | Collect items to reveal more recipes=Collecte des items pour révéler plus de recettes | ||||||
| Show recipe(s) of the pointed node=Affiche les recettes du bloc visé | Show recipe(s) of the pointed node=Affiche les recettes du bloc visé | ||||||
| No node pointed=Aucun bloc visé | No node pointed=Aucun bloc visé | ||||||
| You don't know a recipe or usage for this item=Tu ne connais aucune recette pour ce bloc | You don't know a recipe or usage for this item=Vous ne connaissez aucune recette pour ce bloc | ||||||
| No recipe or usage for this item=Aucune recette pour ce bloc | No recipe or usage for this item=Aucune recette pour ce bloc | ||||||
| Digging=Destruction | Digging=Destruction | ||||||
| Digging (by chance)=Destruction (par chance) | Digging (by chance)=Destruction (par chance) | ||||||
| @@ -61,5 +61,5 @@ Digging (by chance)=Destruction (par chance) | |||||||
| Mark this item=Mettre en favori. | Mark this item=Mettre en favori. | ||||||
| Unmark this item=Enlever des favoris. | Unmark this item=Enlever des favoris. | ||||||
| Cannot mark this item. Limit of bookmarks reached.=Impossible de mettre cet item en favori. Limite des favoris atteinte. | Cannot mark this item. Limit of bookmarks reached.=Impossible de mettre cet item en favori. Limite des favoris atteinte. | ||||||
| Only drop if using one of these tools: @1=Tombe seulement si détruit avec un de ces outils: @1 | Only drop if using one of these tools: @1=Tombe seulement si détruit avec un de ces outils : @1 | ||||||
| Only drop if using this tool: @1=Tombe seulement si détruit avec cet outil: @1 | Only drop if using this tool: @1=Tombe seulement si détruit avec cet outil : @1 | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ Any dark grey dye= | |||||||
| Any green dye= | Any green dye= | ||||||
| Any green flower= | Any green flower= | ||||||
| Any grey dye= | Any grey dye= | ||||||
| Any kind of stone block= | Any stone= | ||||||
| Any magenta dye= | Any magenta dye= | ||||||
| Any orange dye= | Any orange dye= | ||||||
| Any orange flower= | Any orange flower= | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								sounds/craftguide_click.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 3.2 KiB | 
| Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 1.3 KiB | 
| Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.2 KiB | 
| Before Width: | Height: | Size: 708 B After Width: | Height: | Size: 4.1 KiB | 
| Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 5.0 KiB | 
| Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 5.4 KiB | 
| Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 7.3 KiB | 
| Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.1 KiB | 
| Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.4 KiB | 
| Before Width: | Height: | Size: 727 B After Width: | Height: | Size: 2.7 KiB | 
| Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.3 KiB | 
| Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.6 KiB | 
| Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.1 KiB | 
| Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.5 KiB | 
| Before Width: | Height: | Size: 912 B After Width: | Height: | Size: 1.3 KiB | 
| Before Width: | Height: | Size: 305 B After Width: | Height: | Size: 3.9 KiB | 
| Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.0 KiB | 
| Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.3 KiB |