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
models & art
add stack threshold setting
allow "any" signal for network unions
minor:
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
- Nonempty trains in depot are no longer put in manual mode, instead they are forced to park at the depot
- 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
Date: 2022-12-17

View File

@@ -9,6 +9,7 @@ local band = bit32.band
local table_remove = table.remove
local random = math.random
---@param map_data MapData
---@param station Station
---@param manifest Manifest
@@ -188,6 +189,7 @@ local function tick_dispatch(map_data, mod_settings)
local p_stations
local item_name
local item_type
local item_network_name
while true do
local size = #all_names
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
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]]
--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 = stations[r_station_id]
---@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 is_fluid = item_type == "fluid"
--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
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
goto p_continue
end
@@ -462,7 +472,11 @@ local function tick_poll_station(map_data, mod_settings)
station.priority = 0
station.item_priority = nil
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)
station.tick_signals = comb1_signals
station.item_p_counts = {}
@@ -500,6 +514,8 @@ local function tick_poll_station(map_data, mod_settings)
station.r_threshold = abs(item_count)
elseif item_name == LOCKED_SLOTS then
station.locked_slots = max(item_count, 0)
elseif station.network_name == NETWORK_ANY then
station.network_flag[item_name] = item_count
end
comb1_signals[k] = nil
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
is_not_requesting = false
is_requesting_nothing = false
local item_network_name = station.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
local f, a
if station.network_name == NETWORK_ANY then
f, a = pairs(station.network_flag--[[@as {[string]: int}]])
else
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_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
stations[#stations + 1] = station_id
end
end
if is_not_requesting 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 stations = all_p_stations[item_network_name]
if stations == nil then
stations = {}
all_p_stations[item_network_name] = stations
local f, a
if station.network_name == NETWORK_ANY then
f, a = pairs(station.network_flag--[[@as {[string]: int}]])
else
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
stations[#stations + 1] = station_id
station.item_p_counts[item_name] = effective_item_count
else
comb1_signals[k] = nil
end
@@ -589,7 +621,7 @@ function tick(map_data, mod_settings)
map_data.total_ticks = map_data.total_ticks + 1
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)
end
end
@@ -613,9 +645,8 @@ function tick(map_data, mod_settings)
interface_raise_tick_init()
tick_poll_train(map_data, mod_settings)
tick_poll_comb(map_data)
end
if map_data.tick_state == STATE_POLL_STATIONS then
return
elseif map_data.tick_state == STATE_POLL_STATIONS then
for i = 1, mod_settings.update_rate do
if tick_poll_station(map_data, mod_settings) then break end
end

View File

@@ -23,6 +23,7 @@ MODE_WAGON_MANIFEST = "-"
MODE_REFUELER = ">>"
NETWORK_SIGNAL_DEFAULT = {name="signal-A", type="virtual"}
NETWORK_ANY = "signal-everything"
INACTIVITY_TIME = 100
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_r = is_pr_state == 0 or is_pr_state == 2
end
---@param map_data MapData
---@param mod_settings CybersynModSettings
---@param refueler Refueler
function set_refueler_from_comb(mod_settings, refueler)
---@param id uint
function set_refueler_from_comb(map_data, mod_settings, id)
--NOTE: this does nothing to update currently active deliveries
local refueler = map_data.refuelers[id]
local params = get_comb_params(refueler.entity_comb)
local bits = params.second_constant or 0
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.allows_all_trains = bits%2 == 1
local signals = refueler.entity_comb.get_merged_signals(DEFINES_COMBINATOR_INPUT)
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
for k, v in pairs(signals) do
local item_name = v.signal.name
local item_type = v.signal.type
local item_count = v.count
if item_name then
if item_name == SIGNAL_PRIORITY then
refueler.priority = item_count
if item_type == "virtual" then
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
if item_name == refueler.network_name then
refueler.network_flag = item_count
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
---@param map_data MapData

View File

@@ -36,7 +36,7 @@
---@field public r_threshold int >= 0 --transient
---@field public locked_slots int >= 0 --transient
---@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 deliveries {[string]: int}
---@field public accepted_layouts {[uint]: true?}
@@ -151,3 +151,9 @@ function init_global()
global.se_tele_old_id = {}
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]]
if not comb or not comb.valid then return end
local param = get_comb_params(comb)
local signal = element.elem_value
if signal and (signal.name == "signal-everything" or signal.name == "signal-anything" or signal.name == "signal-each") then
signal = nil
element.elem_value = 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
signal.name = NETWORK_ANY
element.elem_value.name = NETWORK_ANY
else
signal = nil
element.elem_value = nil
end
end
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
local train = map_data.trains[train_id]
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)
end
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_flag = set_refueler_from_comb,
}
set_refueler_from_comb(mod_settings, refueler)
local id = stop.unit_number--[[@as uint]]
map_data.refuelers[id] = refueler
set_refueler_from_comb(map_data, mod_settings, id)
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)
end
---@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
remove_train(map_data, train_id, train)
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
train.se_awaiting_removal = train_id
end
end
end
end
if refueler.network_name then
local network = map_data.to_refuelers[refueler.network_name]
network[refueler_id] = nil
if next(network) == nil then
map_data.to_refuelers[refueler.network_name] = nil
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[refueler_id] = nil
if next(network) == nil then
map_data.to_refuelers[network_name] = nil
end
end
end
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
remove_train(map_data, train_id, train)
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
train.se_awaiting_removal = train_id
end
@@ -297,55 +297,6 @@ local function on_combinator_built(map_data, comb)
end
---@param map_data MapData
---@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)
--NOTE: we do not check for wagon manifest combinators and update their stations, it is assumed they will be lazy deleted later
---@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
if new_network ~= old_network then
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
if params.second_constant ~= old_params.second_constant then
has_changed = true
@@ -455,7 +434,7 @@ function combinator_update(map_data, comb, reset_display)
local refueler = map_data.refuelers[id]
if refueler then
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
update_stop_if_auto(map_data, refueler, false)
end
@@ -752,7 +731,7 @@ local function setup_se_compat()
if train.se_awaiting_removal then
remove_train(map_data, train.se_awaiting_removal, train)
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
elseif train.se_awaiting_rename then
rename_manifest_schedule(train.entity, train.se_awaiting_rename[1], train.se_awaiting_rename[2])

View File

@@ -1,6 +1,7 @@
--By Mami
local min = math.min
local INF = math.huge
local btest = bit32.btest
---@param map_data MapData
---@param station Station
@@ -329,8 +330,10 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
local best_prior = -INF
for id, _ in pairs(refuelers) do
local refueler = map_data.refuelers[id]
set_refueler_from_comb(mod_settings, refueler)
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
set_refueler_from_comb(map_data, mod_settings, id)
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 dist = nil
if refueler.priority == best_prior then