mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-07 20:08:02 -06:00
219 lines
7.5 KiB
Lua
219 lines
7.5 KiB
Lua
--By Mami
|
|
local area = require("__flib__.area")
|
|
|
|
function remove_train(map_data, train, train_id)
|
|
map_data.trains[train_id] = nil
|
|
map_data.trains_available[train_id] = nil
|
|
local layout_id = train.layout_id
|
|
local count = map_data.layout_train_count[layout_id]
|
|
if count <= 1 then
|
|
map_data.layout_train_count[layout_id] = nil
|
|
map_data.layouts[layout_id] = nil
|
|
for station_id, station in pairs(map_data.stations) do
|
|
station.accepted_layouts[layout_id] = nil
|
|
end
|
|
map_data.train_classes[TRAIN_CLASS_ALL][layout_id] = nil
|
|
else
|
|
map_data.layout_train_count[layout_id] = count - 1
|
|
end
|
|
end
|
|
|
|
function update_train_layout(map_data, train)
|
|
local carriages = train.entity.carriages
|
|
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
|
|
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
|
|
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
|
|
end
|
|
i = i + 1
|
|
end
|
|
local layout_id = 0
|
|
for id, cur_layout in pairs(map_data.layouts) do
|
|
if layout == cur_layout then
|
|
layout = cur_layout
|
|
layout_id = id
|
|
break
|
|
end
|
|
end
|
|
if layout_id == 0 then
|
|
--define new layout
|
|
layout_id = map_data.layout_top_id
|
|
map_data.layout_top_id = map_data.layout_top_id + 1
|
|
|
|
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
|
|
end
|
|
end
|
|
map_data.train_classes[TRAIN_CLASS_ALL][layout_id] = true
|
|
else
|
|
map_data.layout_train_count[layout_id] = map_data.layout_train_count[layout_id] + 1
|
|
end
|
|
train.layout_id = layout_id
|
|
train.item_slot_capacity = item_slot_capacity
|
|
train.fluid_capacity = fluid_capacity
|
|
end
|
|
|
|
local function reset_station_layout(map_data, station)
|
|
--station.entity
|
|
local station_rail = station.entity.connected_rail
|
|
local rail_direction_from_station
|
|
if station.entity.connected_rail_direction == defines.rail_direction.front then
|
|
rail_direction_from_station = defines.rail_direction.back
|
|
else
|
|
rail_direction_from_station = defines.rail_direction.front
|
|
end
|
|
local station_direction = station.entity.direction
|
|
local surface = station.entity.surface
|
|
local middle_x = station_rail.position.x
|
|
local middle_y = station_rail.position.y
|
|
local reach = LONGEST_INSERTER_REACH + 1 - DELTA
|
|
local search_area
|
|
local area_delta
|
|
local direction_filter
|
|
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}}
|
|
area_delta = {x = 0, y = 7}
|
|
direction_filter = {defines.direction.east, defines.direction.west}
|
|
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}
|
|
direction_filter = {defines.direction.north, defines.direction.south}
|
|
else
|
|
assert(false, "cybersyn: invalid station direction")
|
|
end
|
|
local length = 2
|
|
local pre_rail = station_rail
|
|
local layout_pattern = "^"
|
|
local layout_min_size = 10000
|
|
local type_filter = {"inserter", "pump"}
|
|
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
|
|
break
|
|
end
|
|
length = length + 2
|
|
if length%7 <= 1 then
|
|
local supports_cargo = false
|
|
local supports_fluid = false
|
|
local entities = surface.find_entities_filtered({
|
|
area = search_area,
|
|
type = type_filter,
|
|
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
|
|
end
|
|
end
|
|
end
|
|
|
|
if supports_cargo then
|
|
if supports_fluid then
|
|
layout_pattern = layout_pattern..STATION_LAYOUT_BOTH
|
|
else
|
|
layout_pattern = layout_pattern..STATION_LAYOUT_CARGO
|
|
end
|
|
elseif supports_fluid then
|
|
layout_pattern = layout_pattern..STATION_LAYOUT_FLUID
|
|
else
|
|
layout_pattern = layout_pattern..STATION_LAYOUT_NA
|
|
end
|
|
if layout_min_size <= 0 then
|
|
layout_pattern = layout_pattern.."?"
|
|
else
|
|
layout_min_size = layout_min_size - 1
|
|
end
|
|
search_area = area.move(search_area, area_delta)
|
|
end
|
|
end
|
|
layout_pattern = layout_pattern..STATION_LAYOUT_NA.."*$"
|
|
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
|
|
end
|
|
end
|
|
|
|
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
|
|
station.train_class = TRAIN_CLASS_AUTO
|
|
station.accepted_layouts = {}
|
|
end
|
|
reset_station_layout(map_data, station)
|
|
else
|
|
station.train_class = train_class_name
|
|
station.accepted_layouts = map_data.train_classes[train_class_name]
|
|
assert(station.accepted_layouts ~= nil)
|
|
station.layout_pattern = nil
|
|
end
|
|
end
|
|
|
|
function update_station_if_auto(map_data, station)
|
|
if station.train_class == TRAIN_CLASS_AUTO then
|
|
reset_station_layout(map_data, station)
|
|
end
|
|
end
|
|
|
|
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])
|
|
end
|
|
end
|
|
function update_station_from_pump(map_data, pump)
|
|
if pump.pump_rail_target then
|
|
update_station_from_rail(map_data, pump.pump_rail_target)
|
|
end
|
|
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})
|
|
if rail then
|
|
update_station_from_rail(map_data, rail)
|
|
end
|
|
rail = surface.find_entity("straight-rail", {pos.x + drop_pos.x, pos.y + drop_pos.y})
|
|
if rail then
|
|
update_station_from_rail(map_data, rail)
|
|
end
|
|
end
|