From 50bfc20b084c120278f3e941e7564e3004720119 Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Sun, 30 Oct 2022 19:21:11 -0400 Subject: [PATCH] implemented networks --- cybersyn/scripts/central-planning.lua | 81 +++++++++++----------- cybersyn/scripts/constants.lua | 10 +-- cybersyn/scripts/global.lua | 15 ++-- cybersyn/scripts/gui.lua | 26 +++++-- cybersyn/scripts/main.lua | 98 +++++++++++++++++++++------ 5 files changed, 153 insertions(+), 77 deletions(-) diff --git a/cybersyn/scripts/central-planning.lua b/cybersyn/scripts/central-planning.lua index 628b146..34cecb8 100644 --- a/cybersyn/scripts/central-planning.lua +++ b/cybersyn/scripts/central-planning.lua @@ -247,41 +247,38 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p local requests = {} local manifest = {} - local r_signals = get_signals(r_station) + local r_signals = r_station.tick_signals if r_signals then for k, v in pairs(r_signals) do + ---@type string local item_name = v.signal.name local item_count = v.count - local item_type = v.signal.type - if item_name and item_type and item_type ~= "virtual" then - local effective_item_count = item_count + (r_station.deliveries[item_name] or 0) - local r_threshold, p_threshold = get_thresholds(map_data, r_station, v.signal) - if -effective_item_count >= r_threshold then - requests[item_name] = -effective_item_count - end + --local item_type = v.signal.type + local effective_item_count = item_count + (r_station.deliveries[item_name] or 0) + local r_threshold, p_threshold = get_thresholds(map_data, r_station, v.signal) + if -effective_item_count >= r_threshold then + requests[item_name] = -effective_item_count end end end - local p_signals = get_signals(p_station) + local p_signals = p_station.tick_signals if p_signals then for k, v in pairs(p_signals) do local item_name = v.signal.name local item_count = v.count local item_type = v.signal.type - if item_name and item_type and item_type ~= "virtual" then - local effective_item_count = item_count + (p_station.deliveries[item_name] or 0) - local r_threshold, p_threshold = get_thresholds(map_data, p_station, v.signal) - if effective_item_count >= p_threshold then - local r = requests[item_name] - if r then - local item = {name = item_name, count = math.min(r, effective_item_count), type = item_type} - if item_name == primary_item_name then - manifest[#manifest + 1] = manifest[1] - manifest[1] = item - else - manifest[#manifest + 1] = item - end + local effective_item_count = item_count + (p_station.deliveries[item_name] or 0) + local r_threshold, p_threshold = get_thresholds(map_data, p_station, v.signal) + if effective_item_count >= p_threshold then + local r = requests[item_name] + if r then + local item = {name = item_name, type = item_type, count = math.min(r, effective_item_count)} + if item_name == primary_item_name then + manifest[#manifest + 1] = manifest[1] + manifest[1] = item + else + manifest[#manifest + 1] = item end end end @@ -390,6 +387,7 @@ function tick(map_data, mod_settings) station.locked_slots = 0 station.network_flag = 1 local signals = get_signals(station) + station.tick_signals = signals if signals then for k, v in pairs(signals) do local item_name = v.signal.name @@ -421,26 +419,24 @@ function tick(map_data, mod_settings) local effective_item_count = item_count + (station.deliveries[item_name] or 0) local r_threshold, p_threshold = get_thresholds(map_data, station, v.signal) - if item_name then - if -effective_item_count >= r_threshold then - local item_network_name = item_name + ":" + station.network_name - if r_stations_all[item_network_name] == nil then - r_stations_all[item_network_name] = {} - p_stations_all[item_network_name] = {} - all_names[#all_names + 1] = item_network_name - all_names[#all_names + 1] = v.signal - end - table.insert(r_stations_all[item_name], station_id) - elseif effective_item_count >= p_threshold then - local item_network_name = item_name + ":" + station.network_name - if r_stations_all[item_network_name] == nil then - r_stations_all[item_network_name] = {} - p_stations_all[item_network_name] = {} - all_names[#all_names + 1] = item_network_name - all_names[#all_names + 1] = v.signal - end - table.insert(p_stations_all[item_name], station_id) + if -effective_item_count >= r_threshold then + local item_network_name = item_name + ":" + station.network_name + if r_stations_all[item_network_name] == nil then + r_stations_all[item_network_name] = {} + p_stations_all[item_network_name] = {} + all_names[#all_names + 1] = item_network_name + all_names[#all_names + 1] = v.signal end + table.insert(r_stations_all[item_name], station_id) + elseif effective_item_count >= p_threshold then + local item_network_name = item_name + ":" + station.network_name + if r_stations_all[item_network_name] == nil then + r_stations_all[item_network_name] = {} + p_stations_all[item_network_name] = {} + all_names[#all_names + 1] = item_network_name + all_names[#all_names + 1] = v.signal + end + table.insert(p_stations_all[item_name], station_id) end end end @@ -529,4 +525,7 @@ function tick(map_data, mod_settings) end end end + for station_id, station in pairs(stations) do + station.tick_signals = nil + end end diff --git a/cybersyn/scripts/constants.lua b/cybersyn/scripts/constants.lua index 5bd4ca6..5012d5c 100644 --- a/cybersyn/scripts/constants.lua +++ b/cybersyn/scripts/constants.lua @@ -12,11 +12,14 @@ LOCKED_SLOTS = "cybersyn-locked-slots" COMBINATOR_NAME = "cybersyn-combinator" COMBINATOR_OUT_NAME = "cybersyn-combinator-output" -OPERATION_PRIMARY_IO = "*" -OPERATION_SECONDARY_IO = "/" +OPERATION_DEFAULT = "*" +OPERATION_PRIMARY_IO = "/" +OPERATION_SECONDARY_IO = "%" OPERATION_DEPOT = "+" OPERATION_WAGON_MANIFEST = "-" +NETWORK_SIGNAL_DEFAULT = {name="signal-A", type="virtual"} + DELTA = 1/2048 DEPOT_PRIORITY_MULT = 2048 @@ -38,6 +41,3 @@ STATION_LAYOUT_NOT_FLUID = "[NC]" STATION_LAYOUT_NOT_CARGO = "[NF]" LONGEST_INSERTER_REACH = 2 - -TRAIN_CLASS_ALL = {name = "all", type = "virtual"} -TRAIN_CLASS_AUTO = {name = "auto", type = "virtual"} diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index e4f70d6..cc32185 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -15,28 +15,29 @@ ---@class Station ---@field public deliveries_total int ----@field public priority int ---@field public last_delivery_tick int ----@field public r_threshold int >= 0 ----@field public p_threshold int >= 0 ----@field public locked_slots int >= 0 +---@field public priority int --transient +---@field public r_threshold int >= 0 --transient +---@field public p_threshold int >= 0 --transient +---@field public locked_slots int >= 0 --transient ---@field public entity_stop LuaEntity ---@field public entity_comb1 LuaEntity ---@field public entity_comb2 LuaEntity? ---@field public wagon_combs {[int]: LuaEntity}?--NOTE: allowed to be invalid entities or combinators with the wrong operation, these must be checked and lazy deleted when found ---@field public deliveries {[string]: int} ---@field public network_name string? ----@field public network_flag int +---@field public network_flag int --transient ---@field public train_class SignalID? ---@field public accepted_layouts TrainClass ---@field public layout_pattern string? +---@field public tick_signals Signal[]? --transient ---@class Depot ----@field public priority int +---@field public priority int --transient ---@field public entity_stop LuaEntity ---@field public entity_comb LuaEntity ---@field public network_name string? ----@field public network_flag int +---@field public network_flag int --transient ---@class Train ---@field public entity LuaTrain diff --git a/cybersyn/scripts/gui.lua b/cybersyn/scripts/gui.lua index c2f950a..6401114 100644 --- a/cybersyn/scripts/gui.lua +++ b/cybersyn/scripts/gui.lua @@ -75,8 +75,8 @@ function gui_opened(comb, player) }}, ---choose-elem-button {type="line", style_mods={top_padding=10}}, - {type="label", style="heading_3_label", caption={"cybersyn-gui.network"}, style_mods={top_padding=7}}, - {type="choose-elem-button", style="slot_button_in_shallow_frame", ref={"network"}, elem_type="signal", signal=control.first_signal, style_mods={bottom_margin=2}, actions={ + {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={ on_elem_changed={"choose-elem-button", comb.unit_number} }}, }} @@ -87,6 +87,7 @@ function gui_opened(comb, player) 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 player.opened = window.main_window end @@ -131,19 +132,29 @@ 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 control = a.parameters if element.selected_index == 1 then control.operation = OPERATION_PRIMARY_IO + parent["network"].visible = true + parent["network_label"].visible = true elseif element.selected_index == 2 then control.operation = OPERATION_SECONDARY_IO + parent["network"].visible = false + parent["network_label"].visible = false elseif element.selected_index == 3 then control.operation = OPERATION_DEPOT + parent["network"].visible = true + parent["network_label"].visible = true elseif element.selected_index == 4 then control.operation = OPERATION_WAGON_MANIFEST + parent["network"].visible = false + parent["network_label"].visible = false else return end + a.parameters = control on_combinator_updated(global, comb) elseif msg[1] == "choose-elem-button" then @@ -152,14 +163,19 @@ function register_gui_actions() local comb = global.to_comb[msg[2]] if not comb or not comb.valid then return end - local signal = element.elem_value - local a = comb.get_or_create_control_behavior() local control = a.parameters - control.first_signal = signal + local signal = element.elem_value + if signal and (signal.name == "signal-everything" or signal.name == "signal-anything" or signal.name == "signal-each") then + control.first_signal = nil + element.elem_value = nil + else + control.first_signal = signal + end a.parameters = control + on_combinator_network_updated(global, comb, signal and signal.name or nil) end end end) diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index b00198b..d41ee40 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -26,11 +26,27 @@ local function on_failed_delivery(map_data, train) train.manifest = nil end + +---@param map_data MapData +---@param stop LuaEntity +---@param comb LuaEntity +local function on_depot_built(map_data, stop, comb, network_name) + local depot = { + entity_stop = stop, + entity_comb = comb, + network_name = network_name, + priority = 0, + network_flag = 0, + } + map_data.depots[stop.unit_number] = depot +end + ---@param map_data MapData ---@param stop LuaEntity ---@param comb1 LuaEntity ---@param comb2 LuaEntity -local function on_station_built(map_data, stop, comb1, comb2) +---@param network_name string +local function on_station_built(map_data, stop, comb1, comb2, network_name) local station = { entity_stop = stop, entity_comb1 = comb1, @@ -42,6 +58,8 @@ local function on_station_built(map_data, stop, comb1, comb2) r_threshold = 0, p_threshold = 0, locked_slots = 0, + network_name = network_name, + network_flag = 0, deliveries = {}, train_class = TRAIN_CLASS_AUTO, accepted_layouts = {}, @@ -156,7 +174,13 @@ 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 control = comb.get_or_create_control_behavior().parameters + local a = comb.get_or_create_control_behavior() + local control = a.parameters + if control.operation == OPERATION_DEFAULT then + control.operation = OPERATION_PRIMARY_IO + control.first_signal = NETWORK_SIGNAL_DEFAULT + a.parameters = control + end if control.operation == OPERATION_WAGON_MANIFEST then if rail then update_station_from_rail(map_data, rail, nil) @@ -164,11 +188,12 @@ local function on_combinator_built(map_data, comb) elseif control.operation == OPERATION_DEPOT then if stop then local station = map_data.stations[stop.unit_number] - local depot_comb = map_data.depots[stop.unit_number] - if depot_comb or station then + ---@type Depot + local depot = map_data.depots[stop.unit_number] + if depot or station then --NOTE: repeated combinators are ignored else - map_data.depots[stop.unit_number] = comb + on_depot_built(map_data, stop, comb, control.first_signal) end end elseif control.operation == OPERATION_SECONDARY_IO then @@ -181,11 +206,11 @@ local function on_combinator_built(map_data, comb) elseif stop then control.operation = OPERATION_PRIMARY_IO local station = map_data.stations[stop.unit_number] - local depot_comb = map_data.depots[stop.unit_number] + local depot = map_data.depots[stop.unit_number] if station then --NOTE: repeated combinators are ignored else - if depot_comb then + if depot then --NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way map_data.depots[stop.unit_number] = nil end @@ -194,7 +219,26 @@ 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) + on_station_built(map_data, stop, comb, comb2, control.first_signal) + end + end +end +---@param map_data MapData +---@param comb LuaEntity +function on_combinator_network_updated(map_data, comb, network_name) + local stop = map_data.to_stop[comb.unit_number] + + if stop and stop.valid then + local station = map_data.stations[stop.unit_number] + if station then + if station.entity_comb1 == comb then + station.network_name = network_name + end + else + local depot = map_data.depots[stop.unit_number] + if depot.entity_comb == comb then + depot.network_name = network_name + end end end end @@ -212,18 +256,31 @@ 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 else on_station_broken(map_data, stop.unit_number, station) - map_data.depots[stop.unit_number] = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb) + 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 + on_depot_built(map_data, stop, depot_comb, control.first_signal) + end end elseif station.entity_comb2 == comb then station.entity_comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) end else - local depot_comb = map_data.depots[stop.unit_number] - if depot_comb == comb then + local depot = map_data.depots[stop.unit_number] + if depot.entity_comb == comb then --NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way - map_data.depots[stop.unit_number] = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb) + 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 + depot.entity_comb = depot_comb + depot.network_name = control.first_signal + else + map_data.depots[stop.unit_number] = nil + end end end end @@ -272,9 +329,11 @@ local function on_stop_built(map_data, stop) end end if comb1 then - on_station_built(map_data, stop, comb1, comb2) + local control = comb1.get_or_create_control_behavior().parameters + on_station_built(map_data, stop, comb1, comb2, control.first_signal) elseif depot_comb then - map_data.depots[stop.unit_number] = depot_comb + local control = depot_comb.get_or_create_control_behavior().parameters + on_depot_built(map_data, stop, depot_comb, control.first_signal) end end ---@param map_data MapData @@ -342,8 +401,9 @@ end ---@param map_data MapData +---@param stop LuaEntity ---@param train_entity LuaTrain -local function on_train_arrives_depot(map_data, train_entity) +local function on_train_arrives_depot(map_data, stop, train_entity) local contents = train_entity.get_contents() local train = map_data.trains[train_entity.id] if train then @@ -354,7 +414,7 @@ local function on_train_arrives_depot(map_data, train_entity) train.manifest = nil train.depot_name = train_entity.station.backer_name train.status = STATUS_D - map_data.trains_available[][train_entity.id] = true + map_data.trains_available[stop.unit_number] = train_entity.id else if train.manifest then on_failed_delivery(map_data, train) @@ -362,7 +422,7 @@ local function on_train_arrives_depot(map_data, train_entity) end train.depot_name = train_entity.station.backer_name train.status = STATUS_D - map_data.trains_available[train_entity.id] = true + map_data.trains_available[stop.unit_number] = train_entity.id end if next(contents) ~= nil then --train still has cargo @@ -386,7 +446,7 @@ local function on_train_arrives_depot(map_data, train_entity) } update_train_layout(map_data, train) map_data.trains[train_entity.id] = train - map_data.trains_available[train_entity.id] = true + map_data.trains_available[stop.unit_number] = train_entity.id local schedule = create_depot_schedule(train.depot_name) train_entity.schedule = schedule else @@ -552,7 +612,7 @@ local function on_train_changed(event) if global.stations[stop.unit_number] then on_train_arrives_buffer(global, stop, train) elseif global.depots[stop.unit_number] then - on_train_arrives_depot(global, train_e) + on_train_arrives_depot(global, stop, train_e) end end elseif event.old_state == defines.train_state.wait_station then