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)
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.
- 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:
- 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

View File

@@ -6,6 +6,10 @@ local ceil = math.ceil
local min = math.min
local max = math.max
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)[]
@@ -417,7 +421,7 @@ function unset_wagon_combs(map_data, stop)
end
end
local type_filter = {"inserter", "pump", "arithmetic-combinator", "loader-1x1"}
---@param map_data MapData
---@param stop Station|Refueler
---@param is_station_or_refueler boolean
@@ -432,10 +436,10 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent
return
end
local rail_direction_from_stop
if stop.entity_stop.connected_rail_direction == defines.rail_direction.front then
rail_direction_from_stop = defines.rail_direction.back
if stop.entity_stop.connected_rail_direction == defines_front then
rail_direction_from_stop = defines_back
else
rail_direction_from_stop = defines.rail_direction.front
rail_direction_from_stop = defines_front
end
local stop_direction = stop.entity_stop.direction
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 is_ver
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}}
area_delta = {x = 0, y = 7}
search_area = {{middle_x - reach, middle_y}, {middle_x + reach, middle_y + 6}}
area_delta = {0, 7}
is_ver = true
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}}
area_delta = {x = -7, y = 0}
search_area = {{middle_x - 6, middle_y - reach}, {middle_x, middle_y + reach}}
area_delta = {-7, 0}
is_ver = false
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}}
area_delta = {x = 0, y = -7}
search_area = {{middle_x - reach, middle_y - 6}, {middle_x + reach, middle_y}}
area_delta = {0, -7}
is_ver = true
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}}
area_delta = {x = 7, y = 0}
search_area = {{middle_x, middle_y - reach}, {middle_x + 6, middle_y + reach}}
area_delta = {7, 0}
is_ver = false
else
assert(false, "cybersyn: invalid stop direction")
end
local length = 2
local length = 1
---@type LuaEntity?
local pre_rail = stop_rail
local layout_pattern = {0}
local type_filter = {"inserter", "pump", "arithmetic-combinator", "loader-1x1"}
local wagon_number = 0
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 not rail or not rail.valid then
is_break = true
break
if pre_rail then
local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_stop, rail_connection_direction = defines_straight})
if not rail or rail_connection_direction ~= defines_straight then
-- 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
pre_rail = rail
length = length + 2
if length%7 <= 1 then
if length >= 6 or not pre_rail then
if not pre_rail 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
local supports_cargo = 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,
})
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 not supports_cargo then
local pos = entity.pickup_position
@@ -566,10 +599,6 @@ function reset_stop_layout(map_data, stop, is_station_or_refueler, forbidden_ent
end
search_area = area.move(search_area, area_delta)
end
if rail_connection_direction ~= defines.rail_connection_direction.straight then
is_break = true
break
end
end
stop.layout_pattern = layout_pattern
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
---@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 rail LuaEntity
---@param forbidden_entity LuaEntity?
---@param force boolean?
function update_stop_from_rail(map_data, rail, forbidden_entity, force)
--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
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
if not entity or not entity.valid then
return
end
if entity.name == "train-stop" then
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
if rail_back then
local entity = rail_back.get_rail_segment_entity(defines_back, false)
if entity and entity.name == "train-stop" then
resolve_update_stop_from_rail(map_data, entity, forbidden_entity, force)
return
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
rail_back = rail_back.get_connected_rail({rail_direction = defines_back, rail_connection_direction = defines_straight})
end
if rail_front then
local entity = rail_front.get_rail_segment_entity(defines_front, false)
if entity and entity.name == "train-stop" then
resolve_update_stop_from_rail(map_data, entity, forbidden_entity, force)
return
end
return
rail_front = rail_front.get_connected_rail({rail_direction = defines_front, rail_connection_direction = defines_straight})
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
@@ -650,20 +687,46 @@ end
---@param forbidden_entity LuaEntity?
function update_stop_from_inserter(map_data, inserter, forbidden_entity)
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({
type = "straight-rail",
position = inserter.pickup_position,
radius = 1,
type = search_type,
position = pos1,
})
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
update_stop_from_rail(map_data, rails[1], forbidden_entity)
end
rails = surface.find_entities_filtered({
type = "straight-rail",
position = inserter.drop_position,
radius = 1,
type = search_type,
position = pos2,
})
if rails[1] then
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 direction == defines.direction.east then
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
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
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
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
elseif loader_type == "output" then --unloading train
if direction == defines.direction.east then
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
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
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
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
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)
elseif entity.type == "pump" then
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)
end
end
@@ -642,7 +642,7 @@ local function on_broken(event)
update_stop_from_loader(global, entity, entity)
elseif entity.type == "pump" then
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)
elseif entity.train then
local train_id = entity.train.id
@@ -876,6 +876,7 @@ local filter_built = {
{filter = "type", type = "inserter"},
{filter = "type", type = "pump"},
{filter = "type", type = "straight-rail"},
{filter = "type", type = "curved-rail"},
{filter = "type", type = "loader-1x1"},
}
local filter_broken = {
@@ -884,6 +885,7 @@ local filter_broken = {
{filter = "type", type = "inserter"},
{filter = "type", type = "pump"},
{filter = "type", type = "straight-rail"},
{filter = "type", type = "curved-rail"},
{filter = "type", type = "loader-1x1"},
{filter = "rolling-stock"},
}

View File

@@ -321,13 +321,14 @@ local migrations_table = {
---@param data ConfigurationChangedData
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_data = {}
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
if IS_SE_PRESENT and not global.se_tele_old_id then
global.se_tele_old_id = {}