added depot bypass

This commit is contained in:
Monica Moniot
2022-12-01 01:00:53 -05:00
parent ac09811324
commit a26ed161c6
8 changed files with 102 additions and 56 deletions

View File

@@ -3,6 +3,7 @@ cybersyn-ticks-per-second=Central planning updates per second
cybersyn-update-rate=Central planning update rate cybersyn-update-rate=Central planning update rate
cybersyn-request-threshold=Default requester threshold cybersyn-request-threshold=Default requester threshold
cybersyn-network-flag=Default network mask cybersyn-network-flag=Default network mask
cybersyn-depot-bypass-threshold=Depot bypass fuel threshold
cybersyn-warmup-time=Station warmup time (sec) cybersyn-warmup-time=Station warmup time (sec)
cybersyn-stuck-train-time=Stuck train timeout (sec) cybersyn-stuck-train-time=Stuck train timeout (sec)
@@ -11,6 +12,7 @@ cybersyn-ticks-per-second=How many times per second the central planner should u
cybersyn-update-rate=How many stations per tick can be polled at once or can have deliveries scheduled at once. Larger number allow the central planner to keep more up to date on the current state of the network, but at the cost of performance. cybersyn-update-rate=How many stations per tick can be polled at once or can have deliveries scheduled at once. Larger number allow the central planner to keep more up to date on the current state of the network, but at the cost of performance.
cybersyn-request-threshold=The default request threshold when a request threshold signal is not given to a station. When a station receives a negative item signal that surpasses its request threshold, so long as any station exists with a positive signal greater than the request threshold, a delivery of that item will be scheduled between the two stations. cybersyn-request-threshold=The default request threshold when a request threshold signal is not given to a station. When a station receives a negative item signal that surpasses its request threshold, so long as any station exists with a positive signal greater than the request threshold, a delivery of that item will be scheduled between the two stations.
cybersyn-network-flag=The default set of sub-networks a station will service when no network signal is given to a station. This integer is interpretted bit-wise to give 32 possible sub-networks to choose from. cybersyn-network-flag=The default set of sub-networks a station will service when no network signal is given to a station. This integer is interpretted bit-wise to give 32 possible sub-networks to choose from.
cybersyn-depot-bypass-threshold=What percentage of the fuel inventory of the a train must be full to activate depot bypass. When a train qualifies for depot bypass, it may take a new order from the network before having to return to its depot, dramatically reducing travel time. If this is set to 1, depot bypass will be disabled.
cybersyn-warmup-time=How many seconds a cybernetic combinator will wait before connecting to the Cybersyn network. This is a grace period to modify or correct the circuit network before trains start dispatching to a newly blueprinted station. cybersyn-warmup-time=How many seconds a cybernetic combinator will wait before connecting to the Cybersyn network. This is a grace period to modify or correct the circuit network before trains start dispatching to a newly blueprinted station.
cybersyn-stuck-train-time=After this many seconds from a train's dispatch, an alert will be sent to let you know a train is probably stuck and has not completed its delivery. The player will likely have to debug their network to get the train unstuck. cybersyn-stuck-train-time=After this many seconds from a train's dispatch, an alert will be sent to let you know a train is probably stuck and has not completed its delivery. The player will likely have to debug their network to get the train unstuck.

View File

