fixed depot bypass bugs

This commit is contained in:
Monica Moniot
2022-12-01 15:56:05 -05:00
parent fde0a761dc
commit e648291c0a
6 changed files with 95 additions and 74 deletions

View File

@@ -66,17 +66,17 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type,
capacity >= min_slots_to_move and
btest(netand, train.network_flag) and
(r_station.allows_all_trains or r_station.accepted_layouts[layout_id]) and
(p_station.allows_all_trains or p_station.accepted_layouts[layout_id])
(p_station.allows_all_trains or p_station.accepted_layouts[layout_id]) and
not train.se_is_being_teleported
then
valid_train_exists = true
--check if exists valid path
--check if path is shortest so we prioritize locality
local d_to_p_dist = get_stop_dist(train.entity.front_stock, p_station.entity_stop) - DEPOT_PRIORITY_MULT*train.priority
local t_to_p_dist = get_stop_dist(train.entity.front_stock, p_station.entity_stop) - DEPOT_PRIORITY_MULT*train.priority
local dist = d_to_p_dist
if capacity > best_capacity or (capacity == best_capacity and dist < best_dist) then
if capacity > best_capacity or (capacity == best_capacity and t_to_p_dist < best_dist) then
best_capacity = capacity
best_dist = dist
best_dist = t_to_p_dist
best_train = train_id
end
end
@@ -170,47 +170,48 @@ local function send_train_between(map_data, r_station_id, p_station_id, train_id
end
end
r_station.last_delivery_tick = map_data.total_ticks
p_station.last_delivery_tick = map_data.total_ticks
r_station.deliveries_total = r_station.deliveries_total + 1
p_station.deliveries_total = p_station.deliveries_total + 1
for item_i, item in ipairs(manifest) do
assert(item.count > 0, "main.lua error, transfer amount was not positive")
r_station.deliveries[item.name] = (r_station.deliveries[item.name] or 0) + item.count
p_station.deliveries[item.name] = (p_station.deliveries[item.name] or 0) - item.count
if item_i > 1 then
--prevent deliveries from being processed for these items until their stations are re-polled
local item_network_name = network_name..":"..item.name
economy.all_r_stations[item_network_name] = nil
economy.all_p_stations[item_network_name] = nil
end
end
remove_available_train(map_data, train_id, train)
local depot_id = train.depot_id
local depot_id = train.parked_at_depot_id
if depot_id then
map_data.depots[depot_id].available_train_id = nil
train.depot_id = nil
train.parked_at_depot_id = nil
end
--NOTE: we assume that the train is not being teleported at this time
if set_manifest_schedule(train.entity, train.depot_name, train.se_depot_surface_i, p_station.entity_stop, r_station.entity_stop, manifest, depot_id ~= nil) then
train.status = STATUS_D_TO_P
train.p_station_id = p_station_id
train.r_station_id = r_station_id
train.manifest = manifest
train.last_manifest_tick = map_data.total_ticks
train.status = STATUS_D_TO_P
train.p_station_id = p_station_id
train.r_station_id = r_station_id
train.manifest = manifest
train.last_manifest_tick = map_data.total_ticks
r_station.last_delivery_tick = map_data.total_ticks
p_station.last_delivery_tick = map_data.total_ticks
set_manifest_schedule(train.entity, train.depot_name, train.se_depot_surface_i, p_station.entity_stop, r_station.entity_stop, manifest, depot_id ~= nil)
set_comb2(map_data, p_station)
set_comb2(map_data, r_station)
if p_station.entity_comb1.valid then
set_comb_operation_with_check(map_data, p_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
end
if r_station.entity_comb1.valid then
set_comb_operation_with_check(map_data, r_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
r_station.deliveries_total = r_station.deliveries_total + 1
p_station.deliveries_total = p_station.deliveries_total + 1
for item_i, item in ipairs(manifest) do
assert(item.count > 0, "main.lua error, transfer amount was not positive")
r_station.deliveries[item.name] = (r_station.deliveries[item.name] or 0) + item.count
p_station.deliveries[item.name] = (p_station.deliveries[item.name] or 0) - item.count
if item_i > 1 then
--prevent deliveries from being processed for these items until their stations are re-polled
local item_network_name = network_name..":"..item.name
economy.all_r_stations[item_network_name] = nil
economy.all_p_stations[item_network_name] = nil
end
end
set_comb2(map_data, p_station)
set_comb2(map_data, r_station)
if p_station.entity_comb1.valid then
set_comb_operation_with_check(map_data, p_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
end
if r_station.entity_comb1.valid then
set_comb_operation_with_check(map_data, r_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
end
end
end
@@ -222,7 +223,7 @@ local function tick_poll_train(map_data, mod_settings)
local train_id, train = next(map_data.trains, tick_data.last_train)
tick_data.last_train = train_id
if train and train.manifest and train.entity and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
if train and train.manifest and not train.se_is_being_teleported and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
send_stuck_train_alert(train.entity, train.depot_name)
end
end

View File

@@ -119,7 +119,11 @@ end
---@param manifest Manifest
---@param start_at_depot boolean?
function set_manifest_schedule(train, depot_name, d_surface_i, p_stop, r_stop, manifest, start_at_depot)
--NOTE: train must be on same surface as depot_stop
--NOTE: can only return false if start_at_depot is false, it should be incredibly rare that this function returns false
local old_schedule
if not start_at_depot then
old_schedule = train.schedule
end
local t_surface = train.front_stock.surface
local p_surface = p_stop.surface
local r_surface = r_stop.surface
@@ -134,7 +138,12 @@ function set_manifest_schedule(train, depot_name, d_surface_i, p_stop, r_stop, m
create_direct_to_station_order(r_stop),
create_unloading_order(r_stop),
}}
return
if old_schedule and not train.has_path then
train.schedule = old_schedule
return false
else
return true
end
elseif IS_SE_PRESENT and (t_surface_i == p_surface_i or p_surface_i == r_surface_i or r_surface_i == t_surface_i) then
local t_zone = remote.call("space-exploration", "get_zone_from_surface_index", {surface_index = t_surface_i})
local other_zone = remote.call("space-exploration", "get_zone_from_surface_index", {surface_index = (t_surface_i == p_surface_i) and r_surface_i or p_surface_i})
@@ -161,7 +170,12 @@ function set_manifest_schedule(train, depot_name, d_surface_i, p_stop, r_stop, m
end
train.schedule = {current = start_at_depot and 1 or 2, records = records}
return
if old_schedule and not train.has_path then
train.schedule = old_schedule
return false
else
return true
end
end
end
end
@@ -173,6 +187,7 @@ function set_manifest_schedule(train, depot_name, d_surface_i, p_stop, r_stop, m
}}
lock_train(train)
send_lost_train_alert(train, depot_name)
return true
end

View File

@@ -59,12 +59,13 @@
---@field public last_manifest_tick int
---@field public has_filtered_wagon boolean
---@field public is_available true?
---@field public depot_id uint?
---@field public parked_at_depot_id uint?
---@field public depot_name string
---@field public se_depot_surface_i uint --se only
---@field public network_name string?
---@field public network_name string
---@field public network_flag int
---@field public priority int
---@field public se_depot_surface_i uint --se only
---@field public se_is_being_teleported true? --se only
---@field public se_awaiting_removal any? --se only
---@field public se_awaiting_rename any? --se only

View File

@@ -55,7 +55,7 @@ end
---@param train_id uint
---@param train Train
function remove_train(map_data, train_id, train)
local parked_at_depot_id = train.depot_id
local parked_at_depot_id = train.parked_at_depot_id
if parked_at_depot_id then
local depot = map_data.depots[parked_at_depot_id]
depot.available_train_id = nil

View File

@@ -87,7 +87,7 @@ local function add_available_train_to_depot(map_data, train_id, train, depot_id,
end
depot.available_train_id = train_id
train.status = STATUS_D
train.depot_id = depot_id
train.parked_at_depot_id = depot_id
train.depot_name = depot.entity_stop.backer_name
train.se_depot_surface_i = depot.entity_stop.surface.index
train.network_name = network_name
@@ -124,6 +124,7 @@ function remove_available_train(map_data, train_id, train)
map_data.available_trains[train.network_name] = nil
end
end
train.is_available = nil
end
end
@@ -196,7 +197,7 @@ local function on_station_broken(map_data, station_id, station)
if (is_r and not is_r_delivery_made) or (is_p and not is_p_delivery_made) then
--train is attempting delivery to a stop that was destroyed, stop it
on_failed_delivery(map_data, train)
if train.entity then
if not train.se_is_being_teleported then
remove_train(map_data, train_id, train)
lock_train(train.entity)
send_lost_train_alert(train.entity, train.depot_name)
@@ -548,17 +549,17 @@ local function on_station_rename(map_data, stop, old_name)
local is_r_delivery_made = train.status == STATUS_R_TO_D
if is_r and not is_r_delivery_made then
local r_station = map_data.stations[train.r_station_id]
if train.entity then
if not train.se_is_being_teleported then
rename_manifest_schedule(train.entity, r_station.entity_stop, old_name)
elseif IS_SE_PRESENT then
else
train.se_awaiting_rename = {r_station.entity_stop, old_name}
end
elseif is_p and not is_p_delivery_made then
--train is attempting delivery to a stop that was renamed
local p_station = map_data.stations[train.p_station_id]
if train.entity then
if not train.se_is_being_teleported then
rename_manifest_schedule(train.entity, p_station.entity_stop, old_name)
elseif IS_SE_PRESENT then
else
train.se_awaiting_rename = {p_station.entity_stop, old_name}
end
end
@@ -737,7 +738,7 @@ local function on_train_leaves_station(map_data, mod_settings, train_id, train)
end
elseif train.status == STATUS_D then
--The train is leaving the depot without a manifest, the player likely intervened
local depot = map_data.depots[train.depot_id--[[@as uint]]]
local depot = map_data.depots[train.parked_at_depot_id--[[@as uint]]]
send_lost_train_alert(train.entity, depot.entity_stop.backer_name)
remove_train(map_data, train_id, train)
end
@@ -749,7 +750,7 @@ end
---@param train Train
local function on_train_broken(map_data, train_id, train)
--NOTE: train.entity is only absent if the train is climbing a space elevator as of 0.5.0
if train.entity then
if not train.se_is_being_teleported then
if train.manifest then
on_failed_delivery(map_data, train)
end
@@ -761,7 +762,7 @@ end
local function on_train_modified(map_data, pre_train_id)
local train = map_data.trains[pre_train_id]
--NOTE: train.entity is only absent if the train is climbing a space elevator as of 0.5.0
if train and train.entity then
if train and not train.se_is_being_teleported then
if train.manifest then
on_failed_delivery(map_data, train)
end
@@ -980,7 +981,7 @@ local function main()
local train = map_data.trains[old_id]
if not train then return end
--NOTE: IMPORTANT, until se_on_train_teleport_finished_event is called map_data.trains[old_id] will reference an invalid train entity; very few of our events care about this and the ones that do should be impossible to trigger until teleportation is finished
train.entity = nil
train.se_is_being_teleported = true
map_data.se_tele_old_id[train_unique_identifier] = old_id
end)
flib_event.register(se_on_train_teleport_finished_event, function(event)
@@ -1010,6 +1011,7 @@ local function main()
map_data.trains[new_id] = train
map_data.trains[old_id] = nil
train.se_is_being_teleported = nil
train.entity = train_entity
if train.se_awaiting_removal then

View File

@@ -43,7 +43,7 @@ local migrations_table = {
for id, train in pairs(map_data.trains) do
local depot = train.depot
if depot then
train.depot_id = depot.entity_comb.unit_number
train.parked_at_depot_id = depot.entity_comb.unit_number
train.network_name = depot.network_name
train.network_flag = depot.network_flag
train.priority = depot.priority
@@ -138,7 +138,7 @@ local migrations_table = {
for k, v in pairs(map_data.trains) do
v.depot = nil
if not v.is_available then
v.depot_id = nil
v.parked_at_depot_id = nil
end
end
end,
@@ -147,21 +147,23 @@ local migrations_table = {
local map_data = global
map_data.tick_state = STATE_INIT
map_data.tick_data = {}
if IS_SE_PRESENT then
for k, v in pairs(map_data.available_trains) do
for id, _ in pairs(v) do
local train = map_data.trains[id]
if not train then
v[id] = nil
end
map_data.available_trains = {}
for id, v in pairs(map_data.trains) do
v.parked_at_depot_id = v.depot_id
v.depot_id = nil
v.se_is_being_teleported = not v.entity and true or nil
--NOTE: we are guessing here because this information was never saved
v.se_depot_surface_i = v.entity.front_stock.surface.index
if v.parked_at_depot_id then
v.is_available = true
local network = map_data.available_trains[v.network_name--[[@as string]]]
if not network then
network = {}
map_data.available_trains[v.network_name--[[@as string]]] = network
end
end
for id, v in pairs(map_data.trains) do
if v.is_available then
map_data.available_trains[v.network_name--[[@as string]]][id] = true
end
--NOTE: we are guessing here because this information was never saved
v.se_depot_surface_i = v.entity.front_stock.surface.index
network[id] = true
else
v.is_available = nil
end
end
end,