Files
project-cybersyn/cybersyn/scripts/gui/util.lua
2024-10-23 00:43:15 +02:00

330 lines
8.9 KiB
Lua

local gui = require("__flib__.gui")
local format = require("__flib__.format")
local util = {}
--- Create a flying text at the player's cursor with an error sound.
--- @param player LuaPlayer
--- @param message LocalisedString
function util.error_flying_text(player, message)
player.create_local_flying_text({ create_at_cursor = true, text = message })
player.play_sound({ path = "utility/cannot_build" })
end
function util.gui_list(parent, iterator, test, build, update, ...)
local children = parent.children
local i = 0
for k, v in table.unpack(iterator) do
local passed = test(v, k, i, ...)
if passed then
i = i + 1
local child = children[i]
if not child then
gui.build(parent, { build(...) })
child = parent.children[i]
end
gui.update(child, update(v, k, i, ...))
end
end
for j = i + 1, #children do
children[j].destroy()
end
end
--- Builds a valid sprite path or returns nil
--- @param item string
--- @return string, string, LocalizedString
function util.generate_item_references(item)
local sprite = nil
local image_path = ""
local item_name
if helpers.is_valid_sprite_path("item/" .. item) then
sprite = "item/" .. item
image_path = "[img=item." .. item .. "]"
item_name = {"?", { "item-name." .. item }, { "entity-name." .. item }, "LocalizedString failure: " .. item }
elseif helpers.is_valid_sprite_path("fluid/" .. item) then
sprite = "fluid/" .. item
image_path = "[img=fluid." .. item .. "]"
item_name = {"?", { "fluid-name." .. item }, "LocalizedString failure: " .. item }
elseif helpers.is_valid_sprite_path("virtual-signal/" .. item) then
sprite = "virtual-signal/" .. item
image_path = "[img=virtual-signal." .. item .. "]"
item_name = {"?", { "virtual-signal." .. item }, "LocalizedString failure: " .. item }
end
return sprite, image_path, item_name
end
--- Updates a slot table based on the passed criteria.
--- @param manifest Manifest?
--- @param color string
--- @return GuiElemDef[]
function util.slot_table_build_from_manifest(manifest, color)
---@type GuiElemDef[]
local children = {}
if manifest then
for _, item in pairs(manifest) do
local name = item.name
local count = item.count
local sprite, img_path, item_string = util.generate_item_references(name)
if helpers.is_valid_sprite_path(sprite) then
children[#children + 1] = {
type = "sprite-button",
enabled = false,
style = "ltnm_small_slot_button_" .. color,
sprite = sprite,
number = count,
tooltip = {
"",
img_path,
item_string,
"\n"..format.number(count),
},
}
end
end
end
return children
end
--- @param station Station
--- @param color string
--- @return GuiElemDef[]
function util.slot_table_build_from_station(station)
---@type GuiElemDef[]
local children = {}
local comb1_signals, comb2_signals = get_signals(station)
if comb1_signals then
for _, v in pairs(comb1_signals) do
local item = v.signal
if item.type == "virtual" then
goto continue
end
local count = v.count
local name = item.name
-- FIXME handle item.quality
local sprite, img_path, item_string = util.generate_item_references(name)
if sprite ~= nil then
local color
if count > 0 then
color = "green"
else
color = "red"
end
if helpers.is_valid_sprite_path(sprite) then
children[#children + 1] = {
type = "sprite-button",
enabled = false,
style = "ltnm_small_slot_button_" .. color,
sprite = sprite,
tooltip = {
"",
img_path,
item_string,
"\n"..format.number(count),
},
number = count
}
end
end
::continue::
end
end
return children
end
function util.slot_table_build_from_deliveries(station)
---@type GuiElemDef[]
local children = {}
local deliveries = station.deliveries
for item, count in pairs(deliveries) do
local sprite, img_path, item_string = util.generate_item_references(item)
if sprite ~= nil then
local color
if count > 0 then
color = "green"
else
color = "blue"
end
if helpers.is_valid_sprite_path(sprite) then
children[#children + 1] = {
type = "sprite-button",
enabled = false,
style = "ltnm_small_slot_button_" .. color,
sprite = sprite,
tooltip = {
"",
img_path,
item_string,
"\n"..format.number(count),
},
number = count
}
end
end
end
return children
end
--- @param station Station
--- @return GuiElemDef[]
function util.slot_table_build_from_control_signals(station, map_data)
---@type GuiElemDef[]
local children = {}
local comb1_signals, comb2_signals = get_signals(station)
if comb1_signals then
for _, v in pairs(comb1_signals) do
local item = v.signal
local count = v.count
local name = item.name
-- FIXME handle item.quality
local sprite = ""
local color = "default"
if item.type ~= "virtual" then
goto continue
else
sprite = "virtual-signal" .. "/" .. name
end
if helpers.is_valid_sprite_path(sprite) then
children[#children + 1] = {
type = "sprite-button",
enabled = false,
style = "ltnm_small_slot_button_" .. color,
sprite = sprite,
tooltip = {
"",
"[img=virtual-signal." .. name .. "]",
{ "virtual-signal-name." .. name },
"\n"..format.number(count),
},
number = count
}
end
::continue::
end
end
if comb2_signals then
for _, v in pairs(comb2_signals) do
local item = v.signal
local count = v.count
local name = item.name
local sprite = ""
local color = "default"
if not item.type or item.type == "item" or item.type == "fluid" then
local sprite, img_path, item_string = util.generate_item_references(name)
if sprite ~= nil then
local color
if count > 0 then
color = "green"
else
color = "blue"
end
end
if station.is_stack and (not item.type or item.type == "item") then
count = count * get_stack_size(map_data, name)
end
if helpers.is_valid_sprite_path(sprite) then
children[#children + 1] = {
type = "sprite-button",
enabled = false,
style = "ltnm_small_slot_button_" .. color,
sprite = sprite,
tooltip = {
"",
img_path,
item_string,
"\n"..format.number(count),
},
number = count
}
end
elseif item.type == "virtual" then
sprite = "virtual-signal" .. "/" .. name
if helpers.is_valid_sprite_path(sprite) then
children[#children + 1] = {
type = "sprite-button",
enabled = false,
style = "ltnm_small_slot_button_" .. color,
sprite = sprite,
tooltip = {
"",
"[img=virtual-signal." .. name .. "]",
{ "virtual-signal-name." .. name },
"\n"..format.number(count),
},
number = count
}
end
end
::continue::
end
end
return children
end
function util.sorted_iterator(arr, src_tbl, sort_state)
local step = sort_state and 1 or -1
local i = sort_state and 1 or #arr
return function()
local j = i + step
if arr[j] then
i = j
local arr_value = arr[j]
return arr_value, src_tbl[arr_value]
end
end,
arr
end
local MAX_INT = 2147483648 -- math.pow(2, 31)
function util.signed_int32(val)
return (val >= MAX_INT and val - (2 * MAX_INT)) or val
end
function util.close_manager_window(player, player_data, refs)
if player_data.pinning then
return
end
refs.manager_window.visible = false
player_data.visible = false
if player.opened == refs.manager_window then
player.opened = nil
end
player_data.is_manager_open = false
player.set_shortcut_toggled("cybersyn-toggle-gui", false)
end
function util.build_train_layout_table(map_data)
local layouts = map_data.layouts
local layouts_table = {}
for i, v in pairs(layouts) do
local layout_string = table.concat(v, ",")
layout_string = layout_string.gsub(layout_string, "0", "[item=locomotive]")
layout_string = layout_string.gsub(layout_string, "1", "[item=cargo-wagon]")
layout_string = layout_string.gsub(layout_string, "2", "[item=fluid-wagon]")
layout_string = layout_string.gsub(layout_string, ",", "")
layouts_table[i] = layout_string
end
return layouts_table
end
return util