178 lines
5.3 KiB
Lua
178 lines
5.3 KiB
Lua
local circuit = require 'circuit'
|
|
local util = require 'util'
|
|
|
|
local function fast_replace_loader(loader_name, existing_loader)
|
|
local last_user = existing_loader.last_user
|
|
local new_loader = existing_loader.surface.create_entity{
|
|
name = loader_name,
|
|
position = existing_loader.position,
|
|
direction = existing_loader.direction,
|
|
force = existing_loader.force,
|
|
fast_replace = true,
|
|
spill = false,
|
|
create_build_effect_smoke = false,
|
|
type = existing_loader.loader_type,
|
|
}
|
|
new_loader.last_user = last_user
|
|
return new_loader
|
|
end
|
|
|
|
local function create_new_loader(loader_name, inserter, orientation)
|
|
local loader = inserter.surface.create_entity{
|
|
name = loader_name,
|
|
position = inserter.position,
|
|
direction = orientation.direction,
|
|
force = inserter.force,
|
|
type = orientation.type,
|
|
}
|
|
loader.destructible = false
|
|
return loader
|
|
end
|
|
|
|
local function select_connected_loader(loaders)
|
|
local selected_loader
|
|
for _, loader in pairs(loaders) do
|
|
local tl = loader.get_transport_line(1)
|
|
if next(tl.output_lines) or next(tl.input_lines) then
|
|
selected_loader = loader
|
|
break
|
|
end
|
|
end
|
|
if not selected_loader then
|
|
selected_loader = loaders[1]
|
|
end
|
|
for _, loader in pairs(loaders) do
|
|
if loader ~= selected_loader then
|
|
loader.destroy()
|
|
end
|
|
end
|
|
return selected_loader
|
|
end
|
|
|
|
local function ensure_loader(inserter, orientation)
|
|
local surface = inserter.surface
|
|
local position = inserter.position
|
|
local loader_name = inserter.name:gsub("inserter$", "loader")
|
|
local existing_loaders = util.find_miniloaders{surface=surface, position=position}
|
|
local existing_loader = select_connected_loader(existing_loaders)
|
|
if existing_loader then
|
|
if existing_loader.name ~= loader_name then
|
|
return fast_replace_loader(loader_name, existing_loader)
|
|
else
|
|
existing_loader.loader_type = orientation.type
|
|
end
|
|
else
|
|
return create_new_loader(loader_name, inserter, orientation)
|
|
end
|
|
return existing_loader
|
|
end
|
|
|
|
local function create_miniloader_inserter(main_inserter, fast_replace)
|
|
local new_inserter = main_inserter.surface.create_entity{
|
|
name = main_inserter.name,
|
|
position = main_inserter.position,
|
|
direction = main_inserter.direction,
|
|
force = main_inserter.force,
|
|
fast_replace = fast_replace,
|
|
spill = false,
|
|
create_build_effect_smoke = false,
|
|
}
|
|
new_inserter.last_user = main_inserter.last_user
|
|
if settings.global["miniloader-lock-stack-sizes"].value then
|
|
new_inserter.inserter_stack_size_override = 1
|
|
end
|
|
return new_inserter
|
|
end
|
|
|
|
local function ensure_inserters(desired_count, main_inserter)
|
|
local inserter_name = main_inserter.name
|
|
local surface = main_inserter.surface
|
|
local position = main_inserter.position
|
|
|
|
local inserters = surface.find_entities_filtered{ type = "inserter", position = position }
|
|
|
|
-- remove extra inserters
|
|
for i=#inserters, desired_count+1, -1 do
|
|
inserters[i].destroy()
|
|
inserters[i] = nil
|
|
end
|
|
|
|
-- replace existing inserters
|
|
for i=1, #inserters do
|
|
if inserters[i].name ~= inserter_name then
|
|
create_miniloader_inserter(main_inserter, true)
|
|
inserters[i].destroy()
|
|
end
|
|
end
|
|
|
|
-- create missing inserters
|
|
for i=#inserters+1, desired_count do
|
|
create_miniloader_inserter(main_inserter, false)
|
|
end
|
|
|
|
-- ensure only primary inserter can be damaged
|
|
-- note that order may be different after destroy + create
|
|
inserters = surface.find_entities_filtered{ type = "inserter", position = position }
|
|
inserters[1].destructible = true
|
|
for i=2,#inserters do
|
|
inserters[i].destructible = false
|
|
end
|
|
|
|
return inserters
|
|
end
|
|
|
|
local function ensure_chest(main_inserter)
|
|
local chest = main_inserter.surface.find_entity("miniloader-target-chest", main_inserter.position)
|
|
if not chest then
|
|
chest = main_inserter.surface.create_entity{
|
|
name = "miniloader-target-chest",
|
|
position = main_inserter.position,
|
|
force = main_inserter.force,
|
|
}
|
|
chest.destructible = false
|
|
end
|
|
return chest
|
|
end
|
|
|
|
local function fixup(main_inserter, orientation, tags)
|
|
if not orientation then
|
|
local existing_loader = util.find_miniloaders{surface = main_inserter.surface, position = main_inserter.position}[1]
|
|
if existing_loader then
|
|
orientation = {direction = existing_loader.direction, type = existing_loader.loader_type}
|
|
else
|
|
orientation = {direction = util.opposite_direction(main_inserter.direction), type = "input"}
|
|
end
|
|
end
|
|
local loader = ensure_loader(main_inserter, orientation)
|
|
local inserters = ensure_inserters(util.num_inserters(loader), main_inserter)
|
|
circuit.copy_inserter_settings(main_inserter, inserters[1])
|
|
ensure_chest(main_inserter)
|
|
|
|
util.update_inserters(loader)
|
|
if tags and tags.right_lane_settings then
|
|
global.split_lane_configuration[inserters[1].unit_number] = true
|
|
util.apply_settings(tags.right_lane_settings, inserters[2])
|
|
end
|
|
circuit.sync_behavior(main_inserter)
|
|
circuit.sync_filters(main_inserter)
|
|
circuit.sync_partner_connections(main_inserter)
|
|
|
|
return loader
|
|
end
|
|
|
|
local function forall(f)
|
|
for _, surface in pairs(game.surfaces) do
|
|
local miniloaders = util.find_miniloaders{surface = surface}
|
|
for _, entity in pairs(miniloaders) do
|
|
if entity.valid then
|
|
f(surface, entity)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return {
|
|
fixup = fixup,
|
|
forall = forall,
|
|
}
|