From dd948b0f178018a7c4f3cee2865afd00a276106b Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Fri, 25 Nov 2022 00:27:44 -0500 Subject: [PATCH] fixed layout pattern logic --- TODO | 3 -- cybersyn/changelog.txt | 5 +++ cybersyn/info.json | 2 +- cybersyn/scripts/global.lua | 4 +- cybersyn/scripts/layout.lua | 77 +++++++++++++++++++-------------- cybersyn/scripts/main.lua | 12 ++++- cybersyn/scripts/migrations.lua | 22 ++++++++++ 7 files changed, 86 insertions(+), 39 deletions(-) diff --git a/TODO b/TODO index 1cb3fbb..52bf5a6 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,3 @@ models & art space elevator compat railloader compat major bug with copy-paste when the operation is changed by blueprint but it gets copied to the old settings before it's checked for update -catch inserter rotation -trains of capacity greater than the stations current contents can be dispatched - diff --git a/cybersyn/changelog.txt b/cybersyn/changelog.txt index d6e64db..58affb5 100644 --- a/cybersyn/changelog.txt +++ b/cybersyn/changelog.txt @@ -42,4 +42,9 @@ Date: 2022-11-24 - Added a stuck train alert - Improved localization - Fixed bug with fluid cargo not being detected by depots + +--------------------------------------------------------------------------------------------------- +Version: 0.4.4 +Date: 2022-11-25 + Features: - Greatly improved automatic train blacklist logic diff --git a/cybersyn/info.json b/cybersyn/info.json index 7274d32..88b9ef8 100644 --- a/cybersyn/info.json +++ b/cybersyn/info.json @@ -1,6 +1,6 @@ { "name": "cybersyn", - "version": "0.4.3", + "version": "0.4.4", "title": "Project Cybersyn", "author": "Mami", "factorio_version": "1.1", diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index a97228d..f6e072c 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -13,7 +13,7 @@ ---@field public depots {[uint]: Depot} ---@field public trains {[uint]: Train} ---@field public available_trains {[string]: {[uint]: uint}} --{[network_name]: {[train_id]: depot_id}} ----@field public layouts {[uint]: string} +---@field public layouts {[uint]: int[]} ---@field public layout_train_count {[uint]: int} ---@field public tick_state uint ---@field public tick_data {} @@ -36,7 +36,7 @@ ---@field public network_name string? ---@field public network_flag int --transient ---@field public accepted_layouts TrainClass ----@field public layout_pattern string? +---@field public layout_pattern {[uint]: int} ---@field public tick_signals {[uint]: Signal}? --transient ---@field public p_count_or_r_threshold_per_item {[string]: int} --transient ---@field public display_failed_request true? diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index e418754..18b3301 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -5,6 +5,7 @@ local floor = math.floor local ceil = math.ceil local string_find = string.find local string_sub = string.sub +local table_compare = table.compare local function iterr(a, i) i = i + 1 @@ -18,6 +19,26 @@ local function irpairs(a) end +local function is_layout_accepted(layout_pattern, layout) + local valid = true + for i, v in ipairs(layout) do + local p = layout_pattern[i] or 0 + if (v == 0 and p == 2) or (v == 1 and (p == 0 or p == 2)) or (v == 2 and (p == 0 or p == 1)) then + valid = false + break + end + end + if valid or not layout[0] then return valid end + for i, v in irpairs(layout) do + local p = layout_pattern[i] or 0 + if (v == 0 and p == 2) or (v == 1 and (p == 0 or p == 2)) or (v == 2 and (p == 0 or p == 1)) then + valid = false + break + end + end + return valid +end + ---@param map_data MapData ---@param train Train ---@param train_id uint @@ -40,32 +61,37 @@ function remove_train(map_data, train, train_id) map_data.trains[train_id] = nil end + ---@param map_data MapData ---@param train Train function update_train_layout(map_data, train) local carriages = train.entity.carriages - local layout = "" + local layout = {} local i = 1 local item_slot_capacity = 0 local fluid_capacity = 0 for _, carriage in pairs(carriages) do if carriage.type == "cargo-wagon" then - layout = layout..TRAIN_LAYOUT_CARGO + layout[#layout + 1] = 1 local inv = carriage.get_inventory(defines.inventory.cargo_wagon) item_slot_capacity = item_slot_capacity + #inv elseif carriage.type == "fluid-wagon" then - layout = layout..TRAIN_LAYOUT_FLUID + layout[#layout + 1] = 2 fluid_capacity = fluid_capacity + carriage.prototype.fluid_capacity - --elseif carriage.type == "artillery-wagon" then - --layout = layout..TRAIN_LAYOUT_ARTILLERY else - layout = layout..TRAIN_LAYOUT_NA + layout[#layout + 1] = 0 end i = i + 1 end + local back_movers = train.entity.locomotives["back_movers"] + if back_movers and #back_movers > 0 then + --mark the layout as reversible + layout[0] = true + end + local layout_id = 0 for id, cur_layout in pairs(map_data.layouts) do - if layout == cur_layout then + if table_compare(layout, cur_layout) then layout = cur_layout layout_id = id break @@ -79,8 +105,8 @@ function update_train_layout(map_data, train) map_data.layouts[layout_id] = layout map_data.layout_train_count[layout_id] = 1 for _, station in pairs(map_data.stations) do - if station.layout_pattern and string.find(layout, station.layout_pattern) ~= nil then - station.accepted_layouts[layout_id] = true + if station.layout_pattern then + station.accepted_layouts[layout_id] = is_layout_accepted(station.layout_pattern, layout) or nil end end else @@ -298,12 +324,12 @@ end ---@param map_data MapData ---@param station Station ---@param forbidden_entity LuaEntity? -local function reset_station_layout(map_data, station, forbidden_entity) +function reset_station_layout(map_data, station, forbidden_entity) --NOTE: station must be in auto mode local station_rail = station.entity_stop.connected_rail if station_rail == nil then --cannot accept deliveries - station.layout_pattern = "X" + station.layout_pattern = nil station.accepted_layouts = {} return end @@ -347,12 +373,10 @@ local function reset_station_layout(map_data, station, forbidden_entity) end local length = 2 local pre_rail = station_rail - local layout_pattern = "^" + local layout_pattern = {0} local type_filter = {"inserter", "pump", "arithmetic-combinator"} local wagon_number = 0 - local pattern_length = 1 - local is_break = false - for i = 1, 100 do + for i = 1, 112 do local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_station, 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 is_break = true @@ -421,32 +445,21 @@ local function reset_station_layout(map_data, station, forbidden_entity) if supports_cargo then if supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_ALL + layout_pattern[wagon_number] = 3 else - layout_pattern = layout_pattern..STATION_LAYOUT_NOT_FLUID + layout_pattern[wagon_number] = 2 end - pattern_length = #layout_pattern elseif supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_NOT_CARGO - pattern_length = #layout_pattern + layout_pattern[wagon_number] = 1 else - layout_pattern = layout_pattern..STATION_LAYOUT_NA + --layout_pattern[wagon_number] = nil end search_area = area.move(search_area, area_delta) end end - layout_pattern = string_sub(layout_pattern, 1, pattern_length) - if is_break then - layout_pattern = layout_pattern..STATION_LAYOUT_NA.."*$" - end station.layout_pattern = layout_pattern - local accepted_layouts = station.accepted_layouts for id, layout in pairs(map_data.layouts) do - if string_find(layout, layout_pattern) ~= nil then - accepted_layouts[id] = true - else - accepted_layouts[id] = nil - end + station.accepted_layouts[id] = is_layout_accepted(layout_pattern, layout) or nil end end @@ -472,7 +485,7 @@ function update_station_from_rail(map_data, rail, forbidden_entity, force) rail_direction = defines.rail_direction.front entity = rail.get_rail_segment_entity(rail_direction, false) end - for i = 1, 100 do + for i = 1, 112 do if not entity or not entity.valid then return end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index 2c6f0f2..5dd5873 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -710,7 +710,7 @@ end local function on_built(event) - local entity = event.entity or event.created_entity or event.destination + local entity = event.entity or event.created_entity if not entity or not entity.valid then return end if entity.name == "train-stop" then @@ -746,6 +746,14 @@ local function on_broken(event) end end end +local function on_rotate(event) + local entity = event.entity or event.created_entity + if not entity or not entity.valid then return end + + if entity.type == "inserter" then + update_station_from_inserter(global, entity) + end +end local function on_rename(event) if event.entity.name == "train-stop" then on_station_rename(global, event.entity) @@ -878,6 +886,8 @@ local function main() flib_event.register(defines.events.on_robot_built_entity, on_built, filter_built) flib_event.register({defines.events.script_raised_built, defines.events.script_raised_revive, defines.events.on_entity_cloned}, on_built) + flib_event.register(defines.events.on_player_rotated_entity, on_rotate) + flib_event.register(defines.events.on_pre_player_mined_item, on_broken, filter_broken) flib_event.register(defines.events.on_robot_pre_mined, on_broken, filter_broken) flib_event.register(defines.events.on_entity_died, on_broken, filter_broken) diff --git a/cybersyn/scripts/migrations.lua b/cybersyn/scripts/migrations.lua index 32caeff..8c1cbd4 100644 --- a/cybersyn/scripts/migrations.lua +++ b/cybersyn/scripts/migrations.lua @@ -88,6 +88,28 @@ local migrations_table = { end mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as int]] end, + ["0.4.4"] = function() + ---@type MapData + local map_data = global + map_data.tick_state = STATE_INIT + for id, layout in pairs(map_data.layouts) do + local new_layout = {} + local i = 1 + for c in string.gmatch(layout, ".") do + if c == "N" then + elseif c == "C" then + new_layout[i] = 1 + elseif c == "F" then + new_layout[i] = 2 + end + i = i + 1 + end + map_data.layouts[id] = new_layout + end + for id, station in pairs(map_data.stations) do + reset_station_layout(map_data, station) + end + end, } ---@param data ConfigurationChangedData