146 lines
5.0 KiB
Lua
146 lines
5.0 KiB
Lua
local dictionary = require("__flib__/dictionary-lite")
|
|
|
|
local constants = require("__QuickItemSearch__/constants")
|
|
|
|
local search = {}
|
|
|
|
function search.run(player, player_table, query, combined_contents)
|
|
-- don't bother if they don't have a main inventory
|
|
local main_inventory = player.get_main_inventory()
|
|
if main_inventory and main_inventory.valid then
|
|
local requests = player_table.logistic_requests
|
|
local requests_by_name = requests.by_name
|
|
local filters = player_table.infinity_filters
|
|
local filters_by_name = filters.by_name
|
|
local settings = player_table.settings
|
|
local translations = dictionary.get(player.index, "item")
|
|
|
|
local item_prototypes = game.item_prototypes
|
|
local character = player.character
|
|
|
|
-- settings
|
|
local show_hidden = settings.show_hidden
|
|
|
|
local connected_to_network = false
|
|
local logistic_requests_available = false
|
|
local results = {}
|
|
|
|
-- get contents of all player inventories and cursor stack
|
|
-- in some cases, this is passed in externally to save performance
|
|
combined_contents = combined_contents or search.get_combined_inventory_contents(player, main_inventory)
|
|
-- don't bother doing anything if they don't have an inventory
|
|
local contents = {
|
|
inbound = {},
|
|
inventory = combined_contents,
|
|
logistic = {},
|
|
outbound = {},
|
|
}
|
|
|
|
local controller_type = player.controller_type
|
|
|
|
-- get logistic network and related contents
|
|
if character and character.valid then
|
|
logistic_requests_available = player.force.character_logistic_requests
|
|
for _, data in ipairs(constants.logistic_point_data) do
|
|
local point = character.get_logistic_point(data.logistic_point)
|
|
if point and point.valid then
|
|
contents[data.deliveries_table] = point[data.source_table]
|
|
if data.point_name == "requester" then
|
|
local logistic_network = point.logistic_network
|
|
if logistic_network.valid then
|
|
connected_to_network = true
|
|
contents.logistic = logistic_network.get_contents()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- perform search
|
|
local i = 0
|
|
for name, translation in pairs(translations) do
|
|
if string.find(string.lower(translation), query) then
|
|
local hidden = item_prototypes[name].has_flag("hidden")
|
|
if show_hidden or not hidden then
|
|
local inventory_count = contents.inventory[name]
|
|
local logistic_count = contents.logistic[name]
|
|
|
|
local result = {
|
|
hidden = hidden,
|
|
inventory = inventory_count,
|
|
logistic = logistic_count and math.max(logistic_count, 0) or nil,
|
|
name = name,
|
|
translation = translation,
|
|
}
|
|
|
|
if controller_type == defines.controllers.character then
|
|
-- add logistic request, if one exists
|
|
local request = requests_by_name[name]
|
|
if request then
|
|
result.request = { min = request.min, max = request.max }
|
|
if requests.temporary[name] then
|
|
result.request.is_temporary = true
|
|
end
|
|
end
|
|
-- determine logistic request color
|
|
local color
|
|
if contents.inbound[name] then
|
|
color = "inbound"
|
|
elseif contents.outbound[name] then
|
|
color = "outbound"
|
|
elseif request and (inventory_count or 0) < request.min then
|
|
color = "unsatisfied"
|
|
else
|
|
color = "normal"
|
|
end
|
|
result.request_color = color
|
|
elseif controller_type == defines.controllers.editor then
|
|
-- add infinity filter, if one exists
|
|
local filter = filters_by_name[name]
|
|
if filter then
|
|
result.infinity_filter = { mode = filter.mode, count = filter.count }
|
|
end
|
|
end
|
|
|
|
i = i + 1
|
|
results[i] = result
|
|
end
|
|
end
|
|
if i > constants.results_limit then
|
|
break
|
|
end
|
|
end
|
|
|
|
return results, connected_to_network, logistic_requests_available
|
|
end
|
|
return {}, false, false
|
|
end
|
|
|
|
function search.get_combined_inventory_contents(player, main_inventory)
|
|
-- main inventory contents
|
|
local combined_contents = main_inventory.get_contents()
|
|
-- cursor stack
|
|
local cursor_stack = player.cursor_stack
|
|
if cursor_stack and cursor_stack.valid_for_read then
|
|
combined_contents[cursor_stack.name] = (combined_contents[cursor_stack.name] or 0) + cursor_stack.count
|
|
end
|
|
-- other
|
|
for _, inventory_def in ipairs({
|
|
-- for some reason, the character_ammo and character_guns inventories work in the editor as well
|
|
defines.inventory.character_ammo,
|
|
defines.inventory.character_guns,
|
|
-- defines.inventory.character_trash
|
|
}) do
|
|
local inventory = player.get_inventory(inventory_def)
|
|
if inventory and inventory.valid then
|
|
for name, count in pairs(inventory.get_contents() or {}) do
|
|
combined_contents[name] = (combined_contents[name] or 0) + count
|
|
end
|
|
end
|
|
end
|
|
|
|
return combined_contents, true
|
|
end
|
|
|
|
return search
|