fixed allow list logic

This commit is contained in:
mamoniot
2023-03-29 15:19:02 -04:00
parent 9fe93329cd
commit 4ef0d245c8
4 changed files with 143 additions and 133 deletions

View File

@@ -5,6 +5,7 @@ Date: 2023-3-28
- Added opt-in WIP trains, inventory, and station manager gui (highly experimental, use at your own risk) - Added opt-in WIP trains, inventory, and station manager gui (highly experimental, use at your own risk)
Changes: Changes:
- Improved the recipe derivation logic for the cybernetic combinator, in all modpacks it should now consistently be about as difficult to craft as an arthmetic combinator. Vanilla recipe is unchanged, but several overhaul mods will receive new recipes. - Improved the recipe derivation logic for the cybernetic combinator, in all modpacks it should now consistently be about as difficult to craft as an arthmetic combinator. Vanilla recipe is unchanged, but several overhaul mods will receive new recipes.
- The automatic allow list now consistently looks 3 tiles past the first curve rail it finds along a station for inserters or pumps. Previously it would conditionally look only 1 tile past. This should lead to more intuitive allow list behaviour for stations with trains that park slightly on curved rails.
Bugfixes: Bugfixes:
- Provider override thresholds now correctly override the required train capacity as well; fix contributed by shopt - Provider override thresholds now correctly override the required train capacity as well; fix contributed by shopt
- Fixed a rare crash relating to an uninitialized network mask on a new station - Fixed a rare crash relating to an uninitialized network mask on a new station

View File