@@ -191,13 +191,21 @@ local function send_train_between(map_data, r_station_id, p_station_id, train_id
end end
remove_available_train(map_data, train_id, train) remove_available_train(map_data, train_id, train)
local depot_id = train.depot_id
if depot_id then
map_data.depots[depot_id].available_train_id = nil
train.depot_id = nil
else
local test
end
train.status = STATUS_D_TO_P train.status = STATUS_D_TO_P
train.p_station_id = p_station_id train.p_station_id = p_station_id
train.r_station_id = r_station_id train.r_station_id = r_station_id
train.manifest = manifest train.manifest = manifest
train.last_manifest_tick = map_data.total_ticks train.last_manifest_tick = map_data.total_ticks
set_manifest_schedule(train.entity, train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest) set_manifest_schedule(train.entity, train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest, depot_id ~= nil)
set_comb2(map_data, p_station) set_comb2(map_data, p_station)
set_comb2(map_data, r_station) set_comb2(map_data, r_station)
if p_station.entity_comb1.valid then if p_station.entity_comb1.valid then

View File

@@ -111,7 +111,8 @@ end
---@param p_stop LuaEntity ---@param p_stop LuaEntity
---@param r_stop LuaEntity ---@param r_stop LuaEntity
---@param manifest Manifest ---@param manifest Manifest
function set_manifest_schedule(train, depot_name, p_stop, r_stop, manifest) ---@param start_at_depot boolean?
function set_manifest_schedule(train, depot_name, p_stop, r_stop, manifest, start_at_depot)
--NOTE: train must be on same surface as depot_stop --NOTE: train must be on same surface as depot_stop
local d_surface = train.front_stock.surface local d_surface = train.front_stock.surface
local p_surface = p_stop.surface local p_surface = p_stop.surface
@@ -120,7 +121,7 @@ function set_manifest_schedule(train, depot_name, p_stop, r_stop, manifest)
local p_surface_i = p_surface.index local p_surface_i = p_surface.index
local r_surface_i = r_surface.index local r_surface_i = r_surface.index
if d_surface_i == p_surface_i and p_surface_i == r_surface_i then if d_surface_i == p_surface_i and p_surface_i == r_surface_i then
train.schedule = {current = 1, records = { train.schedule = {current = start_at_depot and 1 or 2, records = {
create_inactivity_order(depot_name), create_inactivity_order(depot_name),
create_direct_to_station_order(p_stop), create_direct_to_station_order(p_stop),
create_loading_order(p_stop, manifest), create_loading_order(p_stop, manifest),

View File

@@ -83,6 +83,7 @@
---@field public network_flag int ---@field public network_flag int
---@field public warmup_time double ---@field public warmup_time double
---@field public stuck_train_time double ---@field public stuck_train_time double
---@field public depot_bypass_threshold double
---@type CybersynModSettings ---@type CybersynModSettings
mod_settings = {} mod_settings = {}

View File

@@ -52,15 +52,15 @@ local function is_layout_accepted(layout_pattern, layout)
end end
---@param map_data MapData ---@param map_data MapData
---@param train Train
---@param train_id uint ---@param train_id uint
function remove_train(map_data, train, train_id) ---@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.depot_id
if parked_at_depot_id then if parked_at_depot_id then
local depot = map_data.depots[parked_at_depot_id] local depot = map_data.depots[parked_at_depot_id]
remove_available_train(map_data, parked_at_depot_id, train)
depot.available_train_id = nil depot.available_train_id = nil
end end
remove_available_train(map_data, train_id, train)
local layout_id = train.layout_id local layout_id = train.layout_id
local count = map_data.layout_train_count[layout_id] local count = map_data.layout_train_count[layout_id]
if count <= 1 then if count <= 1 then

View File

@@ -147,9 +147,7 @@ local function on_depot_broken(map_data, depot)
local train = map_data.trains[train_id] local train = map_data.trains[train_id]
lock_train(train.entity) lock_train(train.entity)
send_lost_train_alert(train.entity, depot.entity_stop.backer_name) send_lost_train_alert(train.entity, depot.entity_stop.backer_name)
remove_available_train(map_data, train_id, train) remove_train(map_data, train_id, train)
map_data.trains[train_id] = nil
depot.available_train_id = nil
end end
map_data.depots[depot.entity_stop.unit_number] = nil map_data.depots[depot.entity_stop.unit_number] = nil
end end
@@ -198,7 +196,7 @@ local function on_station_broken(map_data, station_id, station)
--train is attempting delivery to a stop that was destroyed, stop it --train is attempting delivery to a stop that was destroyed, stop it
on_failed_delivery(map_data, train) on_failed_delivery(map_data, train)
if train.entity then if train.entity then
remove_train(map_data, train, train_id) remove_train(map_data, train_id, train)
lock_train(train.entity) lock_train(train.entity)
send_lost_train_alert(train.entity, train.depot_name) send_lost_train_alert(train.entity, train.depot_name)
else else
@@ -367,7 +365,6 @@ function on_combinator_network_updated(map_data, comb, network_name)
if train_id then if train_id then
local train = map_data.trains[train_id] local train = map_data.trains[train_id]
remove_available_train(map_data, train_id, train) remove_available_train(map_data, train_id, train)
depot.available_train_id = nil
add_available_train_to_depot(map_data, train_id, train, depot_id, depot) add_available_train_to_depot(map_data, train_id, train, depot_id, depot)
end end
end end
@@ -598,26 +595,25 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
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]
if train then if train then
remove_available_train(map_data, train_id, train) if train.manifest then
if train.manifest and train.status == STATUS_R_TO_D then if train.status == STATUS_R_TO_D then
--succeeded delivery --succeeded delivery
train.p_station_id = 0 train.p_station_id = 0
train.r_station_id = 0 train.r_station_id = 0
train.manifest = nil train.manifest = nil
add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id]) else
else
if train.manifest then
on_failed_delivery(map_data, train) on_failed_delivery(map_data, train)
send_unexpected_train_alert(train.entity) send_unexpected_train_alert(train.entity)
end end
add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id])
end end
if is_train_empty then if is_train_empty then
remove_available_train(map_data, train_id, train)
add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id])
set_depot_schedule(train_entity, train.depot_name) set_depot_schedule(train_entity, train.depot_name)
else else
--train still has cargo --train still has cargo
lock_train(train_entity) lock_train(train_entity)
remove_train(map_data, train, train_id) remove_train(map_data, train_id, train)
send_nonempty_train_in_depot_alert(train_entity) send_nonempty_train_in_depot_alert(train_entity)
end end
elseif is_train_empty then elseif is_train_empty then
@@ -644,8 +640,9 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
end end
---@param map_data MapData ---@param map_data MapData
---@param stop LuaEntity ---@param stop LuaEntity
---@param train_id uint
---@param train Train ---@param train Train
local function on_train_arrives_buffer(map_data, stop, train) local function on_train_arrives_buffer(map_data, stop, train_id, train)
if train.manifest then if train.manifest then
---@type uint ---@type uint
local station_id = stop.unit_number local station_id = stop.unit_number
@@ -669,19 +666,20 @@ local function on_train_arrives_buffer(map_data, stop, train)
--this player intervention that is considered valid --this player intervention that is considered valid
else else
on_failed_delivery(map_data, train) on_failed_delivery(map_data, train)
remove_train(map_data, train, train.entity.id) remove_train(map_data, train_id, train)
lock_train(train.entity) lock_train(train.entity)
send_lost_train_alert(train.entity, train.depot_name) send_lost_train_alert(train.entity, train.depot_name)
end end
else else
--train is lost somehow, probably from player intervention --train is lost somehow, probably from player intervention
remove_train(map_data, train, train.entity.id) remove_train(map_data, train_id, train)
end end
end end
---@param map_data MapData ---@param map_data MapData
---@param mod_settings CybersynModSettings
---@param train_id uint ---@param train_id uint
---@param train Train ---@param train Train
local function on_train_leaves_station(map_data, train_id, train) local function on_train_leaves_station(map_data, mod_settings, train_id, train)
if train.manifest then if train.manifest then
if train.status == STATUS_P then if train.status == STATUS_P then
train.status = STATUS_P_TO_R train.status = STATUS_P_TO_R
@@ -691,14 +689,12 @@ local function on_train_leaves_station(map_data, train_id, train)
unset_wagon_combs(map_data, station) unset_wagon_combs(map_data, station)
if train.has_filtered_wagon then if train.has_filtered_wagon then
train.has_filtered_wagon = false train.has_filtered_wagon = false
for carriage_i, carriage in ipairs(train.entity.carriages) do for carriage_i, carriage in ipairs(train.entity.cargo_wagons) do
if carriage.type == "cargo-wagon" then local inv = carriage.get_inventory(defines.inventory.cargo_wagon)
local inv = carriage.get_inventory(defines.inventory.cargo_wagon) if inv and inv.is_filtered() then
if inv and inv.is_filtered() then ---@type uint
---@type uint for i = 1, #inv do
for i = 1, #inv do inv.set_filter(i, nil)
inv.set_filter(i, nil)
end
end end
end end
end end
@@ -709,41 +705,61 @@ local function on_train_leaves_station(map_data, train_id, train)
remove_manifest(map_data, station, train.manifest, -1) remove_manifest(map_data, station, train.manifest, -1)
set_comb1(map_data, station, nil) set_comb1(map_data, station, nil)
unset_wagon_combs(map_data, station) unset_wagon_combs(map_data, station)
--add to available trains for depot bypass
local fuel_fill = 0
local total_slots = 0
for k, v in pairs(train.entity.locomotives) do
if v[1] then
local inv = v[1].get_fuel_inventory()
if inv then
local inv_size = #inv
total_slots = total_slots + inv_size
for i = 1, inv_size do
local item = inv[i--[[@as uint]]]
local count = item.count
if count > 0 then
fuel_fill = fuel_fill + count/get_stack_size(map_data, item.name)
end
end
end
end
end
--if total_slots == 0 it's probably a modded electric train
if total_slots == 0 or fuel_fill/total_slots > mod_settings.depot_bypass_threshold then
add_available_train(map_data, train_id, train)
end
end end
elseif train.status == STATUS_D then 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.depot_id--[[@as uint]]]
remove_available_train(map_data, train_id, train) send_lost_train_alert(train.entity, depot.entity_stop.backer_name)
depot.available_train_id = nil remove_train(map_data, train_id, train)
end end
end end
---@param map_data MapData ---@param map_data MapData
---@param train_id uint
---@param train Train ---@param train Train
local function on_train_broken(map_data, 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 --NOTE: train.entity is only absent if the train is climbing a space elevator as of 0.5.0
if train.manifest and train.entity then if train.entity then
on_failed_delivery(map_data, train) if train.manifest then
remove_train(map_data, train, train.entity.id) on_failed_delivery(map_data, train)
if train.entity.valid then
lock_train(train.entity)
end end
remove_train(map_data, train_id, train)
end end
end end
---@param map_data MapData ---@param map_data MapData
---@param pre_train_id uint ---@param pre_train_id uint
---@param train_entity LuaEntity local function on_train_modified(map_data, pre_train_id)
local function on_train_modified(map_data, pre_train_id, train_entity)
local train = map_data.trains[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 --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 train.entity then
if train.manifest then if train.manifest then
on_failed_delivery(map_data, train) on_failed_delivery(map_data, train)
end end
remove_train(map_data, train, pre_train_id) remove_train(map_data, pre_train_id, train)
if train.entity.valid then
lock_train(train.entity)
end
end end
end end
@@ -779,9 +795,10 @@ local function on_broken(event)
elseif entity.type == "straight-rail" then elseif entity.type == "straight-rail" then
update_station_from_rail(global, entity, nil) update_station_from_rail(global, entity, nil)
elseif entity.train then elseif entity.train then
local train = global.trains[entity.train.id] local train_id = entity.train.id
local train = global.trains[train_id]
if train then if train then
on_train_broken(global, train) on_train_broken(global, train_id, train)
end end
end end
end end
@@ -802,10 +819,10 @@ end
local function on_train_built(event) local function on_train_built(event)
local train_e = event.train local train_e = event.train
if event.old_train_id_1 then if event.old_train_id_1 then
on_train_modified(global, event.old_train_id_1, train_e) on_train_modified(global, event.old_train_id_1)
end end
if event.old_train_id_2 then if event.old_train_id_2 then
on_train_modified(global, event.old_train_id_2, train_e) on_train_modified(global, event.old_train_id_2)
end end
end end
local function on_train_changed(event) local function on_train_changed(event)
@@ -829,7 +846,7 @@ local function on_train_changed(event)
end end
elseif event.old_state == defines.train_state.wait_station then elseif event.old_state == defines.train_state.wait_station then
if train then if train then
on_train_leaves_station(global, train_id, train) on_train_leaves_station(global, mod_settings, train_id, train)
end end
end end
end end
@@ -862,6 +879,7 @@ local function on_settings_changed(event)
mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]] mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]]
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]] mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]] mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]]
mod_settings.depot_bypass_threshold = settings.global["cybersyn-depot-bypass-threshold"].value--[[@as double]]
mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]] mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]]
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]] mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
if event.setting == "cybersyn-ticks-per-second" then if event.setting == "cybersyn-ticks-per-second" then
@@ -896,6 +914,7 @@ local function main()
mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]] mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]]
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]] mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]] mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]]
mod_settings.depot_bypass_threshold = settings.global["cybersyn-depot-bypass-threshold"].value--[[@as double]]
mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]] mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]]
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]] mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
@@ -980,7 +999,7 @@ local function main()
train.entity = train_entity train.entity = train_entity
if train.se_awaiting_removal then if train.se_awaiting_removal then
remove_train(map_data, train, train.se_awaiting_removal) remove_train(map_data, train.se_awaiting_removal, train)
lock_train(train.entity) lock_train(train.entity)
send_lost_train_alert(train.entity, train.depot_name) send_lost_train_alert(train.entity, train.depot_name)
return return

