added an "everything" network

This commit is contained in:
mamoniot
2022-12-23 08:52:55 -05:00
parent 3c80fd0df2
commit be849acb43
10 changed files with 181 additions and 103 deletions

1
TODO
View File

@@ -9,7 +9,6 @@ major:
move to an event based algorithm move to an event based algorithm
models & art models & art
add stack threshold setting add stack threshold setting
allow "any" signal for network unions
minor: minor:
railloader compat railloader compat

View File

@@ -9,6 +9,7 @@ Date: 2022-12-22
- Provide stations now override request thresholds with the per-item thresholds set by their station info combinator - Provide stations now override request thresholds with the per-item thresholds set by their station info combinator
- Nonempty trains in depot are no longer put in manual mode, instead they are forced to park at the depot - Nonempty trains in depot are no longer put in manual mode, instead they are forced to park at the depot
- Made several alerts persistent - Made several alerts persistent
- Allowed station and fuel combinators to be set to network id "everything", for each virtual signal they recieve as input, the stop is added to that network and its signal strength is used as the network mask
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
Version: 1.1.7 Version: 1.1.7
Date: 2022-12-17 Date: 2022-12-17

View File

@@ -9,6 +9,7 @@ local band = bit32.band
local table_remove = table.remove local table_remove = table.remove
local random = math.random local random = math.random
---@param map_data MapData ---@param map_data MapData
---@param station Station ---@param station Station
---@param manifest Manifest ---@param manifest Manifest
@@ -188,6 +189,7 @@ local function tick_dispatch(map_data, mod_settings)
local p_stations local p_stations
local item_name local item_name
local item_type local item_type
local item_network_name
while true do while true do
local size = #all_names local size = #all_names
if size == 0 then if size == 0 then
@@ -198,7 +200,7 @@ local function tick_dispatch(map_data, mod_settings)
--randomizing the ordering should only matter if we run out of available trains --randomizing the ordering should only matter if we run out of available trains
local name_i = size <= 2 and 2 or 2*random(size/2) local name_i = size <= 2 and 2 or 2*random(size/2)
local item_network_name = all_names[name_i - 1]--[[@as string]] item_network_name = all_names[name_i - 1]--[[@as string]]
local signal = all_names[name_i]--[[@as SignalID]] local signal = all_names[name_i]--[[@as SignalID]]
--swap remove --swap remove
@@ -274,7 +276,13 @@ local function tick_dispatch(map_data, mod_settings)
local r_station_id = r_stations[r_station_i] local r_station_id = r_stations[r_station_i]
local r_station = stations[r_station_id] local r_station = stations[r_station_id]
---@type string ---@type string
local network_name = r_station.network_name local network_name
if r_station.network_name == NETWORK_ANY then
--TODO: here
_, _, network_name = string.find(item_network_name, "(^.*):")
else
network_name = r_station.network_name
end
local trains = map_data.available_trains[network_name] local trains = map_data.available_trains[network_name]
local is_fluid = item_type == "fluid" local is_fluid = item_type == "fluid"
--no train exists with layout accepted by both provide and request stations --no train exists with layout accepted by both provide and request stations
@@ -296,7 +304,9 @@ local function tick_dispatch(map_data, mod_settings)
goto p_continue goto p_continue
end end
local netand = band(p_station.network_flag, r_station.network_flag) local p_flag = p_station.network_name == NETWORK_ANY and (p_station.network_flag[item_name] or 0) or p_station.network_flag
local r_flag = r_station.network_name == NETWORK_ANY and (r_station.network_flag[item_name] or 0) or r_station.network_flag
local netand = band(p_flag, r_flag)
if netand == 0 then if netand == 0 then
goto p_continue goto p_continue
end end
@@ -462,7 +472,11 @@ local function tick_poll_station(map_data, mod_settings)
station.priority = 0 station.priority = 0
station.item_priority = nil station.item_priority = nil
station.locked_slots = 0 station.locked_slots = 0
station.network_flag = mod_settings.network_flag if station.network_name == NETWORK_ANY then
station.network_flag = {}
else
station.network_flag = mod_settings.network_flag
end
local comb1_signals, comb2_signals = get_signals(station) local comb1_signals, comb2_signals = get_signals(station)
station.tick_signals = comb1_signals station.tick_signals = comb1_signals
station.item_p_counts = {} station.item_p_counts = {}
@@ -500,6 +514,8 @@ local function tick_poll_station(map_data, mod_settings)
station.r_threshold = abs(item_count) station.r_threshold = abs(item_count)
elseif item_name == LOCKED_SLOTS then elseif item_name == LOCKED_SLOTS then
station.locked_slots = max(item_count, 0) station.locked_slots = max(item_count, 0)
elseif station.network_name == NETWORK_ANY then
station.network_flag[item_name] = item_count
end end
comb1_signals[k] = nil comb1_signals[k] = nil
end end
@@ -524,27 +540,43 @@ local function tick_poll_station(map_data, mod_settings)
if -effective_item_count >= r_threshold and -item_count >= r_threshold then if -effective_item_count >= r_threshold and -item_count >= r_threshold then
is_not_requesting = false is_not_requesting = false
is_requesting_nothing = false is_requesting_nothing = false
local item_network_name = station.network_name..":"..item_name local f, a
local stations = all_r_stations[item_network_name] if station.network_name == NETWORK_ANY then
if stations == nil then f, a = pairs(station.network_flag--[[@as {[string]: int}]])
stations = {} else
all_r_stations[item_network_name] = stations f, a = once, station.network_name
all_names[#all_names + 1] = item_network_name end
all_names[#all_names + 1] = v.signal for network_name, _ in f, a do
local item_network_name = network_name..":"..item_name
local stations = all_r_stations[item_network_name]
if stations == nil then
stations = {}
all_r_stations[item_network_name] = stations
all_names[#all_names + 1] = item_network_name
all_names[#all_names + 1] = v.signal
end
stations[#stations + 1] = station_id
end end
stations[#stations + 1] = station_id
end end
end end
if is_not_requesting then if is_not_requesting then
if station.is_p and effective_item_count > 0 and item_count > 0 then if station.is_p and effective_item_count > 0 and item_count > 0 then
local item_network_name = station.network_name..":"..item_name local f, a
local stations = all_p_stations[item_network_name] if station.network_name == NETWORK_ANY then
if stations == nil then f, a = pairs(station.network_flag--[[@as {[string]: int}]])
stations = {} else
all_p_stations[item_network_name] = stations f, a = once, station.network_name
end
for network_name, _ in f, a do
local item_network_name = network_name..":"..item_name
local stations = all_p_stations[item_network_name]
if stations == nil then
stations = {}
all_p_stations[item_network_name] = stations
end
stations[#stations + 1] = station_id
station.item_p_counts[item_name] = effective_item_count
end end
stations[#stations + 1] = station_id
station.item_p_counts[item_name] = effective_item_count
else else
comb1_signals[k] = nil comb1_signals[k] = nil
end end
@@ -589,7 +621,7 @@ function tick(map_data, mod_settings)
map_data.total_ticks = map_data.total_ticks + 1 map_data.total_ticks = map_data.total_ticks + 1
if map_data.active_alerts then if map_data.active_alerts then
if map_data.total_ticks%(10*mod_settings.tps) < 1 then if map_data.total_ticks%(9*mod_settings.tps) < 1 then
process_active_alerts(map_data) process_active_alerts(map_data)
end end
end end
@@ -613,9 +645,8 @@ function tick(map_data, mod_settings)
interface_raise_tick_init() interface_raise_tick_init()
tick_poll_train(map_data, mod_settings) tick_poll_train(map_data, mod_settings)
tick_poll_comb(map_data) tick_poll_comb(map_data)
end return
elseif map_data.tick_state == STATE_POLL_STATIONS then
if map_data.tick_state == STATE_POLL_STATIONS then
for i = 1, mod_settings.update_rate do for i = 1, mod_settings.update_rate do
if tick_poll_station(map_data, mod_settings) then break end if tick_poll_station(map_data, mod_settings) then break end
end end

View File

@@ -23,6 +23,7 @@ MODE_WAGON_MANIFEST = "-"
MODE_REFUELER = ">>" MODE_REFUELER = ">>"
NETWORK_SIGNAL_DEFAULT = {name="signal-A", type="virtual"} NETWORK_SIGNAL_DEFAULT = {name="signal-A", type="virtual"}
NETWORK_ANY = "signal-everything"
INACTIVITY_TIME = 100 INACTIVITY_TIME = 100
LOCK_TRAIN_TIME = 60*60*60*24*7 LOCK_TRAIN_TIME = 60*60*60*24*7

View File

@@ -345,32 +345,74 @@ function set_station_from_comb_state(station)
station.is_p = is_pr_state == 0 or is_pr_state == 1 station.is_p = is_pr_state == 0 or is_pr_state == 1
station.is_r = is_pr_state == 0 or is_pr_state == 2 station.is_r = is_pr_state == 0 or is_pr_state == 2
end end
---@param map_data MapData
---@param mod_settings CybersynModSettings ---@param mod_settings CybersynModSettings
---@param refueler Refueler ---@param id uint
function set_refueler_from_comb(mod_settings, refueler) function set_refueler_from_comb(map_data, mod_settings, id)
--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
local f, a
if refueler.network_name == NETWORK_ANY then
f, a = pairs(refueler.network_flag--[[@as {[string]: int}]])
else
f, a = once, refueler.network_name
end
for network_name, _ in f, a do
local network = map_data.to_refuelers[network_name]
if network then
network[id] = nil
if next(network) == nil then
map_data.to_refuelers[network_name] = nil
end
end
end
refueler.network_name = signal and signal.name or nil refueler.network_name = signal and signal.name or nil
refueler.allows_all_trains = bits%2 == 1 refueler.allows_all_trains = bits%2 == 1
local signals = refueler.entity_comb.get_merged_signals(DEFINES_COMBINATOR_INPUT) local signals = refueler.entity_comb.get_merged_signals(DEFINES_COMBINATOR_INPUT)
refueler.priority = 0 refueler.priority = 0
refueler.network_flag = mod_settings.network_flag if refueler.network_name == NETWORK_ANY then
refueler.network_flag = {}
else
refueler.network_flag = mod_settings.network_flag
end
if not signals then return end if not signals then return end
for k, v in pairs(signals) do for k, v in pairs(signals) do
local item_name = v.signal.name local item_name = v.signal.name
local item_type = v.signal.type
local item_count = v.count local item_count = v.count
if item_name then if item_name then
if item_name == SIGNAL_PRIORITY then if item_type == "virtual" then
refueler.priority = item_count if item_name == SIGNAL_PRIORITY then
refueler.priority = item_count
elseif refueler.network_name == NETWORK_ANY then
refueler.network_flag[item_name] = item_count
end
end end
if item_name == refueler.network_name then if item_name == refueler.network_name then
refueler.network_flag = item_count refueler.network_flag = item_count
end end
end end
end end
if refueler.network_name == NETWORK_ANY then
f, a = pairs(refueler.network_flag--[[@as {[string]: int}]])
else
f, a = once, refueler.network_name
end
for network_name, _ in f, a do
local network = map_data.to_refuelers[network_name]
if not network then
network = {}
map_data.to_refuelers[network_name] = network
end
network[id] = true
end
end end
---@param map_data MapData ---@param map_data MapData

View File

@@ -36,7 +36,7 @@
---@field public r_threshold int >= 0 --transient ---@field public r_threshold int >= 0 --transient
---@field public locked_slots int >= 0 --transient ---@field public locked_slots int >= 0 --transient
---@field public network_name string? ---@field public network_name string?
---@field public network_flag int --transient ---@field public network_flag int|{[string]: int} --transient
---@field public wagon_combs {[int]: LuaEntity}?--NOTE: allowed to be invalid entities or combinators with the wrong operation, these must be checked and lazy deleted when found ---@field public wagon_combs {[int]: LuaEntity}?--NOTE: allowed to be invalid entities or combinators with the wrong operation, these must be checked and lazy deleted when found
---@field public deliveries {[string]: int} ---@field public deliveries {[string]: int}
---@field public accepted_layouts {[uint]: true?} ---@field public accepted_layouts {[uint]: true?}
@@ -151,3 +151,9 @@ function init_global()
global.se_tele_old_id = {} global.se_tele_old_id = {}
end end
end end
---@param v string
---@param h string?
function once(v, h)
return not h and v or nil--[[@as string|nil]]
end

View File

@@ -192,10 +192,17 @@ function register_gui_actions()
local comb = global.to_comb[msg[2]] local comb = global.to_comb[msg[2]]
if not comb or not comb.valid then return end if not comb or not comb.valid then return end
local param = get_comb_params(comb)
local signal = element.elem_value local signal = element.elem_value
if signal and (signal.name == "signal-everything" or signal.name == "signal-anything" or signal.name == "signal-each") then if signal and (signal.name == "signal-everything" or signal.name == "signal-anything" or signal.name == "signal-each") then
signal = nil if param.operation == MODE_PRIMARY_IO or param.operation == MODE_PRIMARY_IO_ACTIVE or param.operation == MODE_PRIMARY_IO_FAILED_REQUEST or param.operation == MODE_REFUELER then
element.elem_value = nil signal.name = NETWORK_ANY
element.elem_value.name = NETWORK_ANY
else
signal = nil
element.elem_value = nil
end
end end
set_comb_network_name(comb, signal) set_comb_network_name(comb, signal)

9
cybersyn/scripts/log.lua Normal file
View File

@@ -0,0 +1,9 @@
function log_dispatch(network_name, r_stop, p_stop)
end
function log_refuel(network_name, refuel_stop)
end

View File

@@ -27,7 +27,7 @@ local function on_depot_broken(map_data, depot_id, depot)
if train_id then if train_id then
local train = map_data.trains[train_id] local train = map_data.trains[train_id]
lock_train(train.entity) lock_train(train.entity)
send_alert_depot_of_train_broken(train.entity, depot.entity_stop.backer_name) send_alert_depot_of_train_broken(map_data, train.entity)
remove_train(map_data, train_id, train) remove_train(map_data, train_id, train)
end end
map_data.depots[depot_id] = nil map_data.depots[depot_id] = nil
@@ -50,18 +50,10 @@ local function on_refueler_built(map_data, stop, comb)
--network_name = set_refueler_from_comb, --network_name = set_refueler_from_comb,
--network_flag = set_refueler_from_comb, --network_flag = set_refueler_from_comb,
} }
set_refueler_from_comb(mod_settings, refueler)
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)
update_stop_if_auto(map_data, refueler, false) update_stop_if_auto(map_data, refueler, false)
if refueler.network_name then
local network = map_data.to_refuelers[refueler.network_name]
if not network then
network = {}
map_data.to_refuelers[refueler.network_name] = network
end
network[id] = true
end
interface_raise_refueler_created(id) interface_raise_refueler_created(id)
end end
---@param map_data MapData ---@param map_data MapData
@@ -76,18 +68,26 @@ local function on_refueler_broken(map_data, refueler_id, refueler)
if not train.se_is_being_teleported then if not train.se_is_being_teleported then
remove_train(map_data, train_id, train) remove_train(map_data, train_id, train)
lock_train(train.entity) lock_train(train.entity)
send_alert_refueler_of_train_broken(train.entity, train.depot_name) send_alert_refueler_of_train_broken(map_data, train.entity)
else else
train.se_awaiting_removal = train_id train.se_awaiting_removal = train_id
end end
end end
end end
end end
if refueler.network_name then local f, a
local network = map_data.to_refuelers[refueler.network_name] if refueler.network_name == NETWORK_ANY then
network[refueler_id] = nil f, a = pairs(refueler.network_flag--[[@as {[string]: int}]])
if next(network) == nil then else
map_data.to_refuelers[refueler.network_name] = nil f, a = once, refueler.network_name
end
for network_name, _ in f, a do
local network = map_data.to_refuelers[network_name]
if network then
network[refueler_id] = nil
if next(network) == nil then
map_data.to_refuelers[network_name] = nil
end
end end
end end
map_data.refuelers[refueler_id] = nil map_data.refuelers[refueler_id] = nil
@@ -151,7 +151,7 @@ local function on_station_broken(map_data, station_id, station)
if not train.se_is_being_teleported then if not train.se_is_being_teleported then
remove_train(map_data, train_id, train) remove_train(map_data, train_id, train)
lock_train(train.entity) lock_train(train.entity)
send_alert_station_of_train_broken(train.entity, train.depot_name) send_alert_station_of_train_broken(map_data, train.entity)
else else
train.se_awaiting_removal = train_id train.se_awaiting_removal = train_id
end end
@@ -297,55 +297,6 @@ local function on_combinator_built(map_data, comb)
end end
---@param map_data MapData ---@param map_data MapData
---@param comb LuaEntity ---@param comb LuaEntity
---@param network_name string?
function on_combinator_network_updated(map_data, comb, network_name)
local stop = map_data.to_stop[comb.unit_number]
if stop and stop.valid then
local id = stop.unit_number
local station = map_data.stations[id]
if station then
if station.entity_comb1 == comb then
station.network_name = network_name
end
else
local depot = map_data.depots[id]
if depot then
if depot.entity_comb == comb then
local train_id = depot.available_train_id
if train_id then
local train = map_data.trains[train_id]
remove_available_train(map_data, train_id, train)
add_available_train_to_depot(map_data, mod_settings, train_id, train, id, depot)
interface_raise_train_status_changed(train_id, STATUS_D, STATUS_D)
end
end
else
local refueler = map_data.refuelers[id]
if refueler and refueler.entity_comb == comb then
if refueler.network_name then
local network = map_data.to_refuelers[refueler.network_name]
network[id] = nil
if next(network) == nil then
map_data.to_refuelers[refueler.network_name] = nil
end
end
refueler.network_name = network_name
if network_name then
local network = map_data.to_refuelers[network_name]
if not network then
network = {}
map_data.to_refuelers[network_name] = network
end
network[id] = true
end
end
end
end
end
end
---@param map_data MapData
---@param comb LuaEntity
function on_combinator_broken(map_data, comb) function on_combinator_broken(map_data, comb)
--NOTE: we do not check for wagon manifest combinators and update their stations, it is assumed they will be lazy deleted later --NOTE: we do not check for wagon manifest combinators and update their stations, it is assumed they will be lazy deleted later
---@type uint ---@type uint
@@ -441,7 +392,35 @@ function combinator_update(map_data, comb, reset_display)
local old_network = old_signal and old_signal.name or nil local old_network = old_signal and old_signal.name or nil
if new_network ~= old_network then if new_network ~= old_network then
has_changed = true has_changed = true
on_combinator_network_updated(map_data, comb, new_network)
local stop = map_data.to_stop[comb.unit_number]
if stop and stop.valid then
id = stop.unit_number
station = map_data.stations[id]
if station then
if station.entity_comb1 == comb then
station.network_name = new_network
end
else
local depot = map_data.depots[id]
if depot then
if depot.entity_comb == comb then
local train_id = depot.available_train_id
if train_id then
local train = map_data.trains[train_id]
remove_available_train(map_data, train_id, train)
add_available_train_to_depot(map_data, mod_settings, train_id, train, id, depot)
interface_raise_train_status_changed(train_id, STATUS_D, STATUS_D)
end
end
else
local refueler = map_data.refuelers[id]
if refueler and refueler.entity_comb == comb then
set_refueler_from_comb(map_data, mod_settings, id)
end
end
end
end
end end
if params.second_constant ~= old_params.second_constant then if params.second_constant ~= old_params.second_constant then
has_changed = true has_changed = true
@@ -455,7 +434,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(mod_settings, refueler) set_refueler_from_comb(map_data, mod_settings, id)
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
@@ -752,7 +731,7 @@ local function setup_se_compat()
if train.se_awaiting_removal then if train.se_awaiting_removal then
remove_train(map_data, train.se_awaiting_removal, train) remove_train(map_data, train.se_awaiting_removal, train)
lock_train(train.entity) lock_train(train.entity)
send_alert_station_of_train_broken(train.entity, train.depot_name) send_alert_station_of_train_broken(map_data, train.entity)
return return
elseif train.se_awaiting_rename then elseif train.se_awaiting_rename then
rename_manifest_schedule(train.entity, train.se_awaiting_rename[1], train.se_awaiting_rename[2]) rename_manifest_schedule(train.entity, train.se_awaiting_rename[1], train.se_awaiting_rename[2])

View File

@@ -1,6 +1,7 @@
--By Mami --By Mami
local min = math.min local min = math.min
local INF = math.huge local INF = math.huge
local btest = bit32.btest
---@param map_data MapData ---@param map_data MapData
---@param station Station ---@param station Station
@@ -329,8 +330,10 @@ 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(mod_settings, refueler) set_refueler_from_comb(map_data, mod_settings, id)
if bit32.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 refueler_network_flag = refueler.network_name == NETWORK_ANY and refueler.network_flag[train.network_name] or refueler.network_flag
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 accepted = false
local dist = nil local dist = nil
if refueler.priority == best_prior then if refueler.priority == best_prior then