@@ -6,6 +6,10 @@ local ceil = math.ceil
local min = math.min local min = math.min
local max = math.max local max = math.max
local bit_extract = bit32.extract local bit_extract = bit32.extract
local defines_front = defines.rail_direction.front
local defines_back = defines.rail_direction.back
local defines_straight = defines.rail_connection_direction.straight
local search_type = {"straight-rail", "curved-rail"}
---@param layout_pattern (0|1|2|3)[] ---@param layout_pattern (0|1|2|3)[]
@@ -417,7 +421,7 @@ function unset_wagon_combs(map_data, stop)
end end
end end
local type_filter = {"inserter", "pump", "arithmetic-combinator", "loader-1x1"}
---@param map_data MapData ---@param map_data MapData
---@param stop Station|Refueler ---@param stop Station|Refueler
---@param is_station_or_refueler boolean ---@param is_station_or_refueler boolean
@@ -432,10 +436,10 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent
return return
end end
local rail_direction_from_stop local rail_direction_from_stop
if stop.entity_stop.connected_rail_direction == defines.rail_direction.front then if stop.entity_stop.connected_rail_direction == defines_front then
rail_direction_from_stop = defines.rail_direction.back rail_direction_from_stop = defines_back
else else
rail_direction_from_stop = defines.rail_direction.front rail_direction_from_stop = defines_front
end end
local stop_direction = stop.entity_stop.direction local stop_direction = stop.entity_stop.direction
local surface = stop.entity_stop.surface local surface = stop.entity_stop.surface
@@ -446,38 +450,67 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent
local area_delta local area_delta
local is_ver local is_ver
if stop_direction == defines.direction.north then if stop_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}} search_area = {{middle_x - reach, middle_y}, {middle_x + reach, middle_y + 6}}
area_delta = {x = 0, y = 7} area_delta = {0, 7}
is_ver = true is_ver = true
elseif stop_direction == defines.direction.east then elseif stop_direction == defines.direction.east then
search_area = {left_top = {y = middle_y - reach, x = middle_x - 6}, right_bottom = {y = middle_y + reach, x = middle_x}} search_area = {{middle_x - 6, middle_y - reach}, {middle_x, middle_y + reach}}
area_delta = {x = -7, y = 0} area_delta = {-7, 0}
is_ver = false is_ver = false
elseif stop_direction == defines.direction.south then elseif stop_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 = {{middle_x - reach, middle_y - 6}, {middle_x + reach, middle_y}}
area_delta = {x = 0, y = -7} area_delta = {0, -7}
is_ver = true is_ver = true
elseif stop_direction == defines.direction.west then elseif stop_direction == defines.direction.west then
search_area = {left_top = {y = middle_y - reach, x = middle_x}, right_bottom = {y = middle_y + reach, x = middle_x + 6}} search_area = {{middle_x, middle_y - reach}, {middle_x + 6, middle_y + reach}}
area_delta = {x = 7, y = 0} area_delta = {7, 0}
is_ver = false is_ver = false
else else
assert(false, "cybersyn: invalid stop direction") assert(false, "cybersyn: invalid stop direction")
end end
local length = 2 local length = 1
---@type LuaEntity?
local pre_rail = stop_rail local pre_rail = stop_rail
local layout_pattern = {0} local layout_pattern = {0}
local type_filter = {"inserter", "pump", "arithmetic-combinator", "loader-1x1"}
local wagon_number = 0 local wagon_number = 0
for i = 1, 112 do for i = 1, 112 do
local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_stop, rail_connection_direction = defines.rail_connection_direction.straight}) if pre_rail then
if not rail or not rail.valid then local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_stop, rail_connection_direction = defines_straight})
is_break = true if not rail or rail_connection_direction ~= defines_straight then
break -- There is a curved rail or break in the tracks at this point
-- We are assuming it's a curved rail, maybe that's a bad assumption
-- We stop searching to expand the allow list after we see a curved rail
-- We are allowing up to 3 tiles of extra allow list usage on a curved rail
length = length + 3
pre_rail = nil
else
pre_rail = rail
length = length + 2
end
end end
pre_rail = rail if length >= 6 or not pre_rail then
length = length + 2 if not pre_rail then
if length%7 <= 1 then if length <= 0 then
-- No point searching nothing
-- Once we hit a curve and process the 3 extra tiles we break here
-- This is the only breakpoint in this for loop
break
end
-- Minimize the search_area to include only the straight section of track and the 3 tiles of the curved rail
local missing_rail_length = 6 - length
if missing_rail_length > 0 then
if stop_direction == defines.direction.north then
search_area[2][2] = search_area[2][2] - missing_rail_length
elseif stop_direction == defines.direction.east then
search_area[1][1] = search_area[1][1] + missing_rail_length
elseif stop_direction == defines.direction.south then
search_area[1][2] = search_area[1][2] + missing_rail_length
else
search_area[2][1] = search_area[2][1] - missing_rail_length
end
end
end
length = length - 7
wagon_number = wagon_number + 1 wagon_number = wagon_number + 1
local supports_cargo = false local supports_cargo = false
local supports_fluid = false local supports_fluid = false
@@ -486,7 +519,7 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent
type = type_filter, type = type_filter,
}) })
for _, entity in pairs(entities) do for _, entity in pairs(entities) do
if entity.valid and entity ~= forbidden_entity then if entity ~= forbidden_entity then
if entity.type == "inserter" then if entity.type == "inserter" then
if not supports_cargo then if not supports_cargo then
local pos = entity.pickup_position local pos = entity.pickup_position
@@ -566,10 +599,6 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent
end end
search_area = area.move(search_area, area_delta) search_area = area.move(search_area, area_delta)
end end
if rail_connection_direction ~= defines.rail_connection_direction.straight then
is_break = true
break
end
end end
stop.layout_pattern = layout_pattern stop.layout_pattern = layout_pattern
if is_station_or_refueler then if is_station_or_refueler then
@@ -593,47 +622,55 @@ function update_stop_if_auto(map_data, stop, is_station_or_refueler, forbidden_e
end end
end end
---@param map_data MapData
---@param entity LuaEntity
---@param forbidden_entity LuaEntity?
---@param force boolean?
local function resolve_update_stop_from_rail(map_data, entity, forbidden_entity, force)
local id = entity.unit_number--[[@as uint]]
local is_station = true
---@type Station|Refueler
local stop = map_data.stations[id]
if not stop then
stop = map_data.refuelers[id]
is_station = false
end
if stop and stop.entity_stop.valid then
if force then
reset_stop_layout(map_data, stop, is_station, forbidden_entity)
elseif not stop.allows_all_trains then
reset_stop_layout(map_data, stop, is_station, forbidden_entity)
end
end
end
---@param map_data MapData ---@param map_data MapData
---@param rail LuaEntity ---@param rail LuaEntity
---@param forbidden_entity LuaEntity? ---@param forbidden_entity LuaEntity?
---@param force boolean? ---@param force boolean?
function update_stop_from_rail(map_data, rail, forbidden_entity, force) function update_stop_from_rail(map_data, rail, forbidden_entity, force)
--NOTE: is this a correct way to figure out the direction? --NOTE: is this a correct way to figure out the direction?
---@type LuaEntity?
local rail_front = rail
---@type LuaEntity?
local rail_back = rail
---@type defines.rail_direction ---@type defines.rail_direction
local rail_direction = defines.rail_direction.back
local entity = rail.get_rail_segment_entity(rail_direction, false)
if not entity then
rail_direction = defines.rail_direction.front
entity = rail.get_rail_segment_entity(rail_direction, false)
end
for i = 1, 112 do for i = 1, 112 do
if not entity or not entity.valid then if rail_back then
return local entity = rail_back.get_rail_segment_entity(defines_back, false)
end if entity and entity.name == "train-stop" then
if entity.name == "train-stop" then resolve_update_stop_from_rail(map_data, entity, forbidden_entity, force)
local id = entity.unit_number--[[@as uint]] return
local is_station = true
---@type Station|Refueler
local stop = map_data.stations[id]
if not stop then
stop = map_data.refuelers[id]
is_station = false
end end
if stop and stop.entity_stop.valid then rail_back = rail_back.get_connected_rail({rail_direction = defines_back, rail_connection_direction = defines_straight})
if force then end
reset_stop_layout(map_data, stop, is_station, forbidden_entity) if rail_front then
elseif not stop.allows_all_trains then local entity = rail_front.get_rail_segment_entity(defines_front, false)
reset_stop_layout(map_data, stop, is_station, forbidden_entity) if entity and entity.name == "train-stop" then
end resolve_update_stop_from_rail(map_data, entity, forbidden_entity, force)
return
end end
return rail_front = rail_front.get_connected_rail({rail_direction = defines_front, rail_connection_direction = defines_straight})
end end
rail = rail.get_connected_rail({rail_direction = rail_direction, rail_connection_direction = defines.rail_connection_direction.straight})--[[@as LuaEntity]]
if not rail or not rail.valid then
return
end
entity = rail.get_rail_segment_entity(rail_direction, false)
end end
end end
@@ -650,20 +687,46 @@ end
---@param forbidden_entity LuaEntity? ---@param forbidden_entity LuaEntity?
function update_stop_from_inserter(map_data, inserter, forbidden_entity) function update_stop_from_inserter(map_data, inserter, forbidden_entity)
local surface = inserter.surface local surface = inserter.surface
local pos0 = inserter.position
local pos1 = inserter.pickup_position
local pos2 = inserter.drop_position
local has_found = false
--NOTE: we don't use find_entity solely for miniloader compat
local rails = surface.find_entities_filtered({ local rails = surface.find_entities_filtered({
type = "straight-rail", type = search_type,
position = inserter.pickup_position, position = pos1,
radius = 1, })
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
has_found = true
end
rails = surface.find_entities_filtered({
type = search_type,
position = pos2,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
has_found = true
end
if has_found then
return
end
-- We need to check secondary positions because of weird modded inserters.
-- Mostly because of miniloaders not aligning with the hitbox of a rail by default.
pos1.x = pos1.x + 0.2*(pos1.x - pos0.x)
pos1.y = pos1.y + 0.2*(pos1.y - pos0.y)
pos2.x = pos2.x + 0.2*(pos2.x - pos0.x)
pos2.y = pos2.y + 0.2*(pos2.y - pos0.y)
rails = surface.find_entities_filtered({
type = search_type,
position = pos1,
}) })
if rails[1] then if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity) update_stop_from_rail(map_data, rails[1], forbidden_entity)
end end
rails = surface.find_entities_filtered({ rails = surface.find_entities_filtered({
type = "straight-rail", type = search_type,
position = inserter.drop_position, position = pos2,
radius = 1,
}) })
if rails[1] then if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity) update_stop_from_rail(map_data, rails[1], forbidden_entity)
@@ -681,86 +744,29 @@ function update_stop_from_loader(map_data, loader, forbidden_entity)
if loader_type == "input" then --loading train if loader_type == "input" then --loading train
if direction == defines.direction.east then if direction == defines.direction.east then
position.x = position.x + 1 -- input and facing east -> move on X axis 1 to the right position.x = position.x + 1 -- input and facing east -> move on X axis 1 to the right
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
elseif direction == defines.direction.south then elseif direction == defines.direction.south then
position.y = position.y + 1 -- input and facing south -> move on Y axis down 1 unit position.y = position.y + 1 -- input and facing south -> move on Y axis down 1 unit
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
elseif direction == defines.direction.west then elseif direction == defines.direction.west then
position.x = position.x - 1 -- input and facing west -> move on X axis 1 to the left position.x = position.x - 1 -- input and facing west -> move on X axis 1 to the left
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
elseif direction == defines.direction.north then elseif direction == defines.direction.north then
position.y = position.y - 1 -- input and facing south -> move on Y axis up 1 unit position.y = position.y - 1 -- input and facing south -> move on Y axis up 1 unit
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
end end
elseif loader_type == "output" then --unloading train elseif loader_type == "output" then --unloading train
if direction == defines.direction.east then if direction == defines.direction.east then
position.x = position.x - 1 -- output and facing east -> move on X axis 1 to the left position.x = position.x - 1 -- output and facing east -> move on X axis 1 to the left
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
elseif direction == defines.direction.south then elseif direction == defines.direction.south then
position.y = position.y - 1 -- output and facing south -> move on Y axis up 1 unit position.y = position.y - 1 -- output and facing south -> move on Y axis up 1 unit
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
elseif direction == defines.direction.west then elseif direction == defines.direction.west then
position.x = position.x + 1 -- output and facing west -> move on X axis 1 to the right position.x = position.x + 1 -- output and facing west -> move on X axis 1 to the right
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
elseif direction == defines.direction.north then elseif direction == defines.direction.north then
position.y = position.y + 1 -- output and facing south -> move on Y axis down 1 unit position.y = position.y + 1 -- output and facing south -> move on Y axis down 1 unit
local rails = surface.find_entities_filtered({
type = "straight-rail",
position = position,
radius = 1,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
end end
end end
end local rails = surface.find_entities_filtered({
type = search_type,
position = position,
})
if rails[1] then
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
end

View File

@@ -624,7 +624,7 @@ local function on_built(event)
update_stop_from_loader(global, entity) update_stop_from_loader(global, entity)
elseif entity.type == "pump" then elseif entity.type == "pump" then
update_stop_from_pump(global, entity) update_stop_from_pump(global, entity)
elseif entity.type == "straight-rail" then elseif entity.type == "straight-rail" or entity.type == "curved-rail" then
update_stop_from_rail(global, entity) update_stop_from_rail(global, entity)
end end
end end
@@ -642,7 +642,7 @@ local function on_broken(event)
update_stop_from_loader(global, entity, entity) update_stop_from_loader(global, entity, entity)
elseif entity.type == "pump" then elseif entity.type == "pump" then
update_stop_from_pump(global, entity, entity) update_stop_from_pump(global, entity, entity)
elseif entity.type == "straight-rail" then elseif entity.type == "straight-rail" or entity.type == "curved-rail" then
update_stop_from_rail(global, entity, nil) update_stop_from_rail(global, entity, nil)
elseif entity.train then elseif entity.train then
local train_id = entity.train.id local train_id = entity.train.id
@@ -876,6 +876,7 @@ local filter_built = {
{filter = "type", type = "inserter"}, {filter = "type", type = "inserter"},
{filter = "type", type = "pump"}, {filter = "type", type = "pump"},
{filter = "type", type = "straight-rail"}, {filter = "type", type = "straight-rail"},
{filter = "type", type = "curved-rail"},
{filter = "type", type = "loader-1x1"}, {filter = "type", type = "loader-1x1"},
} }
local filter_broken = { local filter_broken = {
@@ -884,6 +885,7 @@ local filter_broken = {
{filter = "type", type = "inserter"}, {filter = "type", type = "inserter"},
{filter = "type", type = "pump"}, {filter = "type", type = "pump"},
{filter = "type", type = "straight-rail"}, {filter = "type", type = "straight-rail"},
{filter = "type", type = "curved-rail"},
{filter = "type", type = "loader-1x1"}, {filter = "type", type = "loader-1x1"},
{filter = "rolling-stock"}, {filter = "rolling-stock"},
} }

View File

@@ -321,13 +321,14 @@ local migrations_table = {
---@param data ConfigurationChangedData ---@param data ConfigurationChangedData
function on_config_changed(data) function on_config_changed(data)
for i, v in pairs(global.manager.players) do
manager_gui.reset_player(i, v)
end
global.tick_state = STATE_INIT global.tick_state = STATE_INIT
global.tick_data = {} global.tick_data = {}
flib_migration.on_config_changed(data, migrations_table) flib_migration.on_config_changed(data, migrations_table)
for i, v in pairs(global.manager.players) do
manager_gui.reset_player(i, v)
end
IS_SE_PRESENT = remote.interfaces["space-exploration"] ~= nil IS_SE_PRESENT = remote.interfaces["space-exploration"] ~= nil
if IS_SE_PRESENT and not global.se_tele_old_id then if IS_SE_PRESENT and not global.se_tele_old_id then
global.se_tele_old_id = {} global.se_tele_old_id = {}