mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-08 06:08:03 -06:00
fixed automatic train layout detection
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user