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

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