Files
project-cybersyn/cybersyn/scripts/gui/inventory.lua
2024-10-22 10:51:51 -04:00

273 lines
7.8 KiB
Lua

local gui = require("__flib__.gui")
local util = require("scripts.gui.util")
local templates = require("scripts.gui.templates")
local format = require("__flib__.format")
local inventory_tab = {}
function inventory_tab.create()
return {
tab = {
name = "manager_inventory_tab",
type = "tab",
caption = { "cybersyn-gui.inventory" },
ref = { "inventory", "tab" },
handler = inventory_tab.handle.on_inventory_tab_selected
},
content = {
name = "manager_inventory_content_frame",
type = "flow",
style_mods = { horizontal_spacing = 12 },
direction = "horizontal",
ref = { "inventory", "content_frame" },
templates.inventory_slot_table("provided", 12),
templates.inventory_slot_table("in_transit", 8),
templates.inventory_slot_table("requested", 6),
},
}
end
---@param map_data MapData
---@param player_data PlayerData
function inventory_tab.build(map_data, player_data)
local refs = player_data.refs
local search_query = player_data.search_query
local search_item = player_data.search_item
local search_network_name = player_data.search_network_name
local search_network_mask = player_data.search_network_mask
local search_surface_idx = player_data.search_surface_idx
local inventory_provided = {}
local inventory_in_transit = {}
local inventory_requested = {}
local stations_sorted = {}
for id, station in pairs(map_data.stations) do
local entity = station.entity_stop
if not entity.valid then
goto continue
end
if search_query then
if not string.match(entity.backer_name, search_query) then
goto continue
end
end
-- move surface comparison up higher in query to short circuit query earlier if surface doesn't match
if search_surface_idx then
if entity.surface.index ~= search_surface_idx then
goto continue
end
end
if search_network_name then
if search_network_name ~= station.network_name then
goto continue
end
local train_flag = get_network_mask(station, station.network_name)
if not bit32.btest(search_network_mask, train_flag) then
goto continue
end
elseif search_network_mask ~= -1 then
if station.network_name == NETWORK_EACH then
local masks = station.network_mask--[[@as {}]]
for _, network_mask in pairs(masks) do
if bit32.btest(search_network_mask, network_mask) then
goto has_match
end
end
goto continue
::has_match::
elseif not bit32.btest(search_network_mask, station.network_mask) then
goto continue
end
end
if search_item then
if station.deliveries then
for item_name, _ in pairs(station.deliveries) do
if item_name == search_item then
goto has_match
end
end
end
local comb1_signals, _ = get_signals(station)
if comb1_signals then
for _, signal_ID in pairs(comb1_signals) do
local item = signal_ID.signal.name
if item then
if item == search_item then
goto has_match
end
end
end
end
goto continue
::has_match::
end
stations_sorted[#stations_sorted + 1] = id
::continue::
end
for i, station_id in pairs(stations_sorted) do
--- @class Station
local station = map_data.stations[station_id]
local comb1_signals, _ = get_signals(station)
if comb1_signals then
for _, v in pairs(comb1_signals) do
local item = v.signal
local count = v.count
if item.type ~= "virtual" then
if count > 0 then
if inventory_provided[item.name] == nil then
inventory_provided[item.name] = count
else
inventory_provided[item.name] = inventory_provided[item.name] + count
end
else
local r_threshold = station.item_thresholds and station.item_thresholds[item.name] or station.r_threshold
if station.is_stack and item_type == "item" then
r_threshold = r_threshold*get_stack_size(map_data, item.name)
end
if -count >= r_threshold then
if inventory_requested[item.name] == nil then
inventory_requested[item.name] = count
else
inventory_requested[item.name] = inventory_requested[item.name] + count
end
end
end
end
end
end
local deliveries = station.deliveries
if deliveries then
for item, count in pairs(deliveries) do
if count > 0 then
if inventory_in_transit[item] == nil then
inventory_in_transit[item] = 0
inventory_in_transit[item] = inventory_in_transit[item] + count
else
inventory_in_transit[item] = inventory_in_transit[item] + count
end
end
end
end
end
local inventory_provided_table = refs.inventory_provided_table
local provided_children = {}
local i = 0
for item, count in pairs(inventory_provided) do
i = i + 1
local sprite, img_path, item_string = util.generate_item_references(item)
if game.is_valid_sprite_path(sprite) then
provided_children[#provided_children+1] = {
type = "sprite-button",
style = "flib_slot_button_green",
enabled = false,
sprite = sprite,
number = count,
tooltip = { "",
img_path,
" [font=default-semibold]",
item_string,
"[/font]\n"..format.number(count),
},
}
end
end
local inventory_requested_table = refs.inventory_requested_table
local requested_children = {}
local i = 0
for item, count in pairs(inventory_requested) do
i = i + 1
local sprite, img_path, item_string = util.generate_item_references(item)
if game.is_valid_sprite_path(sprite) then
requested_children[#requested_children+1] = {
type = "sprite-button",
style = "flib_slot_button_red",
enabled = false,
sprite = sprite,
number = count,
tooltip = { "",
img_path,
" [font=default-semibold]",
item_string,
"[/font]\n"..format.number(count),
},
}
end
end
local inventory_in_transit_table = refs.inventory_in_transit_table
local in_transit_children = {}
local i = 0
for item, count in pairs(inventory_in_transit) do
i = i + 1
local sprite, img_path, item_string = util.generate_item_references(item)
if game.is_valid_sprite_path(sprite) then
in_transit_children[#in_transit_children+1] = {
type = "sprite-button",
style = "flib_slot_button_blue",
enabled = false,
sprite = sprite,
number = count,
tooltip = { "",
img_path,
" [font=default-semibold]",
item_string,
"[/font]\n"..format.number(count),
},
}
end
end
if next(inventory_provided_table.children) ~= nil then
refs.inventory_provided_table.clear()
end
if next(inventory_requested_table.children) ~= nil then
refs.inventory_requested_table.clear()
end
if next(inventory_in_transit_table.children) ~= nil then
refs.inventory_in_transit_table.clear()
end
gui.add(refs.inventory_provided_table, provided_children)
gui.add(refs.inventory_requested_table, requested_children)
gui.add(refs.inventory_in_transit_table, in_transit_children)
end
inventory_tab.handle = {}
--- @param e {player_index: uint}
function inventory_tab.wrapper(e, handler)
local player = game.get_player(e.player_index)
if not player then return end
local player_data = storage.manager.players[e.player_index]
handler(player, player_data, player_data.refs, e)
end
---@param player LuaPlayer
---@param player_data PlayerData
function inventory_tab.handle.on_inventory_tab_selected(player, player_data)
player_data.selected_tab = "inventory_tab"
end
gui.add_handlers(inventory_tab.handle, inventory_tab.wrapper)
return inventory_tab