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,11 +42,33 @@ function create_delivery(map_data, r_station_id, p_station_id, train_id, manifes
local train = map_data.trains[train_id] local train = map_data.trains[train_id]
local depot = map_data.depots[train.depot_id] local depot = map_data.depots[train.depot_id]
local is_at_depot = remove_available_train(map_data, train_id, train)
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
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: 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 --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
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 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 local old_status = train.status
train.status = STATUS_TO_P train.status = STATUS_TO_P
train.p_station_id = p_station_id train.p_station_id = p_station_id
@@ -255,7 +277,7 @@ local function tick_dispatch(map_data, mod_settings)
for i, id in ipairs(r_stations) do for i, id in ipairs(r_stations) do
local station = stations[id] 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 --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 goto continue
end end
@@ -331,7 +353,7 @@ local function tick_dispatch(map_data, mod_settings)
local p_station_id = p_stations[j] local p_station_id = p_stations[j]
local p_station = stations[p_station_id] 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 goto p_continue
end end
@@ -403,7 +425,8 @@ local function tick_dispatch(map_data, mod_settings)
end end
--check if path is shortest so we prioritize locality --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 if capacity == best_capacity and t_to_p_dist > best_t_to_p_dist then
goto train_continue goto train_continue
end end
@@ -443,7 +466,7 @@ local function tick_dispatch(map_data, mod_settings)
goto p_continue goto p_continue
end 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 if p_prior == best_p_prior and best_p_dist > best_dist then
goto p_continue goto p_continue
end 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_id = map_data.active_station_ids[tick_data.i]
station = map_data.stations[station_id] station = map_data.stations[station_id]
if station then if station then
if station_id == 70487 then if station.network_name 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
break break
end end
else else
@@ -514,6 +533,12 @@ local function tick_poll_station(map_data, mod_settings)
tick_data.i = tick_data.i - 1 tick_data.i = tick_data.i - 1
end end
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.r_threshold = mod_settings.r_threshold
station.priority = mod_settings.priority station.priority = mod_settings.priority
station.item_priority = nil 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) local refueler_id, _ = next(map_data.each_refuelers, tick_data.last_refueler)
tick_data.last_refueler = refueler_id tick_data.last_refueler = refueler_id
if refueler_id then 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 end
else else
local comb_id, comb = next(map_data.to_comb, tick_data.last_comb) local comb_id, comb = next(map_data.to_comb, tick_data.last_comb)
tick_data.last_comb = comb_id tick_data.last_comb = comb_id
if comb and comb.valid then if comb then
if comb.valid then
combinator_update(map_data, comb, true) combinator_update(map_data, comb, true)
else
map_data.to_comb[comb_id] = nil
end
end end
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 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.active_station_ids[#map_data.active_station_ids + 1] = id
map_data.warmup_station_ids[i] = nil map_data.warmup_station_ids[i] = nil
if station.entity_comb1.valid then
combinator_update(map_data, station.entity_comb1) combinator_update(map_data, station.entity_comb1)
else
on_station_broken(map_data, id, station)
end
end end
else else
map_data.warmup_station_ids[i] = nil map_data.warmup_station_ids[i] = nil
@@ -708,10 +746,14 @@ function tick_init(map_data, mod_settings)
local station = map_data.stations[id] local station = map_data.stations[id]
if station then if station then
local pre = station.allows_all_trains local pre = station.allows_all_trains
if station.entity_comb1.valid then
set_station_from_comb(station) set_station_from_comb(station)
if station.allows_all_trains ~= pre then if station.allows_all_trains ~= pre then
update_stop_if_auto(map_data, station, true) update_stop_if_auto(map_data, station, true)
end end
else
on_station_broken(map_data, id, station)
end
end end
end end
map_data.queue_station_update = nil map_data.queue_station_update = nil

View File

@@ -15,10 +15,10 @@ function get_stack_size(map_data, item_name)
return game.item_prototypes[item_name].stack_size return game.item_prototypes[item_name].stack_size
end end
---NOTE: does not check .valid
---@param entity0 LuaEntity ---@param entity0 LuaEntity
---@param entity1 LuaEntity ---@param entity1 LuaEntity
function get_stop_dist(entity0, entity1) function get_dist(entity0, entity1)
local surface0 = entity0.surface.index local surface0 = entity0.surface.index
local surface1 = entity1.surface.index local surface1 = entity1.surface.index
return (surface0 == surface1 and get_distance(entity0.position, entity1.position) or DIFFERENT_SURFACE_DISTANCE) return (surface0 == surface1 and get_distance(entity0.position, entity1.position) or DIFFERENT_SURFACE_DISTANCE)
@@ -41,7 +41,7 @@ end
---@param train LuaTrain ---@param train LuaTrain
function get_any_train_entity(train) 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 end
@@ -109,15 +109,20 @@ end
---@param train LuaTrain ---@param train LuaTrain
---@param depot_name string ---@param depot_name string
function set_depot_schedule(train, depot_name) function set_depot_schedule(train, depot_name)
if train.valid then
train.schedule = {current = 1, records = {create_inactivity_order(depot_name)}} train.schedule = {current = 1, records = {create_inactivity_order(depot_name)}}
end end
end
---@param train LuaTrain ---@param train LuaTrain
function lock_train(train) function lock_train(train)
if train.valid then
train.manual_mode = true train.manual_mode = true
end end
end
---@param train LuaTrain ---@param train LuaTrain
function lock_train_to_depot(train) function lock_train_to_depot(train)
if train.valid then
local schedule = train.schedule local schedule = train.schedule
if schedule then if schedule then
local record = schedule.records[schedule.current] local record = schedule.records[schedule.current]
@@ -136,11 +141,13 @@ function lock_train_to_depot(train)
train.manual_mode = true train.manual_mode = true
end end
end end
end
---@param train LuaTrain ---@param train LuaTrain
---@param stop LuaEntity ---@param stop LuaEntity
---@param old_name string ---@param old_name string
function rename_manifest_schedule(train, stop, old_name) function rename_manifest_schedule(train, stop, old_name)
if train.valid then
local new_name = stop.backer_name local new_name = stop.backer_name
local schedule = train.schedule local schedule = train.schedule
if not schedule then return end if not schedule then return end
@@ -151,12 +158,14 @@ function rename_manifest_schedule(train, stop, old_name)
end end
train.schedule = schedule train.schedule = schedule
end end
end
---@param elevator_name string ---@param elevator_name string
---@param is_train_in_orbit boolean ---@param is_train_in_orbit boolean
function se_create_elevator_order(elevator_name, is_train_in_orbit) 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)} return {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
end end
---NOTE: does not check .valid
---@param map_data MapData ---@param map_data MapData
---@param train LuaTrain ---@param train LuaTrain
---@param depot_stop LuaEntity ---@param depot_stop LuaEntity
@@ -281,6 +290,7 @@ function set_manifest_schedule(map_data, train, depot_stop, same_depot, p_stop,
return true return true
end end
---NOTE: does not check .valid
---@param map_data MapData ---@param map_data MapData
---@param train LuaTrain ---@param train LuaTrain
---@param stop LuaEntity ---@param stop LuaEntity
@@ -355,14 +365,8 @@ end
function get_comb_params(comb) function get_comb_params(comb)
return comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]] return comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
end 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 ---@param station Station
function set_station_from_comb(station) function set_station_from_comb(station)
--NOTE: this does nothing to update currently active deliveries --NOTE: this does nothing to update currently active deliveries
@@ -387,6 +391,7 @@ function set_station_from_comb(station)
station.network_flag = {} station.network_flag = {}
end end
end end
---NOTE: does not check .valid
---@param mod_settings CybersynModSettings ---@param mod_settings CybersynModSettings
---@param train Train ---@param train Train
---@param comb LuaEntity ---@param comb LuaEntity
@@ -437,9 +442,9 @@ end
---@param map_data MapData ---@param map_data MapData
---@param mod_settings CybersynModSettings ---@param mod_settings CybersynModSettings
---@param id uint ---@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 --NOTE: this does nothing to update currently active deliveries
local refueler = map_data.refuelers[id]
local params = get_comb_params(refueler.entity_comb) local params = get_comb_params(refueler.entity_comb)
local bits = params.second_constant or 0 local bits = params.second_constant or 0
local signal = params.first_signal local signal = params.first_signal
@@ -620,7 +625,6 @@ end
---@param station Station ---@param station Station
function get_signals(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 comb1 = station.entity_comb1
local status1 = comb1.status local status1 = comb1.status
---@type Signal[]? ---@type Signal[]?
@@ -693,7 +697,7 @@ end
---@param train LuaTrain ---@param train LuaTrain
function send_alert_sounds(train) function send_alert_sounds(train)
local loco = train.front_stock or train.back_stock local loco = get_any_train_entity(train)
if loco then if loco then
for _, player in pairs(loco.force.players) do for _, player in pairs(loco.force.players) do
player.play_sound({path = ALERT_SOUND}) player.play_sound({path = ALERT_SOUND})

View File

@@ -34,6 +34,7 @@
---@field public allows_all_trains true? ---@field public allows_all_trains true?
---@field public deliveries_total int ---@field public deliveries_total int
---@field public last_delivery_tick int ---@field public last_delivery_tick int
---@field public trains_limit int --transient
---@field public priority int --transient ---@field public priority int --transient
---@field public item_priority int? --transient ---@field public item_priority int? --transient
---@field public r_threshold int >= 0 --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 return
end end
if entity.name == "train-stop" then if entity.name == "train-stop" then
local id = entity.unit_number local id = entity.unit_number--[[@as uint]]
local is_station = true local is_station = true
---@type Station|Refueler
local stop = map_data.stations[id] local stop = map_data.stations[id]
if not stop then if not stop then
stop = map_data.refuelers[id] stop = map_data.refuelers[id]
is_station = false is_station = false
end end
if stop then if stop and stop.entity_stop.valid then
if force then if force then
reset_stop_layout(map_data, stop, is_station, forbidden_entity) reset_stop_layout(map_data, stop, is_station, forbidden_entity)
elseif not stop.allows_all_trains then elseif not stop.allows_all_trains then

View File

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

View File

@@ -34,20 +34,24 @@ 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 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 if is_p_in_progress then
local station = map_data.stations[p_station_id] local station = map_data.stations[p_station_id]
if station.entity_comb1.valid and (not station.entity_comb2 or station.entity_comb2.valid) then
remove_manifest(map_data, station, manifest, 1) remove_manifest(map_data, station, manifest, 1)
if train.status == STATUS_P then if train.status == STATUS_P then
set_comb1(map_data, station, nil) set_comb1(map_data, station, nil)
unset_wagon_combs(map_data, station) unset_wagon_combs(map_data, station)
end end
end end
end
if is_r_in_progress then if is_r_in_progress then
local station = map_data.stations[r_station_id] local station = map_data.stations[r_station_id]
if station.entity_comb1.valid and (not station.entity_comb2 or station.entity_comb2.valid) then
remove_manifest(map_data, station, manifest, -1) remove_manifest(map_data, station, manifest, -1)
if train.status == STATUS_R then if train.status == STATUS_R then
set_comb1(map_data, station, nil) set_comb1(map_data, station, nil)
unset_wagon_combs(map_data, station) unset_wagon_combs(map_data, station)
end end
end end
end
if train.has_filtered_wagon then if train.has_filtered_wagon then
train.has_filtered_wagon = nil train.has_filtered_wagon = nil
for carriage_i, carriage in ipairs(train.entity.cargo_wagons) do for carriage_i, carriage in ipairs(train.entity.cargo_wagons) do
@@ -100,7 +104,9 @@ end
---@param train Train ---@param train Train
function add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot) function add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot)
local comb = depot.entity_comb local comb = depot.entity_comb
if comb.valid then
set_train_from_comb(mod_settings, train, comb) set_train_from_comb(mod_settings, train, comb)
end
depot.available_train_id = train_id depot.available_train_id = train_id
train.depot_id = depot_id train.depot_id = depot_id
train.status = STATUS_D train.status = STATUS_D
@@ -141,8 +147,9 @@ end
---@param map_data MapData ---@param map_data MapData
---@param depot_id uint ---@param depot_id uint
---@param depot Depot
---@param train_entity LuaTrain ---@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 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_id = train_entity.id
local train = map_data.trains[train_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 end
if is_train_empty or mod_settings.allow_cargo_in_depot then if is_train_empty or mod_settings.allow_cargo_in_depot then
local old_status = train.status 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) 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) set_depot_schedule(train_entity, depot.entity_stop.backer_name)
interface_raise_train_status_changed(train_id, old_status, STATUS_D) 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]] }--[[@as Train]]
set_train_layout(map_data, train) set_train_layout(map_data, train)
map_data.trains[train_id] = 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) 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) 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
end end
---@param map_data MapData ---@param map_data MapData
---@param station_id uint ---@param station Station
---@param train_id uint ---@param train_id uint
---@param train Train ---@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 ---@type uint
if train.status == STATUS_TO_P then if train.status == STATUS_TO_P then
train.status = STATUS_P 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_comb1(map_data, station, train.manifest, mod_settings.invert_sign and 1 or -1)
set_p_wagon_combs(map_data, station, train) set_p_wagon_combs(map_data, station, train)
interface_raise_train_status_changed(train_id, STATUS_TO_P, STATUS_P) interface_raise_train_status_changed(train_id, STATUS_TO_P, STATUS_P)
elseif train.status == STATUS_TO_R then elseif train.status == STATUS_TO_R then
train.status = STATUS_R 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_comb1(map_data, station, train.manifest, mod_settings.invert_sign and -1 or 1)
set_r_wagon_combs(map_data, station, train) set_r_wagon_combs(map_data, station, train)
interface_raise_train_status_changed(train_id, STATUS_TO_R, STATUS_R) 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 end
---@param map_data MapData ---@param map_data MapData
---@param refueler_id uint ---@param refueler Refueler
---@param train_id uint ---@param train_id uint
---@param train Train ---@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 if train.status == STATUS_TO_F then
local refueler = map_data.refuelers[refueler_id]
train.status = STATUS_F train.status = STATUS_F
set_refueler_combs(map_data, refueler, train) set_refueler_combs(map_data, refueler, train)
interface_raise_train_status_changed(train_id, STATUS_TO_F, STATUS_F) interface_raise_train_status_changed(train_id, STATUS_TO_F, STATUS_F)
@@ -319,24 +321,26 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
local best_prior = -INF local best_prior = -INF
for id, _ in pairs(refuelers) do for id, _ in pairs(refuelers) do
local refueler = map_data.refuelers[id] 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 refueler_network_flag = get_network_flag(refueler, network_name)
local train_network_flag = get_network_flag(train, 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 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 if refueler.priority >= best_prior then
local dist = nil local t = get_any_train_entity(train.entity)
if refueler.priority == best_prior then local dist = t and get_dist(t, refueler.entity_stop) or INF
dist = get_stop_dist(train.entity.front_stock, refueler.entity_stop) if refueler.priority > best_prior or dist < best_dist then
accepted = dist < best_dist
end
if accepted or refueler.priority > best_prior then
best_refueler_id = id best_refueler_id = id
best_dist = dist or get_stop_dist(train.entity.front_stock, refueler.entity_stop) best_dist = dist
best_prior = refueler.priority best_prior = refueler.priority
end end
end end
end end
end
end
if best_refueler_id then if best_refueler_id then
local refueler = map_data.refuelers[best_refueler_id] local refueler = map_data.refuelers[best_refueler_id]
if add_refueler_schedule(map_data, train.entity, refueler.entity_stop) then if add_refueler_schedule(map_data, train.entity, refueler.entity_stop) then
@@ -358,7 +362,9 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
train.refueler_id = nil train.refueler_id = nil
refueler.trains_total = refueler.trains_total - 1 refueler.trains_total = refueler.trains_total - 1
unset_wagon_combs(map_data, refueler) unset_wagon_combs(map_data, refueler)
if refueler.entity_comb.valid then
set_combinator_output(map_data, refueler.entity_comb, nil) set_combinator_output(map_data, refueler.entity_comb, nil)
end
if not train.disable_bypass then if not train.disable_bypass then
train.status = STATUS_TO_D_BYPASS train.status = STATUS_TO_D_BYPASS
add_available_train(map_data, train_id, train) add_available_train(map_data, train_id, train)
@@ -427,8 +433,13 @@ function on_train_changed(event)
local stop = train_e.station local stop = train_e.station
if stop and stop.valid and stop.name == "train-stop" then if stop and stop.valid and stop.name == "train-stop" then
local id = stop.unit_number--[[@as uint]] local id = stop.unit_number--[[@as uint]]
if map_data.depots[id] then local depot = map_data.depots[id]
on_train_arrives_depot(map_data, id, train_e) 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 end
else else
local train = map_data.trains[train_id] local train = map_data.trains[train_id]
@@ -451,11 +462,13 @@ function on_train_changed(event)
station = map_data.refuelers[id] station = map_data.refuelers[id]
is_station = false is_station = false
end 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 if is_station then
on_train_arrives_station(map_data, id, train_id, train) if station.entity_comb1 and (not station.entity_comb2 or station.entity_comb2.valid) then
else on_train_arrives_station(map_data, station, train_id, train)
on_train_arrives_refueler(map_data, id, train_id, train) end
elseif station.entity_comb.valid then
on_train_arrives_refueler(map_data, station, train_id, train)
end end
end end
end end