added optional priority

This commit is contained in:
Monica Moniot
2022-12-07 19:53:12 -05:00
parent 67ab208aea
commit d4cc8481c4
6 changed files with 93 additions and 70 deletions

View File

@@ -111,3 +111,10 @@ Version: 1.0.9
Date: 2022-12-3
Features:
- Fixed a bug with SE compat preventing players from joining multiplayer games
---------------------------------------------------------------------------------------------------
Version: 1.0.10
Date: 2022-12-5
Features:
- Added the ability to use the priority signal as input to optional station control so one can override priority on items with optional station control thresholds
- Added refueler stations
- Fixed a crash relating to wagon control combinators on request stations

View File

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

View File

@@ -114,8 +114,8 @@ function send_train_between(map_data, r_station_id, p_station_id, train_id, prim
local r_item_count = v.count
local r_effective_item_count = r_item_count + (r_station.deliveries[item_name] or 0)
if r_effective_item_count < 0 and r_item_count < 0 then
local r_threshold = r_station.p_count_or_r_threshold_per_item[item_name]
local p_effective_item_count = p_station.p_count_or_r_threshold_per_item[item_name]
local r_threshold = r_station.item_thresholds and r_station.item_thresholds[item_name] or r_station.r_threshold
local p_effective_item_count = p_station.item_p_counts[item_name]
--could be an item that is not present at the station
if p_effective_item_count and p_effective_item_count >= r_threshold then
local item = {name = item_name, type = item_type, count = min(-r_effective_item_count, p_effective_item_count)}
@@ -282,11 +282,19 @@ local function tick_dispatch(map_data, mod_settings)
local station = stations[id]
--NOTE: the station at r_station_id could have been deleted and reregistered since last poll, this check here prevents it from being processed for a delivery in that case
if station and station.deliveries_total < station.entity_stop.trains_limit then
local threshold = station.p_count_or_r_threshold_per_item[item_name]
if threshold <= max_threshold and (station.priority > best_prior or (station.priority == best_prior and station.last_delivery_tick < best_lru)) then
local item_threshold = station.item_thresholds and station.item_thresholds[item_name] or nil
local threshold = station.r_threshold
local prior = station.priority
if item_threshold then
threshold = item_threshold
if station.item_priority then
prior = station.item_priority--[[@as int]]
end
end
if threshold <= max_threshold and (prior > best_prior or (prior == best_prior and station.last_delivery_tick < best_lru)) then
r_station_i = i
r_threshold = threshold
best_prior = station.priority
best_prior = prior
best_lru = station.last_delivery_tick
end
end
@@ -314,9 +322,13 @@ local function tick_dispatch(map_data, mod_settings)
for j, p_station_id in ipairs(p_stations) do
local p_station = stations[p_station_id]
if p_station and p_station.deliveries_total < p_station.entity_stop.trains_limit then
local effective_count = p_station.p_count_or_r_threshold_per_item[item_name]
local effective_count = p_station.item_p_counts[item_name]
if effective_count >= r_threshold then
local item_threshold = p_station.item_thresholds and p_station.item_thresholds[item_name] or nil
local prior = p_station.priority
if item_threshold then
prior = p_station.item_priority--[[@as int]]
end
local slot_threshold = item_type == "fluid" and r_threshold or ceil(r_threshold/get_stack_size(map_data, item_name))
local train, d = get_valid_train(map_data, r_station_id, p_station_id, item_type, slot_threshold)
if prior > best_prior or (prior == best_prior and d < best_dist) then
@@ -385,13 +397,34 @@ local function tick_poll_station(map_data, mod_settings)
end
station.r_threshold = mod_settings.r_threshold
station.priority = 0
station.item_priority = nil
station.locked_slots = 0
station.network_flag = mod_settings.network_flag
local signals = get_signals(station)
station.tick_signals = signals
station.p_count_or_r_threshold_per_item = {}
if signals then
for k, v in pairs(signals) do
local comb1_signals, comb2_signals = get_signals(station)
station.tick_signals = comb1_signals
station.item_p_counts = {}
if comb1_signals then
if comb2_signals then
station.item_thresholds = {}
for k, v in pairs(comb2_signals) do
local item_name = v.signal.name
local item_count = v.count
local item_type = v.signal.type
if item_name then
if item_type == "virtual" then
if item_name == SIGNAL_PRIORITY then
station.item_priority = item_count
end
else
station.item_thresholds[item_name] = abs(item_count)
end
end
end
else
station.item_thresholds = nil
end
for k, v in pairs(comb1_signals) do
local item_name = v.signal.name
local item_count = v.count
local item_type = v.signal.type
@@ -405,18 +438,18 @@ local function tick_poll_station(map_data, mod_settings)
elseif item_name == LOCKED_SLOTS then
station.locked_slots = max(item_count, 0)
end
signals[k] = nil
comb1_signals[k] = nil
end
if item_name == station.network_name then
station.network_flag = item_count
signals[k] = nil
comb1_signals[k] = nil
end
else
signals[k] = nil
comb1_signals[k] = nil
end
end
local is_requesting_nothing = true
for k, v in pairs(signals) do
for k, v in pairs(comb1_signals) do
---@type string
local item_name = v.signal.name
local item_count = v.count
@@ -424,7 +457,7 @@ local function tick_poll_station(map_data, mod_settings)
local is_not_requesting = true
if station.is_r then
local r_threshold = get_threshold(map_data, station, v.signal)
local r_threshold = station.item_thresholds and station.item_thresholds[item_name] or station.r_threshold
if -effective_item_count >= r_threshold and -item_count >= r_threshold then
is_not_requesting = false
is_requesting_nothing = false
@@ -437,7 +470,6 @@ local function tick_poll_station(map_data, mod_settings)
all_names[#all_names + 1] = v.signal
end
stations[#stations + 1] = station_id
station.p_count_or_r_threshold_per_item[item_name] = r_threshold
end
end
if is_not_requesting then
@@ -449,9 +481,9 @@ local function tick_poll_station(map_data, mod_settings)
all_p_stations[item_network_name] = stations
end
stations[#stations + 1] = station_id
station.p_count_or_r_threshold_per_item[item_name] = effective_item_count
station.item_p_counts[item_name] = effective_item_count
else
signals[k] = nil
comb1_signals[k] = nil
end
end
end

View File

@@ -254,38 +254,14 @@ function set_station_from_comb_state(station)
station.is_r = is_pr_state == 0 or is_pr_state == 2
end
---@param map_data MapData
---@param unit_number uint
---@param params ArithmeticCombinatorParameters
local function has_comb_params_changed(map_data, unit_number, params)
local old_params = map_data.to_comb_params[unit_number]
if params.operation ~= old_params.operation then
if (old_params.operation == OPERATION_PRIMARY_IO) and (params.operation == OPERATION_PRIMARY_IO_ACTIVE or params.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST) then
else
return true
end
end
local new_signal = params.first_signal
local old_signal = old_params.first_signal
local new_network = new_signal and new_signal.name or nil
local old_network = old_signal and old_signal.name or nil
if new_network ~= old_network then
return true
end
if params.second_constant ~= old_params.second_constant then
return true
end
return false
end
---@param map_data MapData
---@param station Station
function update_display(map_data, station)
local comb = station.entity_comb1
if comb.valid then
local unit_number = comb.unit_number--[[@as uint]]
local control = get_comb_control(comb)
local params = control.parameters
if not has_comb_params_changed(map_data, unit_number, params) then
--NOTE: the following check can cause a bug where the display desyncs if the player changes the operation of the combinator and then changes it back before the mod can notice, however removing it causes a bug where the user's change is overwritten and ignored. Everything's bad we need an event to catch copy-paste by blueprint.
if params.operation == OPERATION_PRIMARY_IO or params.operation == OPERATION_PRIMARY_IO_ACTIVE or params.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST then
if station.display_state >= 2 then
params.operation = OPERATION_PRIMARY_IO_ACTIVE
elseif station.display_state == 1 then
@@ -350,12 +326,23 @@ local DEFINES_COMBINATOR_INPUT = defines.circuit_connector_id.combinator_input
---@param station Station
function get_signals(station)
--NOTE: the combinator must be valid, but checking for valid every time is too slow
local comb = station.entity_comb1
local status = comb.status
if status == DEFINES_WORKING or status == DEFINES_LOW_POWER then
return comb.get_merged_signals(DEFINES_COMBINATOR_INPUT)
local comb1 = station.entity_comb1
local status1 = comb1.status
---@type Signal[]?
local comb1_signals = nil
---@type Signal[]?
local comb2_signals = nil
if status1 == DEFINES_WORKING or status1 == DEFINES_LOW_POWER then
comb1_signals = comb1.get_merged_signals(DEFINES_COMBINATOR_INPUT)
end
return nil
local comb2 = station.entity_comb2
if comb2 then
local status2 = comb2.status
if status2 == DEFINES_WORKING or status2 == DEFINES_LOW_POWER then
comb2_signals = comb2.get_merged_signals(DEFINES_COMBINATOR_INPUT)
end
end
return comb1_signals, comb2_signals
end
---@param map_data MapData
@@ -373,22 +360,6 @@ function set_comb2(map_data, station)
end
end
---@param map_data MapData
---@param station Station
---@param signal SignalID
function get_threshold(map_data, station, signal)
local comb2 = station.entity_comb2
if comb2 then
local count = comb2.get_merged_signal(signal, defines.circuit_connector_id.combinator_input)
if count ~= 0 then
return abs(count)
end
end
return station.r_threshold
end
------------------------------------------------------------------------------
--[[alerts]]--
------------------------------------------------------------------------------

View File

@@ -182,6 +182,7 @@ local function on_station_built(map_data, stop, comb1, comb2)
deliveries_total = 0,
last_delivery_tick = map_data.total_ticks,
priority = 0,
item_priotity = nil,
r_threshold = 0,
locked_slots = 0,
--network_name = set_station_from_comb_state,
@@ -191,7 +192,8 @@ local function on_station_built(map_data, stop, comb1, comb2)
accepted_layouts = {},
layout_pattern = nil,
tick_signals = nil,
p_count_or_r_threshold_per_item = {},
item_p_counts = {},
item_thresholds = nil,
display_state = 0,
}
set_station_from_comb_state(station)
@@ -473,9 +475,11 @@ function combinator_update(map_data, comb)
local new_network = new_signal and new_signal.name or nil
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)
end
if params.second_constant ~= old_params.second_constant then
has_changed = true
local stop = global.to_stop[comb.unit_number]
if stop then
local station = global.stations[stop.unit_number]
@@ -708,9 +712,9 @@ local function on_train_arrives_buffer(map_data, stop, train_id, train)
set_r_wagon_combs(map_data, station, train)
end
elseif train.status == STATUS_P and train.p_station_id == station_id then
--this player intervention that is considered valid
--this is player intervention that is considered valid
elseif (train.status == STATUS_R or train.status == STATUS_R_TO_D) and train.r_station_id == station_id then
--this player intervention that is considered valid
--this is player intervention that is considered valid
elseif mod_settings.react_to_train_at_incorrect_station then
on_failed_delivery(map_data, train_id, train)
remove_train(map_data, train_id, train)

View File

@@ -184,6 +184,15 @@ local migrations_table = {
station.update_display = nil
end
end,
["1.0.10"] = function()
---@type MapData
local map_data = global
map_data.tick_state = STATE_INIT
map_data.tick_data = {}
for id, station in pairs(map_data.stations) do
station.p_count_or_r_threshold_per_item = nil
end
end,
}
---@param data ConfigurationChangedData