Files
project-cybersyn/cybersyn/scripts/gui/trains.lua

232 lines
6.6 KiB
Lua

local format = require("__flib__.format")
local gui = require("__flib__.gui-lite")
local constants = require("constants")
local util = require("scripts.gui.util")
local templates = require("scripts.gui.templates")
local trains_tab = {}
--- @param map_data MapData
--- @param player_data PlayerData
--- @return GuiElemDef
function trains_tab.build(map_data, player_data)
local widths = constants.gui["en"]
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 trains_sorted = {}
for id, train in pairs(map_data.trains) do
if search_network_name then
if search_network_name ~= train.network_name then
goto continue
end
local train_flag = get_network_flag(train, search_network_name)
if not bit32.btest(search_network_mask, train_flag) then
goto continue
end
elseif search_network_mask ~= -1 then
if train.network_name == NETWORK_EACH then
local masks = train.network_flag--[[@as {}]]
for _, network_flag in pairs(masks) do
if bit32.btest(search_network_mask, network_flag) then
goto has_match
end
end
goto continue
::has_match::
elseif not bit32.btest(search_network_mask, train.network_flag) then
goto continue
end
end
if search_surface_idx then
local entity = get_any_train_entity(train.entity)
if not entity then
goto continue
end
if entity.surface.index ~= search_surface_idx then
goto continue
end
end
if search_item then
if not train.manifest then
goto continue
end
for i, v in ipairs(train.manifest) do
if v.name == search_item then
goto has_match
end
end
goto continue
::has_match::
end
trains_sorted[#trains_sorted + 1] = id
::continue::
end
table.sort(trains_sorted, function(a, b)
local train1 = map_data.trains[a]
local train2 = map_data.trains[b]
for i, v in ipairs(player_data.trains_orderings) do
local invert = player_data.trains_orderings_invert[i]
if v == ORDER_LAYOUT then
if train1.layout_id ~= train2.layout_id then
local layout1 = map_data.layouts[train1.layout_id]
local layout2 = map_data.layouts[train2.layout_id]
for j, c1 in ipairs(layout1) do
local c2 = layout2[j]
if c1 ~= c2 then
return invert ~= (c2 and c1 < c2)
end
end
if layout2[#layout1 + 1] then
return invert ~= true
end
end
elseif v == ORDER_DEPOT then
local depot1 = map_data.depots[train1.depot_id]
local depot2 = map_data.depots[train2.depot_id]
local name1 = depot1.entity_stop.valid and depot1.entity_stop.backer_name
local name2 = depot2.entity_stop.valid and depot2.entity_stop.backer_name
if name1 ~= name2 then
return invert ~= (name1 and (name2 and name1 < name2 or true) or false)
end
elseif v == ORDER_STATUS then
if train1.status ~= train2.status then
return invert ~= (train1.status < train2.status)
end
elseif v == ORDER_MANIFEST then
if not train1.manifest then
if train2.manifest then
return invert ~= true
end
elseif not train2.manifest then
return invert ~= false
else
local primary_item1 = train1.manifest[1]
local primary_item2 = train2.manifest[1]
if primary_item1.name ~= primary_item2.name then
return invert ~= (primary_item1.type == primary_item2.type and primary_item1.name < primary_item2.name or primary_item1.type == "item")
elseif primary_item1.count ~= primary_item2.count then
return invert ~= (primary_item1.count < primary_item2.count)
end
end
end
end
return a < b
end)
---@type GuiElemDef
local train_list = {}
if #trains_sorted == 0 then
train_list[1] = {
type = "label",
style = "ltnm_semibold_label",
caption = { "cybersyn-gui.no-trains" },
}
else
for idx, train_id in ipairs(trains_sorted) do
local train = map_data.trains[train_id]
local depot = map_data.depots[train.depot_id]
local depot_name = depot.entity_stop.valid and depot.entity_stop.backer_name or ""
local color = idx % 2 == 0 and "dark" or "light"
train_list[idx] = {
type = "frame",
style = "ltnm_table_row_frame_" .. color,
children = {
{
type = "frame",
style = "ltnm_table_inset_frame_" .. color,
children = {
type = "minimap",
style = "ltnm_train_minimap",
{ type = "label", style = "ltnm_minimap_label" },
{
type = "button",
style = "ltnm_train_minimap_button",
tooltip = { "cybersyn-gui.open-train-gui" },
elem_mods = { entity = get_any_train_entity(train.entity) },
handler = trains_tab.handle.open_train_gui, --on_click
tags = { train_id = train_id },
},
},
},
{
type = "label",
style_mods = { width = widths.trains.composition },
elem_mods = { caption = train.layout_id },
},
{
type = "label",
style_mods = { width = widths.trains.depot },
elem_mods = { caption = depot_name },
},
{
type = "frame",
name = "shipment_frame",
style = "ltnm_small_slot_table_frame_" .. color,
style_mods = { width = widths.trains.shipment },
children = {
{
type = "table",
name = "shipment_table",
style = "slot_table",
column_count = widths.trains.shipment_columns,
children = util.slot_table_build(train.manifest, "default"),
},
},
},
},
}
end
end
return {
tab = {
name = "trains_tab",
type = "tab",
caption = #trains_sorted == 0 and { "cybersyn-gui.trains" } or { "cybersyn-gui.trains", #train_list },
--badge_text = format.number(#ltn_data.sorted_trains.composition),
handler = trains_tab.handle.change_tab, --on_click
tags = { tab = "trains_tab" },
},
content = {
name = "trains_content_frame",
type = "frame",
style = "ltnm_main_content_frame",
direction = "vertical",
children = {
{
type = "frame",
style = "ltnm_table_toolbar_frame",
templates.sort_checkbox(widths, "trains", "status", false),
templates.sort_checkbox(widths, "trains", "layout", false, { "cybersyn-gui.composition-description" }),
templates.sort_checkbox(widths, "trains", "depot", false),
templates.sort_checkbox(widths, "trains", "shipment", false),
},
{ name = "trains_scroll_pane", type = "scroll-pane", style = "ltnm_table_scroll_pane" },
{
name = "trains_warning_flow",
type = "flow",
style = "ltnm_warning_flow",
children = train_list,
},
},
},
}
end
return trains_tab