From 7e502cf4f77b340683535e7283f46b602c269b41 Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Wed, 26 Oct 2022 15:53:33 -0400 Subject: [PATCH] fixed automatic train layout detection --- .../{locked_slots.png => locked-slots.png} | Bin cybersyn/graphics/icons/lost-train.png | Bin 0 -> 2532 bytes cybersyn/graphics/icons/missing-train.png | Bin 0 -> 2532 bytes cybersyn/graphics/icons/nonempty-train.png | Bin 0 -> 2532 bytes cybersyn/prototypes/signal.lua | 2 +- cybersyn/scripts/constants.lua | 11 +- cybersyn/scripts/controller.lua | 3 +- cybersyn/scripts/global.lua | 5 +- cybersyn/scripts/layout.lua | 161 ++++++++++++------ cybersyn/scripts/main.lua | 77 ++++----- 10 files changed, 157 insertions(+), 102 deletions(-) rename cybersyn/graphics/icons/{locked_slots.png => locked-slots.png} (100%) create mode 100644 cybersyn/graphics/icons/lost-train.png create mode 100644 cybersyn/graphics/icons/missing-train.png create mode 100644 cybersyn/graphics/icons/nonempty-train.png diff --git a/cybersyn/graphics/icons/locked_slots.png b/cybersyn/graphics/icons/locked-slots.png similarity index 100% rename from cybersyn/graphics/icons/locked_slots.png rename to cybersyn/graphics/icons/locked-slots.png diff --git a/cybersyn/graphics/icons/lost-train.png b/cybersyn/graphics/icons/lost-train.png new file mode 100644 index 0000000000000000000000000000000000000000..3f4233236012a0c3d07b99909145f407a013676f GIT binary patch literal 2532 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 r_threshold then if r_stations_all[item_name] == nil then diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index d7429e2..449030a 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -22,9 +22,9 @@ ---@field public entity_stop LuaEntity ---@field public entity_comb1 LuaEntity ---@field public entity_comb2 LuaEntity? ----@field public wagon_combs {[int]: LuaEntity}?--allowed to be invalid entities +---@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 train_class string +---@field public train_class SignalID? ---@field public accepted_layouts TrainClass ---@field public layout_pattern string? @@ -57,6 +57,7 @@ mod_settings.p_threshold = settings.global["cybersyn-provide-threshold"].value global.total_ticks = 0 global.to_output = {} +global.to_stop = {} global.stations = {} global.depots = {} global.trains = {} diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index b3d7a2a..ecc5cc5 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -75,8 +75,16 @@ end ---@param map_data MapData ---@param station Station -local function reset_station_layout(map_data, station) +---@param forbidden_entity LuaEntity? +local 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.accepted_layouts = {} + return + end local rail_direction_from_station if station.entity_stop.connected_rail_direction == defines.rail_direction.front then rail_direction_from_station = defines.rail_direction.back @@ -87,26 +95,32 @@ local function reset_station_layout(map_data, station) local surface = station.entity_stop.surface local middle_x = station_rail.position.x local middle_y = station_rail.position.y - local reach = LONGEST_INSERTER_REACH + 1 - DELTA + local reach = LONGEST_INSERTER_REACH + 1 local search_area 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} - direction_filter = {defines.direction.east, defines.direction.west} - elseif station_direction == defines.direction.east then - search_area = {left_top = {y = middle_y - reach, x = middle_x}, right_bottom = {y = middle_y + reach, x = middle_x - 6}} - area_delta = {y = 0, x = -7} - direction_filter = {defines.direction.north, defines.direction.south} - elseif station_direction == defines.direction.south then - search_area = {left_top = {x = middle_x - reach, y = middle_y + 6}, right_bottom = {x = middle_x + reach, y = middle_y}} + 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} direction_filter = {defines.direction.east, defines.direction.west} + is_ver = true + elseif station_direction == defines.direction.east then + search_area = {left_top = {y = middle_y - reach, x = middle_x}, right_bottom = {y = middle_y + reach, x = middle_x - 6}} + area_delta = {x = -7, y = 0} + direction_filter = {defines.direction.north, defines.direction.south} + is_ver = false + elseif station_direction == defines.direction.south then + search_area = {left_top = {x = middle_x - reach, y = middle_y - 6}, right_bottom = {x = middle_x + reach, y = middle_y}} + area_delta = {x = 0, y = -7} + direction_filter = {defines.direction.east, defines.direction.west} + is_ver = true elseif station_direction == defines.direction.west then search_area = {left_top = {y = middle_y - reach, x = middle_x + 6}, right_bottom = {y = middle_y + reach, x = middle_x}} - area_delta = {y = 0, x = 7} + area_delta = {x = 7, y = 0} direction_filter = {defines.direction.north, defines.direction.south} + is_ver = false else assert(false, "cybersyn: invalid station direction") end @@ -114,14 +128,17 @@ local function reset_station_layout(map_data, station) local pre_rail = station_rail local layout_pattern = "^" local layout_min_size = 10000 - local type_filter = {"inserter", "pump"} + local type_filter = {"inserter", "pump", "arithmetic-combinator"} + local wagon_number = 0 for i = 1, 100 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 rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then + if not rail or rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then break end + pre_rail = rail length = length + 2 if length%7 <= 1 then + wagon_number = wagon_number + 1 local supports_cargo = false local supports_fluid = false local entities = surface.find_entities_filtered({ @@ -130,26 +147,64 @@ local function reset_station_layout(map_data, station) direction = direction_filter, }) for _, entity in pairs(entities) do - if entity.type == "inserter" then - --local pickup_pos = entity.prototype.inserter_pickup_position + entity.position - --local drop_pos = entity.prototype.inserter_drop_position + entity.position - --TODO: add further checks - supports_cargo = true - elseif entity.type == "pump" then - if entity.pump_rail_target then - supports_fluid = true + if entity.valid and entity ~= forbidden_entity then + if entity.type == "inserter" then + if not supports_cargo then + local pos = entity.pickup_position + local is_there + if is_ver then + is_there = middle_x - 1 <= pos.x and pos.x <= middle_x + 1 + else + is_there = middle_y - 1 <= pos.y and pos.y <= middle_y + 1 + end + if is_there then + supports_cargo = true + else + pos = entity.drop_position + if is_ver then + is_there = middle_x - 1 <= pos.x and pos.x <= middle_x + 1 + else + is_there = middle_y - 1 <= pos.y and pos.y <= middle_y + 1 + end + if is_there then + supports_cargo = true + end + end + end + elseif entity.type == "pump" then + if not supports_fluid and entity.pump_rail_target then + supports_fluid = true + end + elseif entity.name == COMBINATOR_NAME then + local control = entity.get_or_create_control_behavior().parameters + if control.operation == OPERATION_WAGON_MANIFEST then + local pos = entity.position + local is_there + if is_ver then + is_there = middle_x - 2.1 <= pos.x and pos.x <= middle_x + 2.1 + else + is_there = middle_y - 2.1 <= pos.y and pos.y <= middle_y + 2.1 + end + if is_there then + if not station.wagon_combs then + station.wagon_combs = {} + end + station.wagon_combs[wagon_number] = entity + end + end end end end if supports_cargo then if supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_BOTH + layout_pattern = layout_pattern..STATION_LAYOUT_ALL else - layout_pattern = layout_pattern..STATION_LAYOUT_CARGO + --TODO: needs to allow misc wagons as well + layout_pattern = layout_pattern..STATION_LAYOUT_NOT_FLUID end elseif supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_FLUID + layout_pattern = layout_pattern..STATION_LAYOUT_NOT_CARGO else layout_pattern = layout_pattern..STATION_LAYOUT_NA end @@ -175,17 +230,17 @@ end ---@param map_data MapData ---@param station Station ----@param train_class_name string -function set_station_train_class(map_data, station, train_class_name) - if train_class_name == TRAIN_CLASS_AUTO then - if station.train_class ~= TRAIN_CLASS_AUTO then +---@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 = {} end - reset_station_layout(map_data, station) + reset_station_layout(map_data, station, nil) else - station.train_class = train_class_name - station.accepted_layouts = map_data.train_classes[train_class_name] + 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 @@ -193,26 +248,39 @@ end ---@param map_data MapData ---@param station Station -function update_station_if_auto(map_data, station) - if station.train_class == TRAIN_CLASS_AUTO then - reset_station_layout(map_data, 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 + reset_station_layout(map_data, station, forbidden_entity) end end ---@param map_data MapData ---@param rail LuaEntity -function update_station_from_rail(map_data, rail) - --TODO: search further? - local entity = rail.get_rail_segment_entity(nil, false) - if entity.name == BUFFER_STATION_NAME then - update_station_if_auto(map_data, map_data.stations[entity.unit_number]) +---@param forbidden_entity LuaEntity +function update_station_from_rail(map_data, rail, forbidden_entity) + --TODO: search further or better? + local entity = rail.get_rail_segment_entity(defines.rail_direction.back, false) + if entity and entity.valid and entity.name == "train-stop" then + local station = map_data.stations[entity.unit_number] + if station then + update_station_if_auto(map_data, station, forbidden_entity) + end + else + entity = rail.get_rail_segment_entity(defines.rail_direction.front, false) + if entity and entity.valid and entity.name == "train-stop" then + local station = map_data.stations[entity.unit_number] + if station then + update_station_if_auto(map_data, station, forbidden_entity) + end + end end end ---@param map_data MapData ---@param pump LuaEntity function update_station_from_pump(map_data, pump) if pump.pump_rail_target then - update_station_from_rail(map_data, pump.pump_rail_target) + update_station_from_rail(map_data, pump.pump_rail_target, pump) end end ---@param map_data MapData @@ -220,16 +288,13 @@ end function update_station_from_inserter(map_data, inserter) --TODO: check if correct local surface = inserter.surface - local pos = inserter.position - local pickup_pos = inserter.prototype.inserter_pickup_position - local drop_pos = inserter.prototype.inserter_drop_position - local rail = surface.find_entity("straight-rail", {pos.x + pickup_pos.x, pos.y + pickup_pos.y}) + local rail = surface.find_entity("straight-rail", inserter.pickup_position) if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, inserter) end - rail = surface.find_entity("straight-rail", {pos.x + drop_pos.x, pos.y + drop_pos.y}) + rail = surface.find_entity("straight-rail", inserter.drop_position) if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, inserter) end end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index 7e717be..e311246 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -48,7 +48,7 @@ local function on_station_built(map_data, stop, comb1, comb2) } map_data.stations[stop.unit_number] = station - update_station_if_auto(map_data, station) + update_station_if_auto(map_data, station, nil) end ---@param map_data MapData ---@param station_id uint @@ -84,8 +84,8 @@ local function search_for_station_combinator(map_data, stop, comb_operation, com local pos_y = stop.position.y --TODO: fix search area local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} } local entities = stop.surface.find_entities(search_area) for _, entity in pairs(entities) do @@ -108,13 +108,21 @@ local function on_combinator_built(map_data, comb) local pos_y = comb.position.y --TODO: fix search area - local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} - } + local search_area + if comb.direction == defines.direction.north or comb.direction == defines.direction.south then + search_area = { + {pos_x - 1.5, pos_y - 2}, + {pos_x + 1.5, pos_y + 2} + } + else + search_area = { + {pos_x - 2, pos_y - 1.5}, + {pos_x + 2, pos_y + 1.5} + } + end local stop = nil local rail = nil - local entities = stop.surface.find_entities(search_area) + local entities = comb.surface.find_entities(search_area) for _, cur_entity in pairs(entities) do if cur_entity.valid then if cur_entity.name == "train-stop" then @@ -131,15 +139,15 @@ local function on_combinator_built(map_data, comb) position = comb.position, force = comb.force }) - assert(out) + assert(out, "cybersyn: could not spawn combinator controller") comb.connect_neighbour({ target_entity = out, - source_wire_id = defines.circuit_connector_id.combinator_output, + source_circuit_id = defines.circuit_connector_id.combinator_output, wire = defines.wire_type.green, }) comb.connect_neighbour({ target_entity = out, - source_wire_id = defines.circuit_connector_id.combinator_output, + source_circuit_id = defines.circuit_connector_id.combinator_output, wire = defines.wire_type.red, }) @@ -149,7 +157,7 @@ local function on_combinator_built(map_data, comb) local control = comb.get_or_create_control_behavior().parameters if control.operation == OPERATION_WAGON_MANIFEST then if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, nil) end elseif control.operation == OPERATION_DEPOT then if stop then @@ -182,49 +190,32 @@ local function on_combinator_built(map_data, comb) --no station or depot --add station - local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, nil) + local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) - station = { - entity_stop = stop, - entity_comb1 = comb, - entity_comb2 = comb2, - wagon_combs = nil, - deliveries_total = 0, - last_delivery_tick = 0, - priority = 0, - r_threshold = 0, - p_threshold = 0, - locked_slots = 0, - deliveries = {}, - train_class = TRAIN_CLASS_AUTO, - accepted_layouts = {}, - layout_pattern = nil, - } - map_data.stations[stop.unit_number] = station - - update_station_if_auto(map_data, station) + on_station_built(map_data, stop, comb, comb2) end end end ---@param map_data MapData ---@param comb LuaEntity local function on_combinator_broken(map_data, comb) + --NOTE: we do not check for wagon manifest combinators and update their stations, it is assumed they will be lazy deleted later local out = map_data.to_output[comb.unit_number] 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.comb1 == comb then + if station.entity_comb1 == comb then local comb1 = search_for_station_combinator(map_data, stop, OPERATION_PRIMARY_IO, comb) if comb1 then - station.comb1 = comb1 + station.entity_comb1 = comb1 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, nil) end - elseif station.comb2 == comb then - station.comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) + 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] @@ -244,7 +235,7 @@ end ---@param map_data MapData ---@param comb LuaEntity local function on_combinator_updated(map_data, comb) - --NOTE: this is the lazy way to implement updates and is not robust + --NOTE: this is the lazy way to implement updates and puts strong restrictions on data validity on on_combinator_broken on_combinator_broken(map_data, comb) on_combinator_built(map_data, comb) end @@ -257,8 +248,8 @@ local function on_stop_built(map_data, stop) --TODO: fix search area local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} } local comb2 = nil local comb1 = nil @@ -291,8 +282,8 @@ local function on_stop_broken(map_data, stop) --TODO: fix search area local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} } local entities = stop.surface.find_entities(search_area) for _, entity in pairs(entities) do @@ -509,7 +500,7 @@ local function on_built(event) elseif entity.type == "pump" then update_station_from_pump(global, entity) elseif entity.type == "straight-rail" then - update_station_from_rail(global, entity) + update_station_from_rail(global, entity, nil) end end local function on_broken(event) @@ -530,7 +521,7 @@ local function on_broken(event) elseif entity.type == "pump" then update_station_from_pump(global, entity) elseif entity.type == "straight-rail" then - update_station_from_rail(global, entity) + update_station_from_rail(global, entity, nil) end end local function on_rename(event)