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-request-threshold=Default requester threshold
cybersyn-network-flag=Default network mask
cybersyn-depot-bypass-threshold=Depot bypass fuel threshold
cybersyn-warmup-time=Station warmup time (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-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-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-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
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.p_station_id = p_station_id
train.r_station_id = r_station_id
train.manifest = manifest
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, r_station)
if p_station.entity_comb1.valid then

View File

@@ -111,7 +111,8 @@ end
---@param p_stop LuaEntity
---@param r_stop LuaEntity
---@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
local d_surface = train.front_stock.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 r_surface_i = r_surface.index
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_direct_to_station_order(p_stop),
create_loading_order(p_stop, manifest),

View File

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

View File

@@ -52,15 +52,15 @@ local function is_layout_accepted(layout_pattern, layout)
end
---@param map_data MapData
---@param train Train
---@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
if parked_at_depot_id then
local depot = map_data.depots[parked_at_depot_id]
remove_available_train(map_data, parked_at_depot_id, train)
depot.available_train_id = nil
end
remove_available_train(map_data, train_id, train)
local layout_id = train.layout_id
local count = map_data.layout_train_count[layout_id]
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]
lock_train(train.entity)
send_lost_train_alert(train.entity, depot.entity_stop.backer_name)
remove_available_train(map_data, train_id, train)
map_data.trains[train_id] = nil
depot.available_train_id = nil
remove_train(map_data, train_id, train)
end
map_data.depots[depot.entity_stop.unit_number] = nil
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
on_failed_delivery(map_data, train)
if train.entity then
remove_train(map_data, train, train_id)
remove_train(map_data, train_id, train)
lock_train(train.entity)
send_lost_train_alert(train.entity, train.depot_name)
else
@@ -367,7 +365,6 @@ function on_combinator_network_updated(map_data, comb, network_name)
if train_id then
local train = map_data.trains[train_id]
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)
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 = map_data.trains[train_id]
if train then
remove_available_train(map_data, train_id, train)
if train.manifest and train.status == STATUS_R_TO_D then
if train.manifest then
if train.status == STATUS_R_TO_D then
--succeeded delivery
train.p_station_id = 0
train.r_station_id = 0
train.manifest = nil
add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id])
else
if train.manifest then
on_failed_delivery(map_data, train)
send_unexpected_train_alert(train.entity)
end
add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id])
end
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)
else
--train still has cargo
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)
end
elseif is_train_empty then
@@ -644,8 +640,9 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
end
---@param map_data MapData
---@param stop LuaEntity
---@param train_id uint
---@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
---@type uint
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
else
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)
send_lost_train_alert(train.entity, train.depot_name)
end
else
--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
---@param map_data MapData
---@param mod_settings CybersynModSettings
---@param train_id uint
---@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.status == STATUS_P then
train.status = STATUS_P_TO_R
@@ -691,8 +689,7 @@ local function on_train_leaves_station(map_data, train_id, train)
unset_wagon_combs(map_data, station)
if train.has_filtered_wagon then
train.has_filtered_wagon = false
for carriage_i, carriage in ipairs(train.entity.carriages) do
if carriage.type == "cargo-wagon" then
for carriage_i, carriage in ipairs(train.entity.cargo_wagons) do
local inv = carriage.get_inventory(defines.inventory.cargo_wagon)
if inv and inv.is_filtered() then
---@type uint
@@ -702,48 +699,67 @@ local function on_train_leaves_station(map_data, train_id, train)
end
end
end
end
elseif train.status == STATUS_R then
train.status = STATUS_R_TO_D
local station = map_data.stations[train.r_station_id]
remove_manifest(map_data, station, train.manifest, -1)
set_comb1(map_data, station, nil)
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
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]]]
remove_available_train(map_data, train_id, train)
depot.available_train_id = nil
send_lost_train_alert(train.entity, depot.entity_stop.backer_name)
remove_train(map_data, train_id, train)
end
end
---@param map_data MapData
---@param train_id uint
---@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
if train.manifest and train.entity then
if train.entity then
if train.manifest then
on_failed_delivery(map_data, train)
remove_train(map_data, train, train.entity.id)
if train.entity.valid then
lock_train(train.entity)
end
remove_train(map_data, train_id, train)
end
end
---@param map_data MapData
---@param pre_train_id uint
---@param train_entity LuaEntity
local function on_train_modified(map_data, pre_train_id, train_entity)
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.manifest then
on_failed_delivery(map_data, train)
end
remove_train(map_data, train, pre_train_id)
if train.entity.valid then
lock_train(train.entity)
end
remove_train(map_data, pre_train_id, train)
end
end
@@ -779,9 +795,10 @@ local function on_broken(event)
elseif entity.type == "straight-rail" then
update_station_from_rail(global, entity, nil)
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
on_train_broken(global, train)
on_train_broken(global, train_id, train)
end
end
end
@@ -802,10 +819,10 @@ end
local function on_train_built(event)
local train_e = event.train
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
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
local function on_train_changed(event)
@@ -829,7 +846,7 @@ local function on_train_changed(event)
end
elseif event.old_state == defines.train_state.wait_station 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
@@ -862,6 +879,7 @@ local function on_settings_changed(event)
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.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.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
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.r_threshold = settings.global["cybersyn-request-threshold"].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.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
@@ -980,7 +999,7 @@ local function main()
train.entity = train_entity
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)
send_lost_train_alert(train.entity, train.depot_name)
return

View File

@@ -135,6 +135,12 @@ local migrations_table = {
train.is_available = true
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,
}

View File

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