added train timeout

This commit is contained in:
Monica Moniot
2022-11-24 17:38:32 -05:00
parent 35a0994ae3
commit fe202642e7
10 changed files with 84 additions and 11 deletions

2
TODO
View File

@@ -7,3 +7,5 @@ space elevator compat
railloader compat railloader compat
major bug with copy-paste when the operation is changed by blueprint but it gets copied to the old settings before it's checked for update major bug with copy-paste when the operation is changed by blueprint but it gets copied to the old settings before it's checked for update
catch inserter rotation catch inserter rotation
trains of capacity greater than the stations current contents can be dispatched

View File

@@ -35,3 +35,10 @@ Version: 0.4.2
Date: 2022-11-22 Date: 2022-11-22
Features: Features:
- Bugfix with station warmup time - Bugfix with station warmup time
---------------------------------------------------------------------------------------------------
Version: 0.4.3
Date: 2022-11-24
Features:
- Added a stuck train alert
- Improved localization
- Fixed Bug with fluid cargo not being detected by depots

View File

@@ -1,6 +1,6 @@
{ {
"name": "cybersyn", "name": "cybersyn",
"version": "0.4.2", "version": "0.4.3",
"title": "Project Cybersyn", "title": "Project Cybersyn",
"author": "Mami", "author": "Mami",
"factorio_version": "1.1", "factorio_version": "1.1",

View File

@@ -1,14 +1,16 @@
[mod-setting-name] [mod-setting-name]
cybersyn-ticks-per-second=Dispatcher updates per second cybersyn-ticks-per-second=Central planning updates per second
cybersyn-request-threshold=Default requester threshold cybersyn-request-threshold=Default requester threshold
cybersyn-network-flag=Default network flags cybersyn-network-flag=Default network flags
cybersyn-warmup-time=Station warmup time cybersyn-warmup-time=Station warmup time (sec)
cybersyn-stuck-train-time=Stuck train timeout (sec)
[mod-setting-description] [mod-setting-description]
cybersyn-ticks-per-second=How many times per second the dispather should check for new deliveries. Deliveries are made one at a time per update. This value will be rounded up to a divisor of 60. cybersyn-ticks-per-second=How many times per second the central planner should update the state of the network and schedule deliveries. Only one deliveries can be made per update. This value will be rounded up to a divisor of 60.
cybersyn-request-threshold=The default request threshold when a request threshold signal is not given to a station. Huge values will prevent stations from taking requests from the network unless an explicit threshold is set. 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 networks a station will service when no network signal is given to a station. This integer is interpretted bit-wise to give 32 possible network flags to choose from. cybersyn-network-flag=The default set of networks a station will service when no network signal is given to a station. This integer is interpretted bit-wise to give 32 possible network flags to choose from.
cybersyn-warmup-time=How many seconds a cybernetic combinator will wait before connecting to the Cybersyn network. 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.
[item-name] [item-name]
cybersyn-combinator=Cybernetic combinator cybersyn-combinator=Cybernetic combinator
@@ -40,6 +42,7 @@ missing-trains=No trains available to make a delivery from __2__ to __1__
lost-train=A train from depot __1__ has become lost lost-train=A train from depot __1__ has become lost
nonempty-train=A train is being held in the depot because it still has cargo nonempty-train=A train is being held in the depot because it still has cargo
unexpected-train=A train has unexpectedly returned to the depot before completing its delivery unexpected-train=A train has unexpectedly returned to the depot before completing its delivery
stuck-train=A train from depot __1__ is stuck
[cybersyn-gui] [cybersyn-gui]
combinator-title=Cybernetic combinator combinator-title=Cybernetic combinator

View File

@@ -215,6 +215,7 @@ local function send_train_between(map_data, r_station_id, p_station_id, depot, 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.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest) train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest)
set_comb2(map_data, p_station) set_comb2(map_data, p_station)
@@ -227,6 +228,18 @@ local function send_train_between(map_data, r_station_id, p_station_id, depot, p
end end
end end
---@param map_data MapData
---@param mod_settings CybersynModSettings
local function tick_poll_train(map_data, mod_settings)
local tick_data = map_data.tick_data
--NOTE: the following has undefined behavior if last_train is deleted, this should be ok since the following doesn't care how inconsistent our access pattern is
local train_id, train = next(map_data.trains, tick_data.last_train)
tick_data.last_train = train_id
if train and train.manifest and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
send_stuck_train_alert(train.entity, train.depot_name)
end
end
---@param map_data MapData ---@param map_data MapData
---@param mod_settings CybersynModSettings ---@param mod_settings CybersynModSettings
local function tick_poll_station(map_data, mod_settings) local function tick_poll_station(map_data, mod_settings)
@@ -467,7 +480,7 @@ function tick(map_data, mod_settings)
for i, id in pairs(map_data.warmup_station_ids) do for i, id in pairs(map_data.warmup_station_ids) do
local station = map_data.stations[id] local station = map_data.stations[id]
if station then if station then
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
end end
@@ -475,6 +488,7 @@ function tick(map_data, mod_settings)
map_data.warmup_station_ids[i] = nil map_data.warmup_station_ids[i] = nil
end end
end end
tick_poll_train(map_data, mod_settings)
end end
if map_data.tick_state == STATE_POLL_STATIONS then if map_data.tick_state == STATE_POLL_STATIONS then

View File

@@ -266,3 +266,20 @@ function send_nonempty_train_in_depot_alert(train)
end end
end end
end end
local send_stuck_train_alert_icon = {name = LOST_TRAIN_NAME, type = "fluid"}
---@param train LuaTrain
---@param depot_name string
function send_stuck_train_alert(train, depot_name)
local loco = train.front_stock or train.back_stock
if loco then
for _, player in pairs(loco.force.players) do
player.add_custom_alert(
loco,
send_stuck_train_alert_icon,
{"cybersyn-messages.stuck-train", depot_name},
true)
end
end
end

View File

@@ -56,6 +56,7 @@
---@field public p_station_id uint ---@field public p_station_id uint
---@field public r_station_id uint ---@field public r_station_id uint
---@field public manifest Manifest ---@field public manifest Manifest
---@field public last_manifest_tick int
---@field public has_filtered_wagon boolean ---@field public has_filtered_wagon boolean
---@field public depot_id uint? ---@field public depot_id uint?
---@field public depot_name string ---@field public depot_name string
@@ -78,6 +79,7 @@
---@field public r_threshold int ---@field public r_threshold int
---@field public network_flag int ---@field public network_flag int
---@field public warmup_time int ---@field public warmup_time int
---@field public stuck_train_time int
---@type CybersynModSettings ---@type CybersynModSettings
mod_settings = {} mod_settings = {}

View File

@@ -558,6 +558,8 @@ end
---@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, train_entity)
local contents = train_entity.get_contents() local contents = train_entity.get_contents()
local fluid_contents = train_entity.get_fluid_contents()
local is_train_empty = next(contents) == nil and next(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]
if train then if train then
@@ -576,15 +578,15 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
train.status = STATUS_D train.status = STATUS_D
add_available_train(map_data, depot_id, train_id) add_available_train(map_data, depot_id, train_id)
end end
if next(contents) ~= nil then if is_train_empty then
train_entity.schedule = create_depot_schedule(train.depot_name)
else
--train still has cargo --train still has cargo
train_entity.schedule = nil train_entity.schedule = nil
remove_train(map_data, train, train_id) remove_train(map_data, train, train_id)
send_nonempty_train_in_depot_alert(train_entity) send_nonempty_train_in_depot_alert(train_entity)
else
train_entity.schedule = create_depot_schedule(train.depot_name)
end end
elseif next(contents) == nil then elseif is_train_empty then
train = { train = {
status = STATUS_D, status = STATUS_D,
entity = train_entity, entity = train_entity,
@@ -593,6 +595,7 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
fluid_capacity = 0, fluid_capacity = 0,
p_station_id = 0, p_station_id = 0,
r_station_id = 0, r_station_id = 0,
last_manifest_tick = map_data.total_ticks,
manifest = nil, manifest = nil,
} }
update_train_layout(map_data, train) update_train_layout(map_data, train)
@@ -602,6 +605,7 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
local schedule = create_depot_schedule(train.depot_name) local schedule = create_depot_schedule(train.depot_name)
train_entity.schedule = schedule train_entity.schedule = schedule
else else
train_entity.schedule = nil
send_nonempty_train_in_depot_alert(train_entity) send_nonempty_train_in_depot_alert(train_entity)
end end
end end
@@ -836,6 +840,7 @@ local function on_settings_changed(event)
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.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as int]] mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as int]]
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as int]]
if event.setting == "cybersyn-ticks-per-second" then if event.setting == "cybersyn-ticks-per-second" then
local nth_tick = math.ceil(60/mod_settings.tps); local nth_tick = math.ceil(60/mod_settings.tps);
flib_event.on_nth_tick(nil) flib_event.on_nth_tick(nil)
@@ -866,6 +871,7 @@ local function main()
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.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as int]] mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as int]]
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as int]]
--NOTE: There is a concern that it is possible to build or destroy important entities without one of these events being triggered, in which case the mod will have undefined behavior --NOTE: There is a concern that it is possible to build or destroy important entities without one of these events being triggered, in which case the mod will have undefined behavior
flib_event.register(defines.events.on_built_entity, on_built, filter_built) flib_event.register(defines.events.on_built_entity, on_built, filter_built)

View File

@@ -75,6 +75,19 @@ local migrations_table = {
} }
end end
end, end,
["0.4.3"] = function()
---@type MapData
local map_data = global
map_data.tick_state = STATE_INIT
for id, station in pairs(map_data.stations) do
set_station_from_comb_state(station)
station.allow_all_trains = nil
end
for id, train in pairs(map_data.trains) do
train.last_manifest_tick = map_data.total_ticks
end
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as int]]
end,
} }
---@param data ConfigurationChangedData ---@param data ConfigurationChangedData

View File

@@ -36,4 +36,13 @@ data:extend({
minimum_value = 0, minimum_value = 0,
maximum_value = 2147483647, maximum_value = 2147483647,
}, },
{
type = "int-setting",
name = "cybersyn-stuck-train-time",
order = "ad",
setting_type = "runtime-global",
default_value = 600,
minimum_value = 0,
maximum_value = 2147483647,
},
}) })