View File

@@ -135,6 +135,12 @@ local migrations_table = {
train.is_available = true train.is_available = true
end end
end end
for k, v in pairs(map_data.trains) do
v.depot = nil
if not v.is_available then
v.depot_id = nil
end
end
end, end,
} }

View File

@@ -47,9 +47,18 @@ data:extend({
}, },
{ {
type = "double-setting", type = "double-setting",
name = "cybersyn-warmup-time", name = "cybersyn-depot-bypass-threshold",
order = "ae", order = "ae",
setting_type = "runtime-global", setting_type = "runtime-global",
default_value = .5,
minimum_value = 0,
maximum_value = 1,
},
{
type = "double-setting",
name = "cybersyn-warmup-time",
order = "af",
setting_type = "runtime-global",
default_value = 20, default_value = 20,
minimum_value = 0, minimum_value = 0,
maximum_value = 2147483647, maximum_value = 2147483647,
@@ -57,7 +66,7 @@ data:extend({
{ {
type = "double-setting", type = "double-setting",
name = "cybersyn-stuck-train-time", name = "cybersyn-stuck-train-time",
order = "af", order = "ag",
setting_type = "runtime-global", setting_type = "runtime-global",
default_value = 600, default_value = 600,
minimum_value = 0, minimum_value = 0,