diff --git a/cybersyn/TODO b/cybersyn/TODO index cbb4781..a2dd21b 100644 --- a/cybersyn/TODO +++ b/cybersyn/TODO @@ -2,6 +2,5 @@ finish wagon manifest close gui when the combinator is destroyed improve localization support space elevator -add an "all" train class do hardcore testing optimizations? diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index 793811b..51b9ce3 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -47,3 +47,4 @@ comb2=Secondary station control depot=Depot wagon-manifest=Wagon combinator-title=Cybernetic combinator +auto-description=Station automatically decides which trains in the network it can service diff --git a/cybersyn/scripts/central-planning.lua b/cybersyn/scripts/central-planning.lua index 34cecb8..cb38061 100644 --- a/cybersyn/scripts/central-planning.lua +++ b/cybersyn/scripts/central-planning.lua @@ -173,7 +173,7 @@ end ---@param station Station ---@param layout_id uint local function station_accepts_layout(station, layout_id) - return station.accepted_layouts[layout_id] + return station.is_all or station.accepted_layouts[layout_id] end diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index cc32185..f0a7d9e 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -27,7 +27,7 @@ ---@field public deliveries {[string]: int} ---@field public network_name string? ---@field public network_flag int --transient ----@field public train_class SignalID? +---@field public is_all boolean ---@field public accepted_layouts TrainClass ---@field public layout_pattern string? ---@field public tick_signals Signal[]? --transient diff --git a/cybersyn/scripts/gui.lua b/cybersyn/scripts/gui.lua index 6401114..bb6173c 100644 --- a/cybersyn/scripts/gui.lua +++ b/cybersyn/scripts/gui.lua @@ -31,7 +31,7 @@ STATUS_NAMES_DEFAULT = "entity-status.disabled" function gui_opened(comb, player) local rootgui = player.gui.screen local selected_index = 0 - local control = comb.get_or_create_control_behavior().parameters + local control = comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] if control.operation == OPERATION_PRIMARY_IO then selected_index = 1 elseif control.operation == OPERATION_SECONDARY_IO then @@ -42,52 +42,60 @@ function gui_opened(comb, player) selected_index = 4 end - local window = flib_gui.build(rootgui, { - {type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, children={ - --title bar - {type="flow", ref={"titlebar"}, children={ - {type="label", style="frame_title", caption={"cybersyn-gui.combinator-title"}, elem_mods={ignored_by_interaction=true}}, - {type="empty-widget", style="flib_titlebar_drag_handle", elem_mods={ignored_by_interaction=true}}, - {type="sprite-button", style="frame_action_button", mouse_button_filter={"left"}, sprite="utility/close_white", hovered_sprite="utility/close_black", name=COMBINATOR_NAME, actions={ - on_click = {"close", comb.unit_number} - }} - }}, - {type="frame", style="inside_shallow_frame_with_padding", style_mods={padding=12}, children={ - {type="flow", direction="vertical", style_mods={horizontal_align="left"}, children={ - --status - {type="flow", style = "status_flow", direction = "horizontal", style_mods={vertical_align="center", horizontally_stretchable=true, bottom_padding=4}, children={ - {type="sprite", sprite=STATUS_SPRITES[comb.status] or STATUS_SPRITES_DEFAULT, style="status_image", ref={"status_icon"}, style_mods={stretch_image_to_widget_size=true}}, - {type="label", caption={STATUS_NAMES[comb.status] or STATUS_NAMES_DEFAULT}, ref={"status_label"}} - }}, - --preview - {type="frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={ - {type="entity-preview", style="wide_entity_button", ref={"preview"}}, - }}, - --drop down - {type="label", style="heading_3_label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}}, - {type="drop-down", style_mods={top_padding=3}, ref={"operation"}, actions={ - on_selection_state_changed={"drop-down", comb.unit_number} - }, selected_index=selected_index, items={ - {"cybersyn-gui.comb1"}, - {"cybersyn-gui.comb2"}, - {"cybersyn-gui.depot"}, - {"cybersyn-gui.wagon-manifest"}, - }}, - ---choose-elem-button - {type="line", style_mods={top_padding=10}}, - {type="label", name="network_label", style="heading_3_label", caption={"cybersyn-gui.network"}, style_mods={top_padding=7}}, - {type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", ref={"network"}, elem_type="signal", signal=control.first_signal, style_mods={bottom_margin=2}, actions={ +local window = flib_gui.build(rootgui, { + {type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, children={ + --title bar + {type="flow", ref={"titlebar"}, children={ + {type="label", style="frame_title", caption={"cybersyn-gui.combinator-title"}, elem_mods={ignored_by_interaction=true}}, + {type="empty-widget", style="flib_titlebar_drag_handle", elem_mods={ignored_by_interaction=true}}, + {type="sprite-button", style="frame_action_button", mouse_button_filter={"left"}, sprite="utility/close_white", hovered_sprite="utility/close_black", name=COMBINATOR_NAME, actions={ + on_click = {"close", comb.unit_number} + }} + }}, + {type="frame", style="inside_shallow_frame_with_padding", style_mods={padding=12}, children={ + {type="flow", direction="vertical", style_mods={horizontal_align="left"}, children={ + --status + {type="flow", style="status_flow", direction="horizontal", style_mods={vertical_align="center", horizontally_stretchable=true, bottom_padding=4}, children={ + {type="sprite", sprite=STATUS_SPRITES[comb.status] or STATUS_SPRITES_DEFAULT, style="status_image", ref={"status_icon"}, style_mods={stretch_image_to_widget_size=true}}, + {type="label", caption={STATUS_NAMES[comb.status] or STATUS_NAMES_DEFAULT}, ref={"status_label"}} + }}, + --preview + {type="frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={ + {type="entity-preview", style="wide_entity_button", ref={"preview"}}, + }}, + --drop down + {type="label", style="heading_3_label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}}, + {type="drop-down", style_mods={top_padding=3}, ref={"operation"}, actions={ + on_selection_state_changed={"drop-down", comb.unit_number} + }, selected_index=selected_index, items={ + {"cybersyn-gui.comb1"}, + {"cybersyn-gui.comb2"}, + {"cybersyn-gui.depot"}, + {"cybersyn-gui.wagon-manifest"}, + }}, + ---choose-elem-button + {type="line", style_mods={top_padding=10}}, + {type="label", name="network_label", style="heading_3_label", caption={"cybersyn-gui.network"}, style_mods={top_padding=7}}, + {type="flow", name="bottom", direction="horizontal", children={ + {type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", ref={"network"}, elem_type="signal", signal=control.first_signal, style_mods={bottom_margin=2, right_margin=6}, actions={ on_elem_changed={"choose-elem-button", comb.unit_number} }}, + {type="checkbox", name="radiobutton", ref={"radiobutton"}, state=control.second_constant ~= 1, style_mods={top_margin=4}, actions={ + on_checked_state_changed={"radiobutton", comb.unit_number} + }}, + {type="label", name="radiolabel", style_mods={single_line=false, maximal_width=330, left_padding=3}, ref={"radiolabel"}, caption={"cybersyn-gui.auto-description"}}, }} }} }} - }) + }} +}) window.preview.entity = comb window.titlebar.drag_target = window.main_window window.main_window.force_auto_center() window.network.visible = selected_index == 1 or selected_index == 3 + window.radiobutton.visible = selected_index == 1 + window.radiolabel.visible = selected_index == 1 player.opened = window.main_window end @@ -132,25 +140,33 @@ function register_gui_actions() local comb = global.to_comb[msg[2]] if not comb or not comb.valid then return end - local parent = element.parent - local a = comb.get_or_create_control_behavior() + local parent = element.parent.bottom + local a = comb.get_or_create_control_behavior() --[[@as LuaArithmeticCombinatorControlBehavior]] local control = a.parameters if element.selected_index == 1 then control.operation = OPERATION_PRIMARY_IO + element.parent["network_label"].visible = true parent["network"].visible = true - parent["network_label"].visible = true + parent["radiobutton"].visible = true + parent["radiolabel"].visible = true elseif element.selected_index == 2 then control.operation = OPERATION_SECONDARY_IO + element.parent["network_label"].visible = false parent["network"].visible = false - parent["network_label"].visible = false + parent["radiobutton"].visible = false + parent["radiolabel"].visible = false elseif element.selected_index == 3 then control.operation = OPERATION_DEPOT + element.parent["network_label"].visible = true parent["network"].visible = true - parent["network_label"].visible = true + parent["radiobutton"].visible = false + parent["radiolabel"].visible = false elseif element.selected_index == 4 then control.operation = OPERATION_WAGON_MANIFEST + element.parent["network_label"].visible = false parent["network"].visible = false - parent["network_label"].visible = false + parent["radiobutton"].visible = false + parent["radiolabel"].visible = false else return end @@ -163,7 +179,7 @@ function register_gui_actions() local comb = global.to_comb[msg[2]] if not comb or not comb.valid then return end - local a = comb.get_or_create_control_behavior() + local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]] local control = a.parameters local signal = element.elem_value @@ -176,6 +192,27 @@ function register_gui_actions() a.parameters = control on_combinator_network_updated(global, comb, signal and signal.name or nil) + elseif msg[1] == "radiobutton" then + local element = event.element + if not element then return end + local comb = global.to_comb[msg[2]] + if not comb or not comb.valid then return end + + local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]] + local control = a.parameters + + local is_auto = element.state + control.second_constant = is_auto and 0 or 1 + + a.parameters = control + + local stop = global.to_stop[comb.unit_number] + if stop then + local station = global.stations[stop.unit_number] + if station then + set_station_train_class(global, station, not is_auto) + end + end end end end) diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index 53ff419..d56b8f6 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -300,7 +300,6 @@ local function reset_station_layout(map_data, station, forbidden_entity) local area_delta local direction_filter local is_ver - --local center_line if station_direction == defines.direction.north then search_area = {left_top = {x = middle_x - reach, y = middle_y}, right_bottom = {x = middle_x + reach, y = middle_y + 6}} area_delta = {x = 0, y = 7} @@ -376,7 +375,7 @@ local function reset_station_layout(map_data, station, forbidden_entity) supports_fluid = true end elseif entity.name == COMBINATOR_NAME then - local control = entity.get_or_create_control_behavior().parameters + local control = entity.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] if control.operation == OPERATION_WAGON_MANIFEST then local pos = entity.position local is_there @@ -427,19 +426,13 @@ end ---@param map_data MapData ---@param station Station ----@param train_class SignalID -function set_station_train_class(map_data, station, train_class) - if train_class.name == TRAIN_CLASS_AUTO.name then - if station.train_class.name ~= TRAIN_CLASS_AUTO.name then - station.train_class = TRAIN_CLASS_AUTO - station.accepted_layouts = {} +---@param is_all boolean +function set_station_train_class(map_data, station, is_all) + if station.is_all ~= is_all then + station.is_all = is_all + if not is_all then + reset_station_layout(map_data, station, nil) end - reset_station_layout(map_data, station, nil) - else - station.train_class = train_class - station.accepted_layouts = map_data.train_classes[train_class.name] - assert(station.accepted_layouts ~= nil) - station.layout_pattern = nil end end @@ -447,7 +440,7 @@ end ---@param station Station ---@param forbidden_entity LuaEntity? function update_station_if_auto(map_data, station, forbidden_entity) - if station.train_class.name == TRAIN_CLASS_AUTO.name then + if not station.is_all then reset_station_layout(map_data, station, forbidden_entity) end end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index 6fb0076..1afd4ba 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -32,11 +32,11 @@ end ---@param map_data MapData ---@param stop LuaEntity ---@param comb LuaEntity -local function on_depot_built(map_data, stop, comb, network_name) +local function on_depot_built(map_data, stop, comb, control) local depot = { entity_stop = stop, entity_comb = comb, - network_name = network_name, + network_name = control.first_signal and control.first_signal.name or nil, priority = 0, network_flag = 0, } @@ -47,8 +47,8 @@ end ---@param stop LuaEntity ---@param comb1 LuaEntity ---@param comb2 LuaEntity ----@param network_name string -local function on_station_built(map_data, stop, comb1, comb2, network_name) +---@param control ArithmeticCombinatorParameters +local function on_station_built(map_data, stop, comb1, comb2, control) local station = { entity_stop = stop, entity_comb1 = comb1, @@ -60,10 +60,10 @@ local function on_station_built(map_data, stop, comb1, comb2, network_name) r_threshold = 0, p_threshold = 0, locked_slots = 0, - network_name = network_name, + network_name = control.first_signal and control.first_signal.name or nil, network_flag = 0, deliveries = {}, - train_class = TRAIN_CLASS_AUTO, + is_all = control.second_constant == 1, accepted_layouts = {}, layout_pattern = nil, } @@ -113,7 +113,7 @@ local function search_for_station_combinator(map_data, stop, comb_operation, com entity.valid and entity.name == COMBINATOR_NAME and entity ~= comb_forbidden and map_data.to_stop[entity.unit_number] == stop then - local control = entity.get_or_create_control_behavior().parameters + local control = entity.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] if control.operation == comb_operation then return entity end @@ -174,7 +174,7 @@ local function on_combinator_built(map_data, comb) map_data.to_output[comb.unit_number] = out map_data.to_stop[comb.unit_number] = stop - local a = comb.get_or_create_control_behavior() + local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]] local control = a.parameters if control.operation == OPERATION_DEFAULT then control.operation = OPERATION_PRIMARY_IO @@ -193,7 +193,7 @@ local function on_combinator_built(map_data, comb) if depot or station then --NOTE: repeated combinators are ignored else - on_depot_built(map_data, stop, comb, control.first_signal) + on_depot_built(map_data, stop, comb, control) end end elseif control.operation == OPERATION_SECONDARY_IO then @@ -219,7 +219,7 @@ local function on_combinator_built(map_data, comb) local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) - on_station_built(map_data, stop, comb, comb2, control.first_signal) + on_station_built(map_data, stop, comb, comb2, control) end end end @@ -256,13 +256,13 @@ local function on_combinator_broken(map_data, comb) local comb1 = search_for_station_combinator(map_data, stop, OPERATION_PRIMARY_IO, comb) if comb1 then station.entity_comb1 = comb1 - local control = comb1.get_or_create_control_behavior().parameters - station.network_name = control.first_signal + local control = comb1.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] + station.network_name = control.first_signal and control.first_signal.name else on_station_broken(map_data, stop.unit_number, station) local depot_comb = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb) if depot_comb then - local control = depot_comb.get_or_create_control_behavior().parameters + local control = depot_comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] on_depot_built(map_data, stop, depot_comb, control.first_signal) end end @@ -275,9 +275,9 @@ local function on_combinator_broken(map_data, comb) --NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way local depot_comb = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb) if depot_comb then - local control = depot_comb.get_or_create_control_behavior().parameters + local control = depot_comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] depot.entity_comb = depot_comb - depot.network_name = control.first_signal + depot.network_name = control.first_signal and control.first_signal.name else map_data.depots[stop.unit_number] = nil end @@ -317,7 +317,7 @@ local function on_stop_built(map_data, stop) for _, entity in pairs(entities) do if entity.valid and entity.name == COMBINATOR_NAME and map_data.to_stop[entity.unit_number] == nil then map_data.to_stop[entity.unit_number] = stop - local control = entity.get_or_create_control_behavior().parameters + local control = entity.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] if control.operation == OPERATION_PRIMARY_IO then comb1 = entity elseif control.operation == OPERATION_SECONDARY_IO then @@ -328,11 +328,9 @@ local function on_stop_built(map_data, stop) end end if comb1 then - local control = comb1.get_or_create_control_behavior().parameters - on_station_built(map_data, stop, comb1, comb2, control.first_signal) + on_station_built(map_data, stop, comb1, comb2, comb1.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]) elseif depot_comb then - local control = depot_comb.get_or_create_control_behavior().parameters - on_depot_built(map_data, stop, depot_comb, control.first_signal) + on_depot_built(map_data, stop, depot_comb, depot_comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]) end end ---@param map_data MapData