-
Notifications
You must be signed in to change notification settings - Fork 1
/
reveal.lua
144 lines (123 loc) · 3.46 KB
/
reveal.lua
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
local revealed_cache = {}
local function item_has_groups(item_groups, groups)
for i = 1, #groups do
local group = groups[i]
if not item_groups[group] then
return
end
end
return true
end
local function revealed_show_recipe(recipe, playername)
if not revealed_cache[playername] then
revealed_cache[playername] = {}
end
if revealed_cache[playername][recipe] then
return true
end
local reg_items = minetest.registered_items
local revealed = doc.data.players[playername].stored_data.revealed
for _, item in pairs(recipe.items) do
local is_revealed_item = false
if item:sub(1,6) == "group:" then
local groups = item:sub(7):split(",")
for cid, items in pairs(revealed) do
for revealed_item in pairs(items) do
if reg_items[revealed_item] and item_has_groups(reg_items[revealed_item].groups, groups) then
is_revealed_item = true
break
end
end
if is_revealed_item then
break
end
end
else
for cid, items in pairs(revealed) do
if items[item] then
is_revealed_item = true
break
end
end
end
if not is_revealed_item then
return false
end
end
revealed_cache[playername][recipe] = true
return true
end
local orig_get_usages = sfcg.get_usages
function sfcg.get_usages(data, item)
local recipes = orig_get_usages(data, item)
if not recipes then
return
end
local filtered = {}
for _, recipe in ipairs(recipes) do
if revealed_show_recipe(recipe, data.playername) then
table.insert(filtered, recipe)
end
end
if #filtered > 0 then
return filtered
end
end
local orig_get_recipes = sfcg.get_recipes
function sfcg.get_recipes(data, item)
local recipes = orig_get_recipes(data, item)
if not recipes then
return
end
local filtered = {}
for _, recipe in ipairs(recipes) do
if revealed_show_recipe(recipe, data.playername) then
table.insert(filtered, recipe)
end
end
if #filtered > 0 then
return filtered
end
end
local orig_execute_search = sfcg.execute_search
function sfcg.execute_search(data)
-- Only needed if doc is an optional dependency
--
-- if not doc.data.players[data.playername] then
-- -- Hack. craftguide is loaded before doc mod. Therefore doc is not initialized yet
-- data.items = {}
-- minetest.after(0, sfcg.execute_search, data)
-- return
-- end
orig_execute_search(data)
local filtered_items = {}
for _, item in ipairs(data.items) do
if sfcg.get_usages(data, item) or
sfcg.get_recipes(data, item) then
table.insert(filtered_items, item)
end
end
data.items = filtered_items
end
-- Update sfinv inventory once in globalstep, if something revealed
local async_update_users = {}
local function async_update()
for playername, _ in pairs(async_update_users) do
sfcg.update_for_player(playername)
async_update_users[playername] = nil
end
end
local orig_mark_entry_as_revealed = doc.mark_entry_as_revealed
function doc.mark_entry_as_revealed(playername, category_id, entry_id)
-- Temp Fix: `doc.entry_revealed()` crashes on some items like farming:* because they're given the wrong category_id
-- if not doc.entry_revealed(playername, category_id, entry_id) then
orig_mark_entry_as_revealed(playername, category_id, entry_id)
if not next(async_update_users) then
minetest.after(0, async_update)
async_update_users[playername] = true
end
-- end
end
minetest.register_on_leaveplayer(function(player)
revealed_cache[player:get_player_name()] = nil
end)