From 94c015e1216d053b542d7c86c94f98731874225d Mon Sep 17 00:00:00 2001 From: monica Date: Tue, 10 Jan 2023 09:46:10 -0500 Subject: [PATCH] changed minor issues --- cybersyn/changelog.txt | 2 + cybersyn/data.lua | 15 +- cybersyn/scripts/central-planning.lua | 58 +++--- cybersyn/scripts/factorio-api.lua | 4 +- cybersyn/scripts/gui/main.lua | 93 +++++++++ cybersyn/scripts/gui/manager.lua | 199 ++++++++----------- cybersyn/scripts/gui/trains.lua | 266 +++++++++++++++++--------- cybersyn/scripts/gui/util.lua | 5 +- cybersyn/scripts/layout.lua | 6 +- cybersyn/settings.lua | 9 +- 10 files changed, 413 insertions(+), 244 deletions(-) create mode 100644 cybersyn/scripts/gui/main.lua diff --git a/cybersyn/changelog.txt b/cybersyn/changelog.txt index f4b6ecc..add31db 100644 --- a/cybersyn/changelog.txt +++ b/cybersyn/changelog.txt @@ -2,10 +2,12 @@ Version: 1.2.10 Date: 2022-1-9 Changes: + - Made the automatic allow list slightly more forgiving to stations where the last wagon would be on a curved rail - Improved performance when fuel threshold is set to 1 Bugfixes: - Fixed a bug where it was possible for a single station to be updated twice per dispatch cycle, which could cause a crash - Fixed a crash where trains would sometimes think a destroyed depot still exists + - Fixed a case where the central planner generated a confusing alert - Removed unfinished mod setting with the broken translation key --------------------------------------------------------------------------------------------------- Version: 1.2.9 diff --git a/cybersyn/data.lua b/cybersyn/data.lua index f46420a..e4877d0 100644 --- a/cybersyn/data.lua +++ b/cybersyn/data.lua @@ -20,5 +20,18 @@ data:extend({ locked_slots_signal, missing_train_icon, lost_train_icon, - nonempty_train_icon + nonempty_train_icon, + + --{ + -- type = "shortcut", + -- name = "ltnm-toggle-gui", + -- icon = data_util.build_sprite(nil, { 0, 0 }, util.paths.shortcut_icons, 32, 2), + -- disabled_icon = data_util.build_sprite(nil, { 48, 0 }, util.paths.shortcut_icons, 32, 2), + -- small_icon = data_util.build_sprite(nil, { 0, 32 }, util.paths.shortcut_icons, 24, 2), + -- disabled_small_icon = data_util.build_sprite(nil, { 36, 32 }, util.paths.shortcut_icons, 24, 2), + -- toggleable = true, + -- action = "lua", + -- associated_control_input = "ltnm-toggle-gui", + -- technology_to_unlock = "logistic-train-network", + --}, }) diff --git a/cybersyn/scripts/central-planning.lua b/cybersyn/scripts/central-planning.lua index 931e129..e68e964 100644 --- a/cybersyn/scripts/central-planning.lua +++ b/cybersyn/scripts/central-planning.lua @@ -363,6 +363,35 @@ local function tick_dispatch(map_data, mod_settings) if netand == 0 then goto p_continue end + + effective_count = p_station.item_p_counts[item_name] + override_threshold = p_station.item_thresholds and p_station.item_thresholds[item_name] + if override_threshold and p_station.is_stack and not is_fluid then + override_threshold = override_threshold*get_stack_size(map_data, item_name) + end + if effective_count < (override_threshold or r_threshold) then + --this p station should have serviced the current r station, lock it so it can't serve any others + --this will lock stations even when the r station manages to find a p station, this not a problem because all stations will be unlocked before it could be an issue + table_remove(p_stations, j) + if band(p_station.display_state, 4) == 0 then + p_station.display_state = p_station.display_state + 4 + update_display(map_data, p_station) + end + goto p_continue_remove + end + + p_prior = p_station.priority + if override_threshold and p_station.item_priority then + p_prior = p_station.item_priority--[[@as int]] + end + if p_prior < best_p_prior then + goto p_continue + end + + best_p_dist = p_station.entity_stop.valid and r_station.entity_stop.valid and (best_t_to_p_dist + get_dist(p_station.entity_stop, r_station.entity_stop)) or INF + if p_prior == best_p_prior and best_p_dist > best_dist then + goto p_continue + end if correctness < 1 then correctness = 1 closest_to_correct_p_station = p_station @@ -442,35 +471,6 @@ local function tick_dispatch(map_data, mod_settings) goto p_continue end - effective_count = p_station.item_p_counts[item_name] - override_threshold = p_station.item_thresholds and p_station.item_thresholds[item_name] - if override_threshold and p_station.is_stack and not is_fluid then - override_threshold = override_threshold*get_stack_size(map_data, item_name) - end - if effective_count < (override_threshold or r_threshold) then - --this p station should have serviced the current r station, lock it so it can't serve any others - --this will lock stations even when the r station manages to find a p station, this not a problem because all stations will be unlocked before it could be an issue - table_remove(p_stations, j) - if band(p_station.display_state, 4) == 0 then - p_station.display_state = p_station.display_state + 4 - update_display(map_data, p_station) - end - goto p_continue_remove - end - - p_prior = p_station.priority - if override_threshold and p_station.item_priority then - p_prior = p_station.item_priority--[[@as int]] - end - if p_prior < best_p_prior then - goto p_continue - end - - best_p_dist = p_station.entity_stop.valid and r_station.entity_stop.valid and (best_t_to_p_dist + get_dist(p_station.entity_stop, r_station.entity_stop)) or INF - if p_prior == best_p_prior and best_p_dist > best_dist then - goto p_continue - end - p_station_i = j best_train_id = best_p_train_id best_p_prior = p_prior diff --git a/cybersyn/scripts/factorio-api.lua b/cybersyn/scripts/factorio-api.lua index d8c0ab0..d5b2c24 100644 --- a/cybersyn/scripts/factorio-api.lua +++ b/cybersyn/scripts/factorio-api.lua @@ -40,6 +40,7 @@ end ---@param train LuaTrain +---@return LuaEntity? function get_any_train_entity(train) return train.valid and (train.front_stock or train.back_stock or train.carriages[1]) or nil end @@ -47,8 +48,9 @@ end ---@param e Station|Refueler|Train ---@param network_name string +---@return int function get_network_flag(e, network_name) - return e.network_name == NETWORK_EACH and (e.network_flag[network_name] or 0) or e.network_flag + return e.network_name == NETWORK_EACH and (e.network_flag[network_name] or 0) or e.network_flag--[[@as int]] end diff --git a/cybersyn/scripts/gui/main.lua b/cybersyn/scripts/gui/main.lua new file mode 100644 index 0000000..fc72dcd --- /dev/null +++ b/cybersyn/scripts/gui/main.lua @@ -0,0 +1,93 @@ +local gui = require("__flib__.gui-lite") +local mod_gui = require("__core__.lualib.mod-gui") + +local manager = require("scripts.gui.manager") + + +--- @class PlayerData +--- @field refs {[string]: LuaGuiElement}? +--- @field search_query string? +--- @field search_network_name string? +--- @field search_network_mask int +--- @field search_surface_idx uint? +--- @field search_item string? +--- @field trains_orderings uint[] +--- @field trains_orderings_invert boolean[] +--- @field pinning boolean + + + + +local function top_left_button_update(player, player_data) + local button_flow = mod_gui.get_button_flow(player) + local button = button_flow["top_left_button"] + if player_data.disable_top_left_button then + if button then + button.destroy() + end + elseif not button then + gui.add(button_flow, { + type = "sprite-button", + name = "top_left_button", + style = "mis_mod_gui_button_green", + sprite = "mis_configure_white", + tooltip = { "", "\n", { "mis-config-gui.configure-tooltip" } }, + handler = manager.handle.toggle, + }) + end +end + + + +local manager_gui = {} + +function manager_gui.on_lua_shortcut(e) + if e.prototype_name == "ltnm-toggle-gui" then + manager.wrapper(e, manager.handle.toggle) + end +end + + + +function manager_gui.on_player_created(e) + local player = game.get_player(e.player_index) + if not player then return end + local player_data = { + search_network_mask = -1, + trains_orderings = {}, + trains_orderings_invert = {}, + pinning = false, + refs = manager.create(player), + } + global.manager_data.players[e.player_index] = player_data + + manager.update(global, player, player_data) + top_left_button_update(player, player_data) +end + +function manager_gui.on_player_removed(e) + global.manager_data.players[e.player_index] = nil +end + +--script.on_event(defines.events.on_player_joined_game, function(e) +--end) + +--script.on_event(defines.events.on_player_left_game, function(e) +--end) + +function manager_gui.on_runtime_mod_setting_changed(e) + if e.setting == "cybersyn-disable-top-left-button" then + if not e.player_index then return end + local player = game.get_player(e.player_index) + if not player then return end + + local player_data = global.manager_data.players[e.player_index] + player_data.disable_top_left_button = player.mod_settings["cybersyn-disable-top-left-button"].value + top_left_button_update(player, player_data) + end +end + + +--gui.handle_events() + +return manager_gui diff --git a/cybersyn/scripts/gui/manager.lua b/cybersyn/scripts/gui/manager.lua index df8f5d7..bd421cb 100644 --- a/cybersyn/scripts/gui/manager.lua +++ b/cybersyn/scripts/gui/manager.lua @@ -13,61 +13,16 @@ local trains_tab = require("scripts.gui.trains") --local alerts_tab = require("scripts.gui.alerts") ---- @class PlayerData ---- @field refs {[string]: LuaGuiElement}? ---- @field search_query string? ---- @field network_name string ---- @field network_flag int ---- @field pinning boolean - - - -function Index:dispatch(msg, e) - -- "Transform" the action based on criteria - if msg.transform == "handle_refresh_click" then - if e.shift then - msg.action = "toggle_auto_refresh" - else - self.state.ltn_data = global.data - self.do_update = true - end - elseif msg.transform == "handle_titlebar_click" then - if e.button == defines.mouse_button_type.middle then - msg.action = "recenter" - end - end - - -- Dispatch the associated action - if msg.action then - local func = self.actions[msg.action] - if func then - func(self, msg, e) - else - log("Attempted to call action `" .. msg.action .. "` for which there is no handler yet.") - end - end - - -- Update if necessary - if self.do_update then - self:update() - self.do_update = false - end -end - -function Index:schedule_update() - self.do_update = true -end - - local manager = {} -function manager.build(player, player_data) +--- @param player LuaPlayer +function manager.create(player) local widths = constants.gui["en"] ---@type table local refs = {} - local _, window = gui.add(player.gui.screen, { + gui.add(player.gui.screen, { { name = "manager_window", type = "frame", @@ -111,25 +66,25 @@ function manager.build(player, player_data) name = "manager_text_search_field", type = "textfield", clear_and_focus_on_right_click = true, - handler = manager.handle.update_text_search_query, --on_gui_text_changed + handler = manager.handle.update_text_search, --on_gui_text_changed }, { type = "empty-widget", style = "flib_horizontal_pusher" }, { type = "label", style = "caption_label", caption = { "gui.ltnm-network-id-label" } }, { - name = "manager_network_id_field", + name = "manager_network_mask_field", type = "textfield", style_mods = { width = 120 }, numeric = true, allow_negative = true, clear_and_focus_on_right_click = true, text = "-1", - handler = manager.handle.update_network_id_query, --on_gui_text_changed + handler = manager.handle.update_network_mask, --on_gui_text_changed }, { type = "label", style = "caption_label", caption = { "gui.ltnm-surface-label" } }, { name = "manager_surface_dropdown", type = "drop-down", - handler = manager.handle.change_surface, --on_gui_selection_state_changed + handler = manager.handle.update_surface, --on_gui_selection_state_changed }, }, }, @@ -137,9 +92,6 @@ function manager.build(player, player_data) name = "manager_tabbed_pane", type = "tabbed-pane", style = "ltnm_tabbed_pane", - children = { - trains_tab.build(widths, refs), - }, }, }, }, @@ -149,23 +101,49 @@ function manager.build(player, player_data) - refs.manager_titlebar.drag_target = window - window.force_auto_center() + refs.manager_titlebar.drag_target = refs.manager_window + refs.manager_window.force_auto_center() + + return refs end +--- @param map_data MapData --- @param player LuaPlayer ---- @param refs table -function manager.destroy(player, refs) - refs.manager_window.destroy() - - player.set_shortcut_toggled("ltnm-toggle-gui", false) - player.set_shortcut_available("ltnm-toggle-gui", false) +--- @param player_data PlayerData +function manager.update(map_data, player, player_data) + local tab = trains_tab.build(map_data, player_data) + gui.add(_, tab, player_data.refs) end + + +manager.handle = {} + +--- @param e {player_index: uint} +function manager.wrapper(e, handler) + local player = game.get_player(e.player_index) + if not player then return end + local player_data = global.manager_data.players[e.player_index] + handler(player, player_data, player_data.refs, e) +end + + +local function toggle_fab(elem, sprite, state) + if state then + elem.style = "flib_selected_frame_action_button" + elem.sprite = sprite .. "_black" + else + elem.style = "frame_action_button" + elem.sprite = sprite .. "_white" + end +end + + + --- @param player LuaPlayer --- @param player_data PlayerData --- @param refs table -function manager.open(player, player_data, refs) +function manager.handle.open(player, player_data, refs) refs.manager_window.bring_to_front() refs.manager_window.visible = true player_data.visible = true @@ -177,10 +155,11 @@ function manager.open(player, player_data, refs) player.set_shortcut_toggled("ltnm-toggle-gui", true) end + --- @param player LuaPlayer --- @param player_data PlayerData --- @param refs table -function manager.close(player, player_data, refs) +function manager.handle.close(player, player_data, refs) if player_data.pinning then return end @@ -195,86 +174,76 @@ function manager.close(player, player_data, refs) player.set_shortcut_toggled("ltnm-toggle-gui", false) end +--- @param player LuaPlayer +--- @param player_data PlayerData +--- @param refs table +function manager.handle.toggle(player, player_data, refs) -manager.handle = {} - ---- @param e GuiEventData -function manager.wrapper(e, handler) - local player = game.get_player(e.player_index) - if not player then return end - local player_data = global.manager.players[e.player_index] - handler(player, player_data, player_data.refs) end - -local function toggle_fab(elem, sprite, state) - if state then - elem.style = "flib_selected_frame_action_button" - elem.sprite = sprite .. "_black" - else - elem.style = "frame_action_button" - elem.sprite = sprite .. "_white" - end -end - - -manager.handle.close = manager.close - --- @param player LuaPlayer --- @param player_data PlayerData --- @param refs table function manager.handle.recenter(player, player_data, refs) - refs.window.force_auto_center() + refs.window.force_auto_center() end --- @param player LuaPlayer --- @param player_data PlayerData --- @param refs table function manager.handle.toggle_auto_refresh(player, player_data, refs) - player_data.auto_refresh = not player_data.auto_refresh - toggle_fab(refs.manager_refresh_button, "ltnm_refresh", player_data.auto_refresh) + player_data.auto_refresh = not player_data.auto_refresh + toggle_fab(refs.manager_refresh_button, "ltnm_refresh", player_data.auto_refresh) end --- @param player LuaPlayer --- @param player_data PlayerData --- @param refs table function manager.handle.toggle_pinned(player, player_data, refs) - player_data.pinned = not player_data.pinned - toggle_fab(refs.manager_pin_button, "ltnm_pin", player_data.pinned) + player_data.pinned = not player_data.pinned + toggle_fab(refs.manager_pin_button, "ltnm_pin", player_data.pinned) end --- @param player LuaPlayer --- @param player_data PlayerData --- @param refs table --- @param e GuiEventData -function manager.handle.update_text_search_query(player, player_data, refs, e) - local query = e.text - -- Input sanitization - for pattern, replacement in pairs(constants.input_sanitizers) do - query = string.gsub(query, pattern, replacement) - end - player_data.search_query = query - - if Gui.state.search_job then - on_tick_n.remove(Gui.state.search_job) - end - - if #query == 0 then - Gui:schedule_update() - else - Gui.state.search_job = on_tick_n.add( - game.tick + 30, - { gui = "main", action = "update", player_index = Gui.player.index } - ) - end +function manager.handle.update_text_search(player, player_data, refs, e) + local query = e.text + -- Input sanitization + for pattern, replacement in pairs(constants.input_sanitizers) do + query = string.gsub(query, pattern, replacement) + end + player_data.search_query = query end + --- @param player LuaPlayer --- @param player_data PlayerData --- @param refs table -function manager.handle.update_network_id_query(player, player_data, refs) - Gui.state.network_id = tonumber(Gui.refs.toolbar.network_id_field.text) or -1 - Gui:schedule_update() +function manager.handle.update_network_name(player, player_data, refs) + local signal = refs.manager_network_name.elem_value + if signal then + player_data.search_network_name = signal.name + else + player_data.search_network_name = nil + end +end +--- @param player LuaPlayer +--- @param player_data PlayerData +--- @param refs table +function manager.handle.update_network_mask(player, player_data, refs) + player_data.search_network_mask = tonumber(refs.manager_network_mask_field.text) or -1 +end +--- @param player LuaPlayer +--- @param player_data PlayerData +--- @param refs table +function manager.handle.update_surface(player, player_data, refs) + local i = refs.manager_surface_dropdown.selected_index + player_data.search_surface_idx = i--TODO: fix this end + +gui.add_handlers(manager.handle, manager.wrapper) + return manager diff --git a/cybersyn/scripts/gui/trains.lua b/cybersyn/scripts/gui/trains.lua index bdbd628..05fd9c8 100644 --- a/cybersyn/scripts/gui/trains.lua +++ b/cybersyn/scripts/gui/trains.lua @@ -1,146 +1,226 @@ +local format = require("__flib__.format") local gui = require("__flib__.gui-lite") local constants = require("constants") local util = require("scripts.gui.util") -local templates = require("templates") +local templates = require("scripts.gui.templates") local trains_tab = {} -function trains_tab.build(map_data, player_id, player_data) +--- @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_query = player_data.search_query - local search_network_flag = player_data.network_flag - local search_network = player_data.network + 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) - local trains_sorted = player_data.trains_sorted ---@type GuiElemDef local train_list = {} - --if not sorted_trains then - -- sorted_trains = {} - -- ids = {} - -- for id, train in pairs(map_data) do - -- local i = #ids + 1 - -- ids[i] = id - -- sorted_trains[i] = train - -- end - -- dual_sort(ids, sorted_trains) - --end if #trains_sorted == 0 then train_list[1] = { type = "label", style = "ltnm_semibold_label", caption = { "gui.ltnm-no-trains" }, - ref = { "trains", "warning_label" }, } else - local start, finish, step - if player_data.trains_ascending then - start = #trains_sorted - finish = 1 - step = -1 - else - start = 1 - finish = #trains_sorted - step = 1 - end - - local gui_idx = 1 - for idx = start, finish, step do - local train_id = trains_sorted[idx] + 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 "" - if - true - then - local color = gui_idx % 2 == 0 and "dark" or "light" - train_list[gui_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 = { "gui.ltnm-open-train-gui" }, - elem_mods = { entity = get_any_train_entity(train.entity) }, - actions = { - on_click = { gui = "main", action = "open_train_gui", train_id = train_id }, - }, - }, - }, - }, - { - type = "label", - style_mods = { width = widths.trains.composition }, - elem_mods = { caption = train.composition }, - }, - { - type = "label", style_mods = { width = widths.trains.depot }, - elem_mods = { caption = train.depot }, - }, - { - 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"), - }, + 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 = { "gui.ltnm-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 }, }, }, }, - } - gui_idx = gui_idx + 1 - end + { + 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 { "gui.ltnm-trains" } or { "gui.ltnm-trains", #train_list }, - badge_text = misc.delineate_number(#ltn_data.sorted_trains.composition), - ref = { "trains", "tab" }, - actions = { - on_click = { gui = "main", action = "change_tab", tab = "trains" }, - }, + --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", - ref = { "trains", "content_frame" }, children = { { type = "frame", style = "ltnm_table_toolbar_frame", - templates.sort_checkbox(widths, "trains", "train_id", true), templates.sort_checkbox(widths, "trains", "status", false), - templates.sort_checkbox(widths, "trains", "composition", false, { "gui.ltnm-composition-description" }), + templates.sort_checkbox(widths, "trains", "layout", false, { "gui.ltnm-composition-description" }), templates.sort_checkbox(widths, "trains", "depot", false), templates.sort_checkbox(widths, "trains", "shipment", false), }, - { type = "scroll-pane", style = "ltnm_table_scroll_pane", ref = { "trains", "scroll_pane" } }, + { name = "trains_scroll_pane", type = "scroll-pane", style = "ltnm_table_scroll_pane" }, { + name = "trains_warning_flow", type = "flow", style = "ltnm_warning_flow", - visible = false, - ref = { "trains", "warning_flow" }, children = train_list, }, }, diff --git a/cybersyn/scripts/gui/util.lua b/cybersyn/scripts/gui/util.lua index c1b01bf..5b3893a 100644 --- a/cybersyn/scripts/gui/util.lua +++ b/cybersyn/scripts/gui/util.lua @@ -38,8 +38,8 @@ end --- @param color string --- @return GuiElemDef[] function util.slot_table_build(manifest, color) + ---@type GuiElemDef[] local children = {} - local i = 1 for _, item in pairs(manifest) do local name = item.name local sprite @@ -49,7 +49,7 @@ function util.slot_table_build(manifest, color) sprite = string.gsub(name, ",", "/") end if game.is_valid_sprite_path(sprite) then - children[i] = { + children[#children + 1] = { type = "sprite-button", enabled = false, style = "ltnm_small_slot_button_" .. color, @@ -61,7 +61,6 @@ function util.slot_table_build(manifest, color) "\n"..format.number(count), }, } - i = i + 1 end end return children diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index 5c9497b..4bea069 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -471,7 +471,7 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent local wagon_number = 0 for i = 1, 112 do local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_stop, rail_connection_direction = defines.rail_connection_direction.straight}) - if not rail or rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then + if not rail or not rail.valid then is_break = true break end @@ -555,6 +555,10 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent end search_area = area.move(search_area, area_delta) end + if not rail_connection_direction ~= defines.rail_connection_direction.straight then + is_break = true + break + end end stop.layout_pattern = layout_pattern if is_station_or_refueler then diff --git a/cybersyn/settings.lua b/cybersyn/settings.lua index f2888e9..664fcca 100644 --- a/cybersyn/settings.lua +++ b/cybersyn/settings.lua @@ -103,12 +103,19 @@ data:extend({ default_value = false, }, --{ + -- type = "bool-setting", + -- name = "cybersyn-disable-top-left-button", + -- setting_type = "runtime-player", + -- default_value = false, + -- order = "ea", + --}, + --{ -- type = "int-setting", -- name = "cybersyn-history-length", -- setting_type = "runtime-global", -- minimum_value = 10, -- maximum_value = 1000, -- default_value = 50, - -- order = "ea", + -- order = "eb", --}, })