added valid checking

This commit is contained in:
monica
2023-01-07 18:57:13 -05:00
committed by Monica Moniot
parent 2e0216a351
commit 1fc464055e
6 changed files with 241 additions and 169 deletions

View File

@@ -42,71 +42,93 @@ function create_delivery(map_data, r_station_id, p_station_id, train_id, manifes
local train = map_data.trains[train_id]
local depot = map_data.depots[train.depot_id]
local is_at_depot = remove_available_train(map_data, train_id, train)
--NOTE: we assume that the train is not being teleported at this time
--NOTE: set_manifest_schedule is allowed to cancel the delivery at the last second if applying the schedule to the train makes it lost
if set_manifest_schedule(map_data, train.entity, depot.entity_stop, not train.use_any_depot, p_station.entity_stop, p_station.enable_inactive, r_station.entity_stop, mod_settings.allow_cargo_in_depot and r_station.enable_inactive--[[@as boolean]], manifest, is_at_depot) then
local old_status = train.status
train.status = STATUS_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
r_station.deliveries_total = r_station.deliveries_total + 1
p_station.deliveries_total = p_station.deliveries_total + 1
local r_is_each = r_station.network_name == NETWORK_EACH
local p_is_each = p_station.network_name == NETWORK_EACH
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 or r_is_each or p_is_each then
local f, a
if r_is_each then
f, a = pairs(r_station.network_flag--[[@as {[string]: int}]])
if p_is_each then
for network_name, _ in f, a do
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
f, a = pairs(p_station.network_flag--[[@as {[string]: int}]])
end
elseif p_is_each then
f, a = pairs(p_station.network_flag--[[@as {[string]: int}]])
else
f, a = once, r_station.network_name
end
--prevent deliveries from being processed for these items until their stations are re-polled
--if we don't wait until they are repolled a duplicate delivery might be generated for stations that share inventories
for network_name, _ in f, a do
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
if not train.entity.valid then
on_train_broken(map_data, train_id, train)
interface_raise_train_dispatch_failed(train_id)
return
end
if not depot.entity_stop.valid then
on_depot_broken(map_data, train.depot_id, depot)
interface_raise_train_dispatch_failed(train_id)
return
end
if not p_station.entity_stop.valid then
on_station_broken(map_data, p_station_id, p_station)
interface_raise_train_dispatch_failed(train_id)
return
end
if not r_station.entity_stop.valid then
on_station_broken(map_data, r_station_id, r_station)
interface_raise_train_dispatch_failed(train_id)
return
end
set_comb2(map_data, p_station)
set_comb2(map_data, r_station)
local is_at_depot = remove_available_train(map_data, train_id, train)
--NOTE: we assume that the train is not being teleported at this time
--NOTE: set_manifest_schedule is allowed to cancel the delivery at the last second if applying the schedule to the train makes it lost and is_at_depot == false
local r_enable_inactive = mod_settings.allow_cargo_in_depot and r_station.enable_inactive--[[@as boolean]]
if set_manifest_schedule(map_data, train.entity, depot.entity_stop, not train.use_any_depot, p_station.entity_stop, p_station.enable_inactive, r_station.entity_stop, r_enable_inactive, manifest, is_at_depot) then
local old_status = train.status
train.status = STATUS_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
p_station.display_state = 1
update_display(map_data, p_station)
r_station.display_state = 1
update_display(map_data, r_station)
r_station.last_delivery_tick = map_data.total_ticks
p_station.last_delivery_tick = map_data.total_ticks
interface_raise_train_status_changed(train_id, old_status, STATUS_TO_P)
else
interface_raise_train_dispatch_failed(train_id)
end
r_station.deliveries_total = r_station.deliveries_total + 1
p_station.deliveries_total = p_station.deliveries_total + 1
local r_is_each = r_station.network_name == NETWORK_EACH
local p_is_each = p_station.network_name == NETWORK_EACH
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 or r_is_each or p_is_each then
local f, a
if r_is_each then
f, a = pairs(r_station.network_flag--[[@as {[string]: int}]])
if p_is_each then
for network_name, _ in f, a do
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
f, a = pairs(p_station.network_flag--[[@as {[string]: int}]])
end
elseif p_is_each then
f, a = pairs(p_station.network_flag--[[@as {[string]: int}]])
else
f, a = once, r_station.network_name
end
--prevent deliveries from being processed for these items until their stations are re-polled
--if we don't wait until they are repolled a duplicate delivery might be generated for stations that share inventories
for network_name, _ in f, a do
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
end
set_comb2(map_data, p_station)
set_comb2(map_data, r_station)
p_station.display_state = 1
update_display(map_data, p_station)
r_station.display_state = 1
update_display(map_data, r_station)
interface_raise_train_status_changed(train_id, old_status, STATUS_TO_P)
else
interface_raise_train_dispatch_failed(train_id)
end
end
---@param map_data MapData
---@param r_station_id uint
@@ -255,7 +277,7 @@ local function tick_dispatch(map_data, mod_settings)
for i, id in ipairs(r_stations) do
local station = stations[id]
--NOTE: the station at r_station_id could have been deleted and reregistered since last poll, this check here prevents it from being processed for a delivery in that case
if not station or station.deliveries_total >= station.entity_stop.trains_limit then
if not station or station.deliveries_total >= station.trains_limit then
goto continue
end
@@ -331,7 +353,7 @@ local function tick_dispatch(map_data, mod_settings)
local p_station_id = p_stations[j]
local p_station = stations[p_station_id]
if not p_station or p_station.deliveries_total >= p_station.entity_stop.trains_limit then
if not p_station or p_station.deliveries_total >= p_station.trains_limit then
goto p_continue
end
@@ -403,7 +425,8 @@ local function tick_dispatch(map_data, mod_settings)
end
--check if path is shortest so we prioritize locality
local t_to_p_dist = get_stop_dist(train.entity.front_stock, p_station.entity_stop) - DEPOT_PRIORITY_MULT*train.priority
local t = get_any_train_entity(train.entity)
local t_to_p_dist = t and p_station.entity_stop.valid and (get_dist(t, p_station.entity_stop) - DEPOT_PRIORITY_MULT*train.priority) or INF
if capacity == best_capacity and t_to_p_dist > best_t_to_p_dist then
goto train_continue
end
@@ -443,7 +466,7 @@ local function tick_dispatch(map_data, mod_settings)
goto p_continue
end
best_p_dist = best_t_to_p_dist + get_stop_dist(p_station.entity_stop, r_station.entity_stop)
best_p_dist = p_station.entity_stop.valid and r_station.entity_stop.valid and (best_t_to_p_dist + get_dist(p_station.entity_stop, r_station.entity_stop)) or INF
if p_prior == best_p_prior and best_p_dist > best_dist then
goto p_continue
end
@@ -501,11 +524,7 @@ local function tick_poll_station(map_data, mod_settings)
station_id = map_data.active_station_ids[tick_data.i]
station = map_data.stations[station_id]
if station then
if station_id == 70487 then
local i = 0
end
--NOTE: polling trains_limit here is expensive and not strictly necessary but using it to early out saves more ups
if station.network_name and station.deliveries_total < station.entity_stop.trains_limit then
if station.network_name then
break
end
else
@@ -514,6 +533,12 @@ local function tick_poll_station(map_data, mod_settings)
tick_data.i = tick_data.i - 1
end
end
if station.entity_stop.valid and station.entity_comb1.valid and (not station.entity_comb2 or station.entity_comb2.valid) then
station.trains_limit = station.entity_stop.trains_limit
else
on_station_broken(map_data, station_id, station)
return false
end
station.r_threshold = mod_settings.r_threshold
station.priority = mod_settings.priority
station.item_priority = nil
@@ -673,13 +698,22 @@ function tick_poll_entities(map_data, mod_settings)
local refueler_id, _ = next(map_data.each_refuelers, tick_data.last_refueler)
tick_data.last_refueler = refueler_id
if refueler_id then
set_refueler_from_comb(map_data, mod_settings, refueler_id)
local refueler = map_data.refuelers[refueler_id]
if refueler.entity_stop.valid and refueler.entity_comb.valid then
set_refueler_from_comb(map_data, mod_settings, refueler_id, refueler)
else
on_refueler_broken(map_data, refueler_id, refueler)
end
end
else
local comb_id, comb = next(map_data.to_comb, tick_data.last_comb)
tick_data.last_comb = comb_id
if comb and comb.valid then
combinator_update(map_data, comb, true)
if comb then
if comb.valid then
combinator_update(map_data, comb, true)
else
map_data.to_comb[comb_id] = nil
end
end
end
end
@@ -697,7 +731,11 @@ function tick_init(map_data, mod_settings)
if station.last_delivery_tick + mod_settings.warmup_time*mod_settings.tps < map_data.total_ticks then
map_data.active_station_ids[#map_data.active_station_ids + 1] = id
map_data.warmup_station_ids[i] = nil
combinator_update(map_data, station.entity_comb1)
if station.entity_comb1.valid then
combinator_update(map_data, station.entity_comb1)
else
on_station_broken(map_data, id, station)
end
end
else
map_data.warmup_station_ids[i] = nil
@@ -708,9 +746,13 @@ function tick_init(map_data, mod_settings)
local station = map_data.stations[id]
if station then
local pre = station.allows_all_trains
set_station_from_comb(station)
if station.allows_all_trains ~= pre then
update_stop_if_auto(map_data, station, true)
if station.entity_comb1.valid then
set_station_from_comb(station)
if station.allows_all_trains ~= pre then
update_stop_if_auto(map_data, station, true)
end
else
on_station_broken(map_data, id, station)
end
end
end

View File

@@ -15,10 +15,10 @@ function get_stack_size(map_data, item_name)
return game.item_prototypes[item_name].stack_size
end
---NOTE: does not check .valid
---@param entity0 LuaEntity
---@param entity1 LuaEntity
function get_stop_dist(entity0, entity1)
function get_dist(entity0, entity1)
local surface0 = entity0.surface.index
local surface1 = entity1.surface.index
return (surface0 == surface1 and get_distance(entity0.position, entity1.position) or DIFFERENT_SURFACE_DISTANCE)
@@ -41,7 +41,7 @@ end
---@param train LuaTrain
function get_any_train_entity(train)
return train.front_stock or train.back_stock or train.carriages[1]
return train.valid and (train.front_stock or train.back_stock or train.carriages[1]) or nil
end
@@ -109,31 +109,37 @@ end
---@param train LuaTrain
---@param depot_name string
function set_depot_schedule(train, depot_name)
train.schedule = {current = 1, records = {create_inactivity_order(depot_name)}}
if train.valid then
train.schedule = {current = 1, records = {create_inactivity_order(depot_name)}}
end
end
---@param train LuaTrain
function lock_train(train)
train.manual_mode = true
if train.valid then
train.manual_mode = true
end
end
---@param train LuaTrain
function lock_train_to_depot(train)
local schedule = train.schedule
if schedule then
local record = schedule.records[schedule.current]
if record then
local wait = record.wait_conditions
if wait and wait[1] then
wait[1].ticks = LOCK_TRAIN_TIME
if train.valid then
local schedule = train.schedule
if schedule then
local record = schedule.records[schedule.current]
if record then
local wait = record.wait_conditions
if wait and wait[1] then
wait[1].ticks = LOCK_TRAIN_TIME
else
record.wait_conditions = {{type = "inactivity", compare_type = "and", ticks = LOCK_TRAIN_TIME}}
end
train.schedule = schedule
else
record.wait_conditions = {{type = "inactivity", compare_type = "and", ticks = LOCK_TRAIN_TIME}}
train.manual_mode = true
end
train.schedule = schedule
else
train.manual_mode = true
end
else
train.manual_mode = true
end
end
@@ -141,15 +147,17 @@ end
---@param stop LuaEntity
---@param old_name string
function rename_manifest_schedule(train, stop, old_name)
local new_name = stop.backer_name
local schedule = train.schedule
if not schedule then return end
for i, record in ipairs(schedule.records) do
if record.station == old_name then
record.station = new_name
if train.valid then
local new_name = stop.backer_name
local schedule = train.schedule
if not schedule then return end
for i, record in ipairs(schedule.records) do
if record.station == old_name then
record.station = new_name
end
end
train.schedule = schedule
end
train.schedule = schedule
end
---@param elevator_name string
@@ -157,6 +165,7 @@ end
function se_create_elevator_order(elevator_name, is_train_in_orbit)
return {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
end
---NOTE: does not check .valid
---@param map_data MapData
---@param train LuaTrain
---@param depot_stop LuaEntity
@@ -281,6 +290,7 @@ function set_manifest_schedule(map_data, train, depot_stop, same_depot, p_stop,
return true
end
---NOTE: does not check .valid
---@param map_data MapData
---@param train LuaTrain
---@param stop LuaEntity
@@ -355,14 +365,8 @@ end
function get_comb_params(comb)
return comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
end
---@param comb LuaEntity
function get_comb_network_name(comb)
local params = get_comb_params(comb)
local signal = params.first_signal
return signal and signal.name or nil
end
---NOTE: does not check .valid
---@param station Station
function set_station_from_comb(station)
--NOTE: this does nothing to update currently active deliveries
@@ -387,6 +391,7 @@ function set_station_from_comb(station)
station.network_flag = {}
end
end
---NOTE: does not check .valid
---@param mod_settings CybersynModSettings
---@param train Train
---@param comb LuaEntity
@@ -437,9 +442,9 @@ end
---@param map_data MapData
---@param mod_settings CybersynModSettings
---@param id uint
function set_refueler_from_comb(map_data, mod_settings, id)
---@param refueler Refueler
function set_refueler_from_comb(map_data, mod_settings, id, refueler)
--NOTE: this does nothing to update currently active deliveries
local refueler = map_data.refuelers[id]
local params = get_comb_params(refueler.entity_comb)
local bits = params.second_constant or 0
local signal = params.first_signal
@@ -620,7 +625,6 @@ end
---@param station Station
function get_signals(station)
--NOTE: the combinator must be valid, but checking for valid every time is too slow
local comb1 = station.entity_comb1
local status1 = comb1.status
---@type Signal[]?
@@ -693,7 +697,7 @@ end
---@param train LuaTrain
function send_alert_sounds(train)
local loco = train.front_stock or train.back_stock
local loco = get_any_train_entity(train)
if loco then
for _, player in pairs(loco.force.players) do
player.play_sound({path = ALERT_SOUND})

View File

@@ -34,6 +34,7 @@
---@field public allows_all_trains true?
---@field public deliveries_total int
---@field public last_delivery_tick int
---@field public trains_limit int --transient
---@field public priority int --transient
---@field public item_priority int? --transient
---@field public r_threshold int >= 0 --transient

View File

@@ -596,14 +596,15 @@ function update_stop_from_rail(map_data, rail, forbidden_entity, force)
return
end
if entity.name == "train-stop" then
local id = entity.unit_number
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 then
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

View File

@@ -21,17 +21,19 @@ end
---@param map_data MapData
---@param depot_id uint
---@param depot Depot
local function on_depot_broken(map_data, depot_id, depot)
function on_depot_broken(map_data, depot_id, depot)
for train_id, train in pairs(map_data.trains) do
if train.depot_id == depot_id then
if train.use_any_depot then
local e = get_any_train_entity(train.entity)
local stops = e.force.get_train_stops({name = depot.entity_stop.backer_name, surface = e.surface})
for stop in rnext_consume, stops do
local new_depot_id = stop.unit_number
if map_data.depots[new_depot_id] then
train.depot_id = new_depot_id--[[@as uint]]
goto continue
if e then
local stops = e.force.get_train_stops({name = depot.entity_stop.backer_name, surface = e.surface})
for stop in rnext_consume, stops do
local new_depot_id = stop.unit_number
if map_data.depots[new_depot_id] then
train.depot_id = new_depot_id--[[@as uint]]
goto continue
end
end
end
end
@@ -63,14 +65,14 @@ local function on_refueler_built(map_data, stop, comb)
}
local id = stop.unit_number--[[@as uint]]
map_data.refuelers[id] = refueler
set_refueler_from_comb(map_data, mod_settings, id)
set_refueler_from_comb(map_data, mod_settings, id, refueler)
update_stop_if_auto(map_data, refueler, false)
interface_raise_refueler_created(id)
end
---@param map_data MapData
---@param refueler_id uint
---@param refueler Refueler
local function on_refueler_broken(map_data, refueler_id, refueler)
function on_refueler_broken(map_data, refueler_id, refueler)
if refueler.trains_total > 0 then
--search for trains coming to the destroyed refueler
for train_id, train in pairs(map_data.trains) do
@@ -121,6 +123,7 @@ local function on_station_built(map_data, stop, comb1, comb2)
--allows_all_trains = set_station_from_comb,
deliveries_total = 0,
last_delivery_tick = map_data.total_ticks,
trains_limit = math.huge,
priority = 0,
item_priotity = nil,
r_threshold = 0,
@@ -150,7 +153,7 @@ end
---@param map_data MapData
---@param station_id uint
---@param station Station
local function on_station_broken(map_data, station_id, station)
function on_station_broken(map_data, station_id, station)
if station.deliveries_total > 0 then
--search for trains coming to the destroyed station
for train_id, train in pairs(map_data.trains) do
@@ -430,7 +433,7 @@ function combinator_update(map_data, comb, reset_display)
else
local refueler = map_data.refuelers[id]
if refueler and refueler.entity_comb == comb then
set_refueler_from_comb(map_data, mod_settings, id)
set_refueler_from_comb(map_data, mod_settings, id, refueler)
end
end
end
@@ -448,7 +451,7 @@ function combinator_update(map_data, comb, reset_display)
local refueler = map_data.refuelers[id]
if refueler then
local pre = refueler.allows_all_trains
set_refueler_from_comb(map_data, mod_settings, id)
set_refueler_from_comb(map_data, mod_settings, id, refueler)
if refueler.allows_all_trains ~= pre then
update_stop_if_auto(map_data, refueler, false)
end
@@ -757,19 +760,27 @@ local function setup_se_compat()
if schedule then
if train.status == STATUS_TO_P then
local stop = map_data.stations[train.p_station_id].entity_stop
se_add_direct_to_station_order(schedule, stop, old_surface_index)
if stop.valid then
se_add_direct_to_station_order(schedule, stop, old_surface_index)
end
end
if train.status == STATUS_TO_P or train.status == STATUS_TO_R then
local stop = map_data.stations[train.r_station_id].entity_stop
se_add_direct_to_station_order(schedule, stop, old_surface_index)
if stop.valid then
se_add_direct_to_station_order(schedule, stop, old_surface_index)
end
end
if train.status == STATUS_TO_F then
local stop = map_data.refuelers[train.refueler_id].entity_stop
se_add_direct_to_station_order(schedule, stop, old_surface_index)
if stop.valid then
se_add_direct_to_station_order(schedule, stop, old_surface_index)
end
end
if not train.use_any_depot then
local depot = map_data.depots[train.depot_id]
se_add_direct_to_station_order(schedule, depot.entity_stop, old_surface_index)
local stop = map_data.depots[train.depot_id].entity_stop
if stop.valid then
se_add_direct_to_station_order(schedule, stop, old_surface_index)
end
end
train_entity.schedule = schedule
end

View File

@@ -34,18 +34,22 @@ function on_failed_delivery(map_data, train_id, train)
local is_r_in_progress = is_p_in_progress or train.status == STATUS_TO_R or train.status == STATUS_R
if is_p_in_progress then
local station = map_data.stations[p_station_id]
remove_manifest(map_data, station, manifest, 1)
if train.status == STATUS_P then
set_comb1(map_data, station, nil)
unset_wagon_combs(map_data, station)
if station.entity_comb1.valid and (not station.entity_comb2 or station.entity_comb2.valid) then
remove_manifest(map_data, station, manifest, 1)
if train.status == STATUS_P then
set_comb1(map_data, station, nil)
unset_wagon_combs(map_data, station)
end
end
end
if is_r_in_progress then
local station = map_data.stations[r_station_id]
remove_manifest(map_data, station, manifest, -1)
if train.status == STATUS_R then
set_comb1(map_data, station, nil)
unset_wagon_combs(map_data, station)
if station.entity_comb1.valid and (not station.entity_comb2 or station.entity_comb2.valid) then
remove_manifest(map_data, station, manifest, -1)
if train.status == STATUS_R then
set_comb1(map_data, station, nil)
unset_wagon_combs(map_data, station)
end
end
end
if train.has_filtered_wagon then
@@ -100,7 +104,9 @@ end
---@param train Train
function add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot)
local comb = depot.entity_comb
set_train_from_comb(mod_settings, train, comb)
if comb.valid then
set_train_from_comb(mod_settings, train, comb)
end
depot.available_train_id = train_id
train.depot_id = depot_id
train.status = STATUS_D
@@ -141,8 +147,9 @@ end
---@param map_data MapData
---@param depot_id uint
---@param depot Depot
---@param train_entity LuaTrain
local function on_train_arrives_depot(map_data, depot_id, train_entity)
local function on_train_arrives_depot(map_data, depot_id, depot, train_entity)
local is_train_empty = next(train_entity.get_contents()) == nil and next(train_entity.get_fluid_contents()) == nil
local train_id = train_entity.id
local train = map_data.trains[train_id]
@@ -161,7 +168,6 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
end
if is_train_empty or mod_settings.allow_cargo_in_depot then
local old_status = train.status
local depot = map_data.depots[depot_id]
add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot)
set_depot_schedule(train_entity, depot.entity_stop.backer_name)
interface_raise_train_status_changed(train_id, old_status, STATUS_D)
@@ -194,7 +200,6 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
}--[[@as Train]]
set_train_layout(map_data, train)
map_data.trains[train_id] = train
local depot = map_data.depots[depot_id]
add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot)
set_depot_schedule(train_entity, depot.entity_stop.backer_name)
@@ -208,20 +213,18 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
end
end
---@param map_data MapData
---@param station_id uint
---@param station Station
---@param train_id uint
---@param train Train
local function on_train_arrives_station(map_data, station_id, train_id, train)
local function on_train_arrives_station(map_data, station, train_id, train)
---@type uint
if train.status == STATUS_TO_P then
train.status = STATUS_P
local station = map_data.stations[station_id]
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and 1 or -1)
set_p_wagon_combs(map_data, station, train)
interface_raise_train_status_changed(train_id, STATUS_TO_P, STATUS_P)
elseif train.status == STATUS_TO_R then
train.status = STATUS_R
local station = map_data.stations[station_id]
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and -1 or 1)
set_r_wagon_combs(map_data, station, train)
interface_raise_train_status_changed(train_id, STATUS_TO_R, STATUS_R)
@@ -229,12 +232,11 @@ local function on_train_arrives_station(map_data, station_id, train_id, train)
end
---@param map_data MapData
---@param refueler_id uint
---@param refueler Refueler
---@param train_id uint
---@param train Train
local function on_train_arrives_refueler(map_data, refueler_id, train_id, train)
local function on_train_arrives_refueler(map_data, refueler, train_id, train)
if train.status == STATUS_TO_F then
local refueler = map_data.refuelers[refueler_id]
train.status = STATUS_F
set_refueler_combs(map_data, refueler, train)
interface_raise_train_status_changed(train_id, STATUS_TO_F, STATUS_F)
@@ -319,21 +321,23 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
local best_prior = -INF
for id, _ in pairs(refuelers) do
local refueler = map_data.refuelers[id]
set_refueler_from_comb(map_data, mod_settings, id)
if not refueler.entity_stop.valid or not refueler.entity_comb.valid then
on_refueler_broken(map_data, id, refueler)
else
set_refueler_from_comb(map_data, mod_settings, id, refueler)
local refueler_network_flag = get_network_flag(refueler, network_name)
local train_network_flag = get_network_flag(train, network_name)
if btest(train_network_flag, refueler_network_flag) and (refueler.allows_all_trains or refueler.accepted_layouts[train.layout_id]) and refueler.trains_total < refueler.entity_stop.trains_limit then
local accepted = false
local dist = nil
if refueler.priority == best_prior then
dist = get_stop_dist(train.entity.front_stock, refueler.entity_stop)
accepted = dist < best_dist
end
if accepted or refueler.priority > best_prior then
best_refueler_id = id
best_dist = dist or get_stop_dist(train.entity.front_stock, refueler.entity_stop)
best_prior = refueler.priority
local refueler_network_flag = get_network_flag(refueler, network_name)
local train_network_flag = get_network_flag(train, network_name)
if btest(train_network_flag, refueler_network_flag) and (refueler.allows_all_trains or refueler.accepted_layouts[train.layout_id]) and refueler.trains_total < refueler.entity_stop.trains_limit then
if refueler.priority >= best_prior then
local t = get_any_train_entity(train.entity)
local dist = t and get_dist(t, refueler.entity_stop) or INF
if refueler.priority > best_prior or dist < best_dist then
best_refueler_id = id
best_dist = dist
best_prior = refueler.priority
end
end
end
end
end
@@ -358,7 +362,9 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
train.refueler_id = nil
refueler.trains_total = refueler.trains_total - 1
unset_wagon_combs(map_data, refueler)
set_combinator_output(map_data, refueler.entity_comb, nil)
if refueler.entity_comb.valid then
set_combinator_output(map_data, refueler.entity_comb, nil)
end
if not train.disable_bypass then
train.status = STATUS_TO_D_BYPASS
add_available_train(map_data, train_id, train)
@@ -427,8 +433,13 @@ function on_train_changed(event)
local stop = train_e.station
if stop and stop.valid and stop.name == "train-stop" then
local id = stop.unit_number--[[@as uint]]
if map_data.depots[id] then
on_train_arrives_depot(map_data, id, train_e)
local depot = map_data.depots[id]
if depot then
if depot.entity_comb.valid and depot.entity_stop.valid then
on_train_arrives_depot(map_data, id, depot, train_e)
else
on_depot_broken(map_data, id, depot)
end
end
else
local train = map_data.trains[train_id]
@@ -451,11 +462,13 @@ function on_train_changed(event)
station = map_data.refuelers[id]
is_station = false
end
if id and station.entity_stop.connected_rail == rail then
if id and station.entity_stop.valid and station.entity_stop.connected_rail == rail then
if is_station then
on_train_arrives_station(map_data, id, train_id, train)
else
on_train_arrives_refueler(map_data, id, train_id, train)
if station.entity_comb1 and (not station.entity_comb2 or station.entity_comb2.valid) then
on_train_arrives_station(map_data, station, train_id, train)
end
elseif station.entity_comb.valid then
on_train_arrives_refueler(map_data, station, train_id, train)
end
end
end