Split init.lua into separate files (Part I)
This commit is contained in:
parent
f8ac9c45d1
commit
853ddc9d94
8
API.md
8
API.md
|
@ -186,9 +186,9 @@ Removes all recipe filters and adds a new one.
|
||||||
|
|
||||||
Removes the recipe filter with the given `name`.
|
Removes the recipe filter with the given `name`.
|
||||||
|
|
||||||
#### `i3.get_recipe_filters()`
|
#### `i3.recipe_filters`
|
||||||
|
|
||||||
Returns a map of recipe filters, indexed by name.
|
A map of recipe filters, indexed by name.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -233,9 +233,9 @@ end)
|
||||||
|
|
||||||
Removes the search filter with the given `name`.
|
Removes the search filter with the given `name`.
|
||||||
|
|
||||||
#### `i3.get_search_filters()`
|
#### `i3.search_filters`
|
||||||
|
|
||||||
Returns a map of search filters, indexed by name.
|
A map of search filters, indexed by name.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,211 @@
|
||||||
|
local modpath = core.get_modpath "i3"
|
||||||
|
local item_compression = core.settings:get_bool("i3_item_compression", true)
|
||||||
|
local reg_items, translate = core.registered_items, core.get_translated_string
|
||||||
|
|
||||||
|
local fmt, find, gmatch, match, sub, split, lower =
|
||||||
|
string.format, string.find, string.gmatch, string.match,
|
||||||
|
string.sub, string.split, string.lower
|
||||||
|
|
||||||
|
local function reset_compression(data)
|
||||||
|
data.alt_items = nil
|
||||||
|
data.expand = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function search(data)
|
||||||
|
reset_compression(data)
|
||||||
|
|
||||||
|
local filter = data.filter
|
||||||
|
local opt = "^(.-)%+([%w_]+)=([%w_,]+)"
|
||||||
|
local search_filter = next(i3.search_filters) and match(filter, opt)
|
||||||
|
local filters = {}
|
||||||
|
|
||||||
|
if search_filter then
|
||||||
|
search_filter = search_filter:trim()
|
||||||
|
|
||||||
|
for filter_name, values in gmatch(filter, sub(opt, 6)) do
|
||||||
|
if i3.search_filters[filter_name] then
|
||||||
|
values = split(values, ",")
|
||||||
|
filters[filter_name] = values
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local filtered_list, c = {}, 0
|
||||||
|
|
||||||
|
for i = 1, #data.items_raw do
|
||||||
|
local item = data.items_raw[i]
|
||||||
|
local def = core.registered_items[item]
|
||||||
|
local desc = lower(translate(data.lang_code, def and def.description)) or ""
|
||||||
|
local search_in = fmt("%s %s", item, desc)
|
||||||
|
local temp, j, to_add = {}, 1
|
||||||
|
|
||||||
|
if search_filter then
|
||||||
|
for filter_name, values in pairs(filters) do
|
||||||
|
if values then
|
||||||
|
local func = i3.search_filters[filter_name]
|
||||||
|
to_add = (j > 1 and temp[item] or j == 1) and
|
||||||
|
func(item, values) and (search_filter == "" or
|
||||||
|
find(search_in, search_filter, 1, true))
|
||||||
|
|
||||||
|
if to_add then
|
||||||
|
temp[item] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
j = j + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local ok = true
|
||||||
|
|
||||||
|
for keyword in gmatch(filter, "%S+") do
|
||||||
|
if not find(search_in, keyword, 1, true) then
|
||||||
|
ok = nil
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
to_add = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if to_add then
|
||||||
|
c = c + 1
|
||||||
|
filtered_list[c] = item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
data.items = filtered_list
|
||||||
|
end
|
||||||
|
|
||||||
|
local function table_merge(t1, t2, hash)
|
||||||
|
t1 = t1 or {}
|
||||||
|
t2 = t2 or {}
|
||||||
|
|
||||||
|
if hash then
|
||||||
|
for k, v in pairs(t2) do
|
||||||
|
t1[k] = v
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local c = #t1
|
||||||
|
|
||||||
|
for i = 1, #t2 do
|
||||||
|
c = c + 1
|
||||||
|
t1[c] = t2[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return t1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_group(item)
|
||||||
|
return sub(item, 1, 6) == "group:"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function extract_groups(str)
|
||||||
|
if sub(str, 1, 6) == "group:" then
|
||||||
|
return split(sub(str, 7), ",")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function item_has_groups(item_groups, groups)
|
||||||
|
for i = 1, #groups do
|
||||||
|
local group = groups[i]
|
||||||
|
if (item_groups[group] or 0) == 0 then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function show_item(def)
|
||||||
|
return def and def.groups.not_in_creative_inventory ~= 1 and
|
||||||
|
def.description and def.description ~= ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function groups_to_items(groups, get_all)
|
||||||
|
if not get_all and #groups == 1 then
|
||||||
|
local group = groups[1]
|
||||||
|
local stereotype = i3.group_stereotypes[group]
|
||||||
|
local def = reg_items[stereotype]
|
||||||
|
|
||||||
|
if show_item(def) then
|
||||||
|
return stereotype
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local names = {}
|
||||||
|
|
||||||
|
for name, def in pairs(reg_items) do
|
||||||
|
if show_item(def) and item_has_groups(def.groups, groups) then
|
||||||
|
if get_all then
|
||||||
|
names[#names + 1] = name
|
||||||
|
else
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return get_all and names or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function apply_recipe_filters(recipes, player)
|
||||||
|
for _, filter in pairs(i3.recipe_filters) do
|
||||||
|
recipes = filter(recipes, player)
|
||||||
|
end
|
||||||
|
|
||||||
|
return recipes
|
||||||
|
end
|
||||||
|
|
||||||
|
local function compression_active(data)
|
||||||
|
return item_compression and not next(i3.recipe_filters) and data.filter == ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function compressible(item, data)
|
||||||
|
return compression_active(data) and i3.compress_groups[item]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_str(x)
|
||||||
|
return type(x) == "string"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function true_str(str)
|
||||||
|
return is_str(str) and str ~= ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_fav(favs, query_item)
|
||||||
|
local fav, i
|
||||||
|
for j = 1, #favs do
|
||||||
|
if favs[j] == query_item then
|
||||||
|
fav = true
|
||||||
|
i = j
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return fav, i
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
init = {
|
||||||
|
is_str,
|
||||||
|
show_item,
|
||||||
|
reset_compression,
|
||||||
|
},
|
||||||
|
|
||||||
|
progressive = {
|
||||||
|
search,
|
||||||
|
table_merge,
|
||||||
|
is_group,
|
||||||
|
extract_groups,
|
||||||
|
item_has_groups,
|
||||||
|
apply_recipe_filters,
|
||||||
|
},
|
||||||
|
|
||||||
|
gui = {
|
||||||
|
groups_to_items,
|
||||||
|
compression_active,
|
||||||
|
compressible,
|
||||||
|
true_str,
|
||||||
|
is_fav,
|
||||||
|
},
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,301 @@
|
||||||
|
local POLL_FREQ = 0.25
|
||||||
|
local HUD_TIMER_MAX = 1.5
|
||||||
|
|
||||||
|
local set_fs = i3.set_fs
|
||||||
|
local modpath = core.get_modpath "i3"
|
||||||
|
local search, table_merge, is_group, extract_groups, item_has_groups, apply_recipe_filters =
|
||||||
|
unpack(dofile(modpath .. "/etc/common.lua").progressive)
|
||||||
|
|
||||||
|
local singleplayer = core.is_singleplayer()
|
||||||
|
local fmt, after = string.format, core.after
|
||||||
|
|
||||||
|
local function array_diff(t1, t2)
|
||||||
|
local hash = {}
|
||||||
|
|
||||||
|
for i = 1, #t1 do
|
||||||
|
local v = t1[i]
|
||||||
|
hash[v] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, #t2 do
|
||||||
|
local v = t2[i]
|
||||||
|
hash[v] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local diff, c = {}, 0
|
||||||
|
|
||||||
|
for i = 1, #t1 do
|
||||||
|
local v = t1[i]
|
||||||
|
if hash[v] then
|
||||||
|
c = c + 1
|
||||||
|
diff[c] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return diff
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_filtered_items(player, data)
|
||||||
|
local items, known, c = {}, 0, 0
|
||||||
|
|
||||||
|
for i = 1, #i3.init_items do
|
||||||
|
local item = i3.init_items[i]
|
||||||
|
local recipes = i3.recipes_cache[item]
|
||||||
|
local usages = i3.usages_cache[item]
|
||||||
|
|
||||||
|
recipes = #apply_recipe_filters(recipes or {}, player)
|
||||||
|
usages = #apply_recipe_filters(usages or {}, player)
|
||||||
|
|
||||||
|
if recipes > 0 or usages > 0 then
|
||||||
|
c = c + 1
|
||||||
|
items[c] = item
|
||||||
|
|
||||||
|
if data then
|
||||||
|
known = known + recipes + usages
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if data then
|
||||||
|
data.known_recipes = known
|
||||||
|
end
|
||||||
|
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
|
local function item_in_inv(item, inv_items)
|
||||||
|
local inv_items_size = #inv_items
|
||||||
|
|
||||||
|
if is_group(item) then
|
||||||
|
local groups = extract_groups(item)
|
||||||
|
|
||||||
|
for i = 1, inv_items_size do
|
||||||
|
local def = core.registered_items[inv_items[i]]
|
||||||
|
|
||||||
|
if def then
|
||||||
|
if item_has_groups(def.groups, groups) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for i = 1, inv_items_size do
|
||||||
|
if inv_items[i] == item then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function recipe_in_inv(rcp, inv_items)
|
||||||
|
for _, item in pairs(rcp.items) do
|
||||||
|
if not item_in_inv(item, inv_items) then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function progressive_filter(recipes, player)
|
||||||
|
if not recipes then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local data = i3.data[name]
|
||||||
|
|
||||||
|
if #data.inv_items == 0 then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local filtered, c = {}, 0
|
||||||
|
|
||||||
|
for i = 1, #recipes do
|
||||||
|
local recipe = recipes[i]
|
||||||
|
if recipe_in_inv(recipe, data.inv_items) then
|
||||||
|
c = c + 1
|
||||||
|
filtered[c] = recipe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return filtered
|
||||||
|
end
|
||||||
|
|
||||||
|
local item_lists = {"main", "craft", "craftpreview"}
|
||||||
|
|
||||||
|
local function get_inv_items(player)
|
||||||
|
local inv = player:get_inventory()
|
||||||
|
local stacks = {}
|
||||||
|
|
||||||
|
for i = 1, #item_lists do
|
||||||
|
local list = inv:get_list(item_lists[i])
|
||||||
|
table_merge(stacks, list)
|
||||||
|
end
|
||||||
|
|
||||||
|
local inv_items, c = {}, 0
|
||||||
|
|
||||||
|
for i = 1, #stacks do
|
||||||
|
local stack = stacks[i]
|
||||||
|
|
||||||
|
if not stack:is_empty() then
|
||||||
|
local name = stack:get_name()
|
||||||
|
if core.registered_items[name] then
|
||||||
|
c = c + 1
|
||||||
|
inv_items[c] = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return inv_items
|
||||||
|
end
|
||||||
|
|
||||||
|
local function init_hud(player, data)
|
||||||
|
data.hud = {
|
||||||
|
bg = player:hud_add {
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.78, y = 1},
|
||||||
|
alignment = {x = 1, y = 1},
|
||||||
|
scale = {x = 370, y = 112},
|
||||||
|
text = "i3_bg.png",
|
||||||
|
z_index = 0xDEAD,
|
||||||
|
},
|
||||||
|
|
||||||
|
book = player:hud_add {
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.79, y = 1.02},
|
||||||
|
alignment = {x = 1, y = 1},
|
||||||
|
scale = {x = 4, y = 4},
|
||||||
|
text = "i3_book.png",
|
||||||
|
z_index = 0xDEAD,
|
||||||
|
},
|
||||||
|
|
||||||
|
text = player:hud_add {
|
||||||
|
hud_elem_type = "text",
|
||||||
|
position = {x = 0.84, y = 1.04},
|
||||||
|
alignment = {x = 1, y = 1},
|
||||||
|
number = 0xffffff,
|
||||||
|
text = "",
|
||||||
|
z_index = 0xDEAD,
|
||||||
|
style = 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function show_hud_success(player, data)
|
||||||
|
-- It'd better to have an engine function `hud_move` to only need
|
||||||
|
-- 2 calls for the notification's back and forth.
|
||||||
|
|
||||||
|
local hud_info_bg = player:hud_get(data.hud.bg)
|
||||||
|
local dt = 0.016
|
||||||
|
|
||||||
|
if hud_info_bg.position.y <= 0.9 then
|
||||||
|
data.show_hud = false
|
||||||
|
data.hud_timer = (data.hud_timer or 0) + dt
|
||||||
|
end
|
||||||
|
|
||||||
|
if data.show_hud then
|
||||||
|
for _, def in pairs(data.hud) do
|
||||||
|
local hud_info = player:hud_get(def)
|
||||||
|
|
||||||
|
player:hud_change(def, "position", {
|
||||||
|
x = hud_info.position.x,
|
||||||
|
y = hud_info.position.y - (dt / 5)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
player:hud_change(data.hud.text, "text",
|
||||||
|
fmt("%u new recipe%s unlocked!",
|
||||||
|
data.discovered, data.discovered > 1 and "s" or ""))
|
||||||
|
|
||||||
|
elseif data.show_hud == false then
|
||||||
|
if data.hud_timer >= HUD_TIMER_MAX then
|
||||||
|
for _, def in pairs(data.hud) do
|
||||||
|
local hud_info = player:hud_get(def)
|
||||||
|
|
||||||
|
player:hud_change(def, "position", {
|
||||||
|
x = hud_info.position.x,
|
||||||
|
y = hud_info.position.y + (dt / 5)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if hud_info_bg.position.y >= 1 then
|
||||||
|
data.show_hud = nil
|
||||||
|
data.hud_timer = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Workaround. Need an engine call to detect when the contents of
|
||||||
|
-- the player inventory changed, instead.
|
||||||
|
local function poll_new_items()
|
||||||
|
local players = core.get_connected_players()
|
||||||
|
|
||||||
|
for i = 1, #players do
|
||||||
|
local player = players[i]
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local data = i3.data[name]
|
||||||
|
if not data then return end
|
||||||
|
|
||||||
|
local inv_items = get_inv_items(player)
|
||||||
|
local diff = array_diff(inv_items, data.inv_items)
|
||||||
|
|
||||||
|
if #diff > 0 then
|
||||||
|
data.inv_items = table_merge(diff, data.inv_items)
|
||||||
|
local oldknown = data.known_recipes or 0
|
||||||
|
local items = get_filtered_items(player, data)
|
||||||
|
data.discovered = data.known_recipes - oldknown
|
||||||
|
|
||||||
|
if data.show_hud == nil and data.discovered > 0 then
|
||||||
|
data.show_hud = true
|
||||||
|
end
|
||||||
|
|
||||||
|
data.items_raw = items
|
||||||
|
data.current_itab = 1
|
||||||
|
|
||||||
|
search(data)
|
||||||
|
set_fs(player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
after(POLL_FREQ, poll_new_items)
|
||||||
|
end
|
||||||
|
|
||||||
|
poll_new_items()
|
||||||
|
|
||||||
|
if singleplayer then
|
||||||
|
core.register_globalstep(function()
|
||||||
|
local name = "singleplayer"
|
||||||
|
local player = core.get_player_by_name(name)
|
||||||
|
local data = i3.data[name]
|
||||||
|
|
||||||
|
if data and data.show_hud ~= nil then
|
||||||
|
show_hud_success(player, data)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
i3.add_recipe_filter("Default progressive filter", progressive_filter)
|
||||||
|
|
||||||
|
core.register_on_joinplayer(function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local data = i3.data[name]
|
||||||
|
if not data then return end
|
||||||
|
|
||||||
|
data.inv_items = data.inv_items or {}
|
||||||
|
data.known_recipes = data.known_recipes or 0
|
||||||
|
|
||||||
|
local oldknown = data.known_recipes
|
||||||
|
local items = get_filtered_items(player, data)
|
||||||
|
data.discovered = data.known_recipes - oldknown
|
||||||
|
|
||||||
|
data.items_raw = items
|
||||||
|
search(data)
|
||||||
|
|
||||||
|
if singleplayer then
|
||||||
|
init_hud(player, data)
|
||||||
|
|
||||||
|
if data.show_hud == nil and data.discovered > 0 then
|
||||||
|
data.show_hud = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
Ŝarĝante…
Reference in New Issue