removed provide threshold

This commit is contained in:
Monica Moniot
2022-11-10 19:20:29 -05:00
parent e6a8d72f85
commit 0b370407fa
14 changed files with 335 additions and 265 deletions

View File

@@ -70,49 +70,6 @@ function create_manifest_schedule(depot_name, p_stop, r_stop, manifest)
}}
end
---@param station Station
local function get_signals(station)
local comb = station.entity_comb1
if comb.valid and (comb.status == defines.entity_status.working or comb.status == defines.entity_status.low_power) then
return comb.get_merged_signals(defines.circuit_connector_id.combinator_input)
else
return nil
end
end
---@param map_data MapData
---@param comb LuaEntity
---@param signals ConstantCombinatorParameters[]?
function set_combinator_output(map_data, comb, signals)
local out = map_data.to_output[comb.unit_number]
if out.valid then
out.get_or_create_control_behavior().parameters = signals
end
end
---@param comb LuaEntity
---@param op string
function set_combinator_operation(comb, op)
local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local control = a.parameters
control.operation = op
a.parameters = control
end
---@param map_data MapData
---@param station Station
local function set_comb2(map_data, station)
if station.entity_comb2 then
local deliveries = station.deliveries
local signals = {}
for item_name, count in pairs(deliveries) do
local i = #signals + 1
local is_fluid = game.item_prototypes[item_name] == nil--NOTE: this is expensive
signals[i] = {index = i, signal = {type = is_fluid and "fluid" or "item", name = item_name}, count = -count}
end
set_combinator_output(map_data, station.entity_comb2, signals)
end
end
---@param map_data MapData
---@param station Station
---@param manifest Manifest
@@ -128,20 +85,6 @@ function remove_manifest(map_data, station, manifest, sign)
station.deliveries_total = station.deliveries_total - 1
end
---@param map_data MapData
---@param signal SignalID
local function get_thresholds(map_data, station, signal)
local comb2 = station.entity_comb2
if comb2 and comb2.valid then
local count = comb2.get_merged_signal(signal, defines.circuit_connector_id.combinator_input)
if count > 0 then
return station.r_threshold, count
elseif count < 0 then
return -count, station.p_threshold
end
end
return station.r_threshold, station.p_threshold
end
---@param stop0 LuaEntity
---@param stop1 LuaEntity
@@ -150,12 +93,12 @@ local function get_stop_dist(stop0, stop1)
end
---@param map_data MapData
---@param r_station_id uint
---@param p_station_id uint
---@param item_type string
local function get_valid_train(map_data, r_station_id, p_station_id, item_type)
---@param min_amount_to_move int
local function get_valid_train(map_data, r_station_id, p_station_id, item_type, min_amount_to_move)
--NOTE: this code is the critical section for run-time optimization
local r_station = map_data.stations[r_station_id]
local p_station = map_data.stations[p_station_id]
@@ -185,10 +128,10 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type)
--check layout validity for both stations
local capacity = (is_fluid and train.fluid_capacity) or train.item_slot_capacity
if
capacity > 0 and
capacity > min_amount_to_move and
btest(netand, depot.network_flag) and
(r_station.is_all or r_station.accepted_layouts[layout_id]) and
(p_station.is_all or p_station.accepted_layouts[layout_id])
(r_station.allows_all_trains or r_station.accepted_layouts[layout_id]) and
(p_station.allows_all_trains or p_station.accepted_layouts[layout_id])
then
valid_train_exists = true
--check if exists valid path
@@ -227,48 +170,35 @@ local function send_train_between(map_data, r_station_id, p_station_id, depot, p
---@type string
local network_name = depot.network_name
local requests = {}
local manifest = {}
local r_signals = r_station.tick_signals
if r_signals then
for k, v in pairs(r_signals) do
---@type string
local item_name = v.signal.name
local item_count = v.count
local effective_item_count = item_count + (r_station.deliveries[item_name] or 0)
if effective_item_count < 0 and item_count < 0 then
requests[item_name] = -effective_item_count
end
end
end
local p_signals = p_station.tick_signals
if p_signals then
for k, v in pairs(p_signals) do
local item_name = v.signal.name
local item_count = v.count
local item_type = v.signal.type
local effective_item_count = item_count + (p_station.deliveries[item_name] or 0)
if effective_item_count > 0 and item_count > 0 then
local r = requests[item_name]
if r then
local item = {name = item_name, type = item_type, count = min(r, effective_item_count)}
if item_name == primary_item_name then
manifest[#manifest + 1] = manifest[1]
manifest[1] = item
else
manifest[#manifest + 1] = item
end
for k, v in pairs(r_station.tick_signals) do
---@type string
local item_name = v.signal.name
local item_type = v.signal.type
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]
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)}
if item_name == primary_item_name then
manifest[#manifest + 1] = manifest[1]
manifest[1] = item
else
manifest[#manifest + 1] = item
end
end
end
end
local locked_slots = max(p_station.locked_slots, r_station.locked_slots)
--locked slots is only taken into account after the train is already approved for dispatch
local locked_slots = p_station.locked_slots
local total_slots_left = train.item_slot_capacity
if locked_slots > 0 then
total_slots_left = max(total_slots_left - #train.entity.cargo_wagons*locked_slots, min(total_slots_left, #train.entity.cargo_wagons))
local total_cw = #train.entity.cargo_wagons
total_slots_left = min(total_slots_left, max(total_slots_left - total_cw*locked_slots, total_cw))
end
local total_liquid_left = train.fluid_capacity
@@ -307,7 +237,6 @@ local function send_train_between(map_data, r_station_id, p_station_id, depot, p
r_station.deliveries_total = r_station.deliveries_total + 1
p_station.deliveries_total = p_station.deliveries_total + 1
assert(manifest[1].name == primary_item_name)
for item_i, item in ipairs(manifest) do
assert(item.count > 0, "main.lua error, transfer amount was not positive")
@@ -420,12 +349,12 @@ local function tick_poll_station(map_data, mod_settings)
if station.network_name and station.deliveries_total < station.entity_stop.trains_limit then
station.r_threshold = mod_settings.r_threshold
station.p_threshold = mod_settings.p_threshold
station.priority = 0
station.locked_slots = 0
station.network_flag = mod_settings.network_flag
local signals = get_signals(station)
station.tick_signals = signals
table_clear(station.p_count_or_r_threshold_per_item)
if signals then
for k, v in pairs(signals) do
local item_name = v.signal.name
@@ -436,10 +365,8 @@ local function tick_poll_station(map_data, mod_settings)
if item_name == SIGNAL_PRIORITY then
station.priority = item_count
elseif item_name == REQUEST_THRESHOLD and item_count ~= 0 then
--NOTE: thresholds must be >0 or they will cause a crash
--NOTE: thresholds must be >0 or they can cause a crash
station.r_threshold = abs(item_count)
elseif item_name == PROVIDE_THRESHOLD and item_count ~= 0 then
station.p_threshold = abs(item_count)
elseif item_name == LOCKED_SLOTS then
station.locked_slots = max(item_count, 0)
end
@@ -453,12 +380,13 @@ local function tick_poll_station(map_data, mod_settings)
end
end
for k, v in pairs(signals) do
---@type string
local item_name = v.signal.name
local item_count = v.count
local effective_item_count = item_count + (station.deliveries[item_name] or 0)
local r_threshold, p_threshold = get_thresholds(map_data, station, v.signal)
local r_threshold = get_threshold(map_data, station, v.signal)
if -effective_item_count >= r_threshold and -item_count >= r_threshold then
if station.is_r and -effective_item_count >= r_threshold and -item_count >= r_threshold then
local item_network_name = station.network_name..":"..item_name
local stations = all_r_stations[item_network_name]
if stations == nil then
@@ -468,7 +396,8 @@ local function tick_poll_station(map_data, mod_settings)
all_names[#all_names + 1] = v.signal
end
stations[#stations + 1] = station_id
elseif effective_item_count >= p_threshold and item_count >= p_threshold then
station.p_count_or_r_threshold_per_item[item_name] = r_threshold
elseif 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
@@ -476,6 +405,7 @@ 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
else
signals[k] = nil
end
@@ -544,6 +474,10 @@ local function tick_dispatch(map_data, mod_settings)
end
local r_station_id = table_remove(r_stations--[[@as uint[] ]])
local r_station = stations[r_station_id]
local item_name = tick_data.item_name
local item_type = tick_data.item_type
local r_threshold = r_station.p_count_or_r_threshold_per_item[item_name]
local best = 0
local best_depot = nil
@@ -551,24 +485,27 @@ local function tick_dispatch(map_data, mod_settings)
local highest_prior = -INF
local could_have_been_serviced = false
for j, p_station_id in ipairs(p_stations) do
local depot, d = get_valid_train(map_data, r_station_id, p_station_id, tick_data.item_type)
local prior = stations[p_station_id].priority
if prior > highest_prior or (prior == highest_prior and d < best_dist) then
if depot then
best = j
best_dist = d
best_depot = depot
highest_prior = prior
elseif d < INF then
could_have_been_serviced = true
best = j
local p_station = stations[p_station_id]
if p_station.p_count_or_r_threshold_per_item[item_name] >= r_threshold then
local prior = p_station.priority
local depot, d = get_valid_train(map_data, r_station_id, p_station_id, item_type, r_threshold)
if prior > highest_prior or (prior == highest_prior and d < best_dist) then
if depot then
best = j
best_dist = d
best_depot = depot
highest_prior = prior
elseif d < INF then
could_have_been_serviced = true
best = j
end
end
end
end
if best_depot then
send_train_between(map_data, r_station_id, table_remove(p_stations, best), best_depot, tick_data.item_name)
send_train_between(map_data, r_station_id, table_remove(p_stations, best), best_depot, item_name)
elseif could_have_been_serviced then
send_missing_train_alert_for_stops(stations[r_station_id].entity_stop, stations[p_stations[best]].entity_stop)
send_missing_train_alert_for_stops(r_station.entity_stop, stations[p_stations[best]].entity_stop)
end
return false
end

View File

@@ -0,0 +1,100 @@
--By Mami
local abs = math.abs
local floor = math.floor
---@param param ArithmeticCombinatorParameters
function get_comb_secondary_state(param)
local bits = param.second_constant or 0
return bits%2 == 1, floor(bits/2)%3
end
---@param depot Depot
function set_depot_from_comb_state(depot)
local param = depot.entity_comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
local signal = param.first_signal
depot.network_name = signal and signal.name or nil
end
---@param station Station
function set_station_from_comb_state(station)
--NOTE: this does nothing to update currently active deliveries
local param = station.entity_comb1.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
local bits = param.second_constant or 0
local is_pr_state = floor(bits/2)%3
local signal = param.first_signal
station.network_name = signal and signal.name or nil
station.allows_all_trains = bits%2 == 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
end
---@param control LuaArithmeticCombinatorControlBehavior
function set_comb_allows_all_trains(control, allows_all_trains)
local param = control.parameters
local bits = param.second_constant or 0
param.second_constant = (bits - bits%2) + (allows_all_trains and 1 or 0)
control.parameters = param
end
---@param control LuaArithmeticCombinatorControlBehavior
function set_comb_is_pr_state(control, is_pr_state)
local param = control.parameters
local bits = param.second_constant or 0
param.second_constant = (bits%2) + (2*is_pr_state)
control.parameters = param
end
---@param map_data MapData
---@param comb LuaEntity
---@param signals ConstantCombinatorParameters[]?
function set_combinator_output(map_data, comb, signals)
local out = map_data.to_output[comb.unit_number]
if out.valid then
out.get_or_create_control_behavior().parameters = signals
end
end
---@param comb LuaEntity
---@param op string
function set_combinator_operation(comb, op)
local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local control = a.parameters
control.operation = op
a.parameters = control
end
---@param station Station
function get_signals(station)
local comb = station.entity_comb1
if comb.valid and (comb.status == defines.entity_status.working or comb.status == defines.entity_status.low_power) then
return comb.get_merged_signals(defines.circuit_connector_id.combinator_input)
else
return nil
end
end
---@param map_data MapData
---@param station Station
function set_comb2(map_data, station)
if station.entity_comb2 then
local deliveries = station.deliveries
local signals = {}
for item_name, count in pairs(deliveries) do
local i = #signals + 1
local is_fluid = game.item_prototypes[item_name] == nil--NOTE: this is expensive
signals[i] = {index = i, signal = {type = is_fluid and "fluid" or "item", name = item_name}, count = -count}
end
set_combinator_output(map_data, station.entity_comb2, signals)
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 and comb2.valid 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

View File

@@ -6,7 +6,6 @@ NONEMPTY_TRAIN_NAME = "cybersyn-nonempty-train"
SIGNAL_PRIORITY = "cybersyn-priority"
REQUEST_THRESHOLD = "cybersyn-request-threshold"
PROVIDE_THRESHOLD = "cybersyn-provide-threshold"
LOCKED_SLOTS = "cybersyn-locked-slots"
COMBINATOR_NAME = "cybersyn-combinator"
@@ -16,6 +15,7 @@ COMBINATOR_CLOSE_SOUND = "entity-close/cybersyn-combinator"
OPERATION_DEFAULT = "*"
OPERATION_PRIMARY_IO = "/"
OPERATION_PRIMARY_IO_ACTIVE = "^"
OPERATION_PRIMARY_IO_NOT_FOUND = "<<"
OPERATION_SECONDARY_IO = "%"
OPERATION_DEPOT = "+"
OPERATION_WAGON_MANIFEST = "-"

View File

@@ -16,11 +16,12 @@
---@field public economy Economy
---@class Station
---@field public is_p boolean
---@field public is_r boolean
---@field public deliveries_total int
---@field public last_delivery_tick int
---@field public priority int --transient
---@field public r_threshold int >= 0 --transient
---@field public p_threshold int >= 0 --transient
---@field public locked_slots int >= 0 --transient
---@field public entity_stop LuaEntity
---@field public entity_comb1 LuaEntity
@@ -29,10 +30,11 @@
---@field public deliveries {[string]: int}
---@field public network_name string?
---@field public network_flag int --transient
---@field public is_all boolean
---@field public allows_all_trains boolean
---@field public accepted_layouts TrainClass
---@field public layout_pattern string?
---@field public tick_signals {[uint]: Signal}? --transient
---@field public p_count_or_r_threshold_per_item {[string]: int}? --transient
---@class Depot
---@field public priority int --transient
@@ -67,12 +69,18 @@
---@class CybersynModSettings
---@field public tps int
---@field public r_threshold int
---@field public p_threshold int
---@field public network_flag int
---@type CybersynModSettings
mod_settings = {}
local pairs = pairs
function table_clear(tab)
for k, _ in pairs(tab) do
tab[k] = nil
end
end
function init_global()
global.total_ticks = 0
global.tick_state = STATE_INIT

View File

@@ -30,10 +30,21 @@ STATUS_NAMES_DEFAULT = "entity-status.disabled"
---@param player LuaPlayer
function gui_opened(comb, player)
local rootgui = player.gui.screen
local selected_index = 0
local control = comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
local op = control.operation
if op == OPERATION_PRIMARY_IO or op == OPERATION_PRIMARY_IO_ACTIVE then
local selected_index = 0
local switch_state = "none"
local allows_all_trains, is_pr_state = get_comb_secondary_state(control)
if is_pr_state == 0 then
switch_state = "none"
elseif is_pr_state == 1 then
switch_state = "left"
elseif is_pr_state == 2 then
switch_state = "right"
end
if op == OPERATION_PRIMARY_IO or op == OPERATION_PRIMARY_IO_ACTIVE or op == OPERATION_PRIMARY_IO_NOT_FOUND then
selected_index = 1
elseif op == OPERATION_SECONDARY_IO then
selected_index = 2
@@ -43,61 +54,67 @@ function gui_opened(comb, player)
selected_index = 4
end
local window = flib_gui.build(rootgui, {
{type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, children={
--title bar
{type="flow", ref={"titlebar"}, children={
{type="label", style="frame_title", caption={"cybersyn-gui.combinator-title"}, elem_mods={ignored_by_interaction=true}},
{type="empty-widget", style="flib_titlebar_drag_handle", elem_mods={ignored_by_interaction=true}},
{type="sprite-button", style="frame_action_button", mouse_button_filter={"left"}, sprite="utility/close_white", hovered_sprite="utility/close_black", name=COMBINATOR_NAME, actions={
on_click = {"close", comb.unit_number}
}}
}},
{type="frame", style="inside_shallow_frame_with_padding", style_mods={padding=12}, children={
{type="flow", direction="vertical", style_mods={horizontal_align="left"}, children={
--status
{type="flow", style="status_flow", direction="horizontal", style_mods={vertical_align="center", horizontally_stretchable=true, bottom_padding=4}, children={
{type="sprite", sprite=STATUS_SPRITES[comb.status] or STATUS_SPRITES_DEFAULT, style="status_image", ref={"status_icon"}, style_mods={stretch_image_to_widget_size=true}},
{type="label", caption={STATUS_NAMES[comb.status] or STATUS_NAMES_DEFAULT}, ref={"status_label"}}
}},
--preview
{type="frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={
{type="entity-preview", style="wide_entity_button", ref={"preview"}},
}},
--drop down
{type="label", style="heading_3_label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}},
{type="drop-down", style_mods={top_padding=3}, ref={"operation"}, actions={
on_selection_state_changed={"drop-down", comb.unit_number}
}, selected_index=selected_index, items={
{"cybersyn-gui.comb1"},
{"cybersyn-gui.comb2"},
{"cybersyn-gui.depot"},
{"cybersyn-gui.wagon-manifest"},
}},
---choose-elem-button
{type="line", style_mods={top_padding=10}},
{type="label", name="network_label", ref={"network_label"}, style="heading_3_label", caption={"cybersyn-gui.network"}, style_mods={top_padding=7}},
{type="flow", name="bottom", direction="horizontal", children={
{type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", ref={"network"}, elem_type="signal", signal=control.first_signal, style_mods={bottom_margin=2, right_margin=6}, actions={
on_elem_changed={"choose-elem-button", comb.unit_number}
local window = flib_gui.build(rootgui, {
{type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, children={
--title bar
{type="flow", ref={"titlebar"}, children={
{type="label", style="frame_title", caption={"cybersyn-gui.combinator-title"}, elem_mods={ignored_by_interaction=true}},
{type="empty-widget", style="flib_titlebar_drag_handle", elem_mods={ignored_by_interaction=true}},
{type="sprite-button", style="frame_action_button", mouse_button_filter={"left"}, sprite="utility/close_white", hovered_sprite="utility/close_black", name=COMBINATOR_NAME, actions={
on_click = {"close", comb.unit_number}
}}
}},
{type="frame", style="inside_shallow_frame_with_padding", style_mods={padding=12}, children={
{type="flow", direction="vertical", style_mods={horizontal_align="left"}, children={
--status
{type="flow", style="status_flow", direction="horizontal", style_mods={vertical_align="center", horizontally_stretchable=true, bottom_padding=4}, children={
{type="sprite", sprite=STATUS_SPRITES[comb.status] or STATUS_SPRITES_DEFAULT, style="status_image", ref={"status_icon"}, style_mods={stretch_image_to_widget_size=true}},
{type="label", caption={STATUS_NAMES[comb.status] or STATUS_NAMES_DEFAULT}, ref={"status_label"}}
}},
{type="checkbox", name="radiobutton", ref={"radiobutton"}, state=control.second_constant ~= 1, style_mods={top_margin=4}, actions={
on_checked_state_changed={"radiobutton", comb.unit_number}
--preview
{type="frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={
{type="entity-preview", style="wide_entity_button", ref={"preview"}},
}},
{type="label", name="radiolabel", style_mods={single_line=false, maximal_width=330, left_padding=3}, ref={"radiolabel"}, caption={"cybersyn-gui.auto-description"}},
--drop down
{type="label", style="heading_3_label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}},
{type="flow", name="top", direction="horizontal", style_mods={vertical_align="center"}, children={
{type="drop-down", style_mods={top_padding=3, right_margin=8}, ref={"operation"}, actions={
on_selection_state_changed={"drop-down", comb.unit_number}
}, selected_index=selected_index, items={
{"cybersyn-gui.comb1"},
{"cybersyn-gui.comb2"},
{"cybersyn-gui.depot"},
{"cybersyn-gui.wagon-manifest"},
}},
{type="switch", name="switch", ref={"switch"}, allow_none_state=true, switch_state=switch_state, left_label_caption={"cybersyn-gui.switch-provide"}, right_label_caption={"cybersyn-gui.switch-request"}, left_label_tooltip={"cybersyn-gui.switch-provide-tooltip"}, right_label_tooltip={"cybersyn-gui.switch-request-tooltip"}, actions={
on_switch_state_changed={"switch", comb.unit_number}
}}
}},
---choose-elem-button
{type="line", style_mods={top_padding=10}},
{type="label", name="network_label", ref={"network_label"}, style="heading_3_label", caption={"cybersyn-gui.network"}, style_mods={top_padding=8}},
{type="flow", name="bottom", direction="horizontal", style_mods={vertical_align="center"}, children={
{type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", ref={"network"}, elem_type="signal", tooltip={"cybersyn-gui.network-tooltip"}, signal=control.first_signal, style_mods={bottom_margin=1, right_margin=6}, actions={
on_elem_changed={"choose-elem-button", comb.unit_number}
}},
{type="checkbox", name="radio_button", ref={"radio_button"}, state=not allows_all_trains, tooltip={"cybersyn-gui.auto-tooltip"}, actions={
on_checked_state_changed={"radio_button", comb.unit_number}
}},
{type="label", name="radio_label", style_mods={left_padding=3}, ref={"radio_label"}, caption={"cybersyn-gui.auto-description"}},
}}
}}
}}
}}
}}
})
})
window.preview.entity = comb
window.titlebar.drag_target = window.main_window
window.main_window.force_auto_center()
window.network.visible = selected_index == 1 or selected_index == 3
window.network_label.visible = selected_index == 1 or selected_index == 3
window.radiobutton.visible = selected_index == 1
window.radiolabel.visible = selected_index == 1
window.radio_button.visible = selected_index == 1
window.radio_label.visible = selected_index == 1
window.switch.visible = selected_index == 1
player.opened = window.main_window
end
@@ -142,31 +159,37 @@ function register_gui_actions()
local comb = global.to_comb[msg[2]]
if not comb or not comb.valid then return end
local parent = element.parent.bottom
local top_flow = element.parent
local all_flow = top_flow.parent
local bottom_flow = all_flow.bottom
if element.selected_index == 1 then
set_combinator_operation(comb, OPERATION_PRIMARY_IO)
element.parent["network_label"].visible = true
parent["network"].visible = true
parent["radiobutton"].visible = true
parent["radiolabel"].visible = true
top_flow["switch"].visible = true
all_flow["network_label"].visible = true
bottom_flow["network"].visible = true
bottom_flow["radio_button"].visible = true
bottom_flow["radio_label"].visible = true
elseif element.selected_index == 2 then
set_combinator_operation(comb, OPERATION_SECONDARY_IO)
element.parent["network_label"].visible = false
parent["network"].visible = false
parent["radiobutton"].visible = false
parent["radiolabel"].visible = false
top_flow["switch"].visible = false
all_flow["network_label"].visible = false
bottom_flow["network"].visible = false
bottom_flow["radio_button"].visible = false
bottom_flow["radio_label"].visible = false
elseif element.selected_index == 3 then
set_combinator_operation(comb, OPERATION_DEPOT)
element.parent["network_label"].visible = true
parent["network"].visible = true
parent["radiobutton"].visible = false
parent["radiolabel"].visible = false
top_flow["switch"].visible = false
all_flow["network_label"].visible = true
bottom_flow["network"].visible = true
bottom_flow["radio_button"].visible = false
bottom_flow["radio_label"].visible = false
elseif element.selected_index == 4 then
set_combinator_operation(comb, OPERATION_WAGON_MANIFEST)
element.parent["network_label"].visible = false
parent["network"].visible = false
parent["radiobutton"].visible = false
parent["radiolabel"].visible = false
top_flow["switch"].visible = false
all_flow["network_label"].visible = false
bottom_flow["network"].visible = false
bottom_flow["radio_button"].visible = false
bottom_flow["radio_label"].visible = false
else
return
end
@@ -188,28 +211,43 @@ function register_gui_actions()
else
control.first_signal = signal
end
a.parameters = control
on_combinator_network_updated(global, comb, signal and signal.name or nil)
elseif msg[1] == "radiobutton" then
elseif msg[1] == "radio_button" then
local element = event.element
if not element then return end
local comb = global.to_comb[msg[2]]
if not comb or not comb.valid then return end
local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local control = a.parameters
local is_auto = element.state
control.second_constant = is_auto and 0 or 1
a.parameters = control
local allows_all_trains = element.state
set_comb_allows_all_trains(a, allows_all_trains)
local stop = global.to_stop[comb.unit_number]
if stop then
local station = global.stations[stop.unit_number]
if station then
set_station_train_class(global, station, not is_auto)
set_station_train_class(global, station, allows_all_trains)
end
end
elseif msg[1] == "switch" then
local element = event.element
if not element then return end
local comb = global.to_comb[msg[2]]
if not comb or not comb.valid then return end
local is_pr_state = (element.switch_state == "none" and 0) or (element.switch_state == "left" and 1) or 2
local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
set_comb_is_pr_state(a, is_pr_state)
local stop = global.to_stop[comb.unit_number]
if stop then
local station = global.stations[stop.unit_number]
if station then
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
end
end

View File

@@ -447,11 +447,11 @@ end
---@param map_data MapData
---@param station Station
---@param is_all boolean
function set_station_train_class(map_data, station, is_all)
if station.is_all ~= is_all then
station.is_all = is_all
if not is_all then
---@param allows_all_trains boolean
function set_station_train_class(map_data, station, allows_all_trains)
if station.allows_all_trains ~= allows_all_trains then
station.allows_all_trains = allows_all_trains
if not allows_all_trains then
reset_station_layout(map_data, station, nil)
end
end
@@ -461,7 +461,7 @@ end
---@param station Station
---@param forbidden_entity LuaEntity?
function update_station_if_auto(map_data, station, forbidden_entity)
if not station.is_all then
if not station.allows_all_trains then
reset_station_layout(map_data, station, forbidden_entity)
end
end

View File

@@ -91,15 +91,16 @@ end
---@param map_data MapData
---@param stop LuaEntity
---@param comb LuaEntity
local function on_depot_built(map_data, stop, comb, control)
local function on_depot_built(map_data, stop, comb)
local depot = {
entity_stop = stop,
entity_comb = comb,
network_name = control.first_signal and control.first_signal.name or nil,
--network_name = nil,
priority = 0,
network_flag = 0,
}
map_data.depots[stop.unit_number] = depot
set_depot_from_comb_state(depot)
end
local function on_depot_broken(map_data, depot)
@@ -117,8 +118,7 @@ end
---@param stop LuaEntity
---@param comb1 LuaEntity
---@param comb2 LuaEntity
---@param control ArithmeticCombinatorParameters
local function on_station_built(map_data, stop, comb1, comb2, control)
local function on_station_built(map_data, stop, comb1, comb2)
local station = {
entity_stop = stop,
entity_comb1 = comb1,
@@ -130,13 +130,14 @@ local function on_station_built(map_data, stop, comb1, comb2, control)
r_threshold = 0,
p_threshold = 0,
locked_slots = 0,
network_name = control.first_signal and control.first_signal.name or nil,
--network_name = param.first_signal and param.first_signal.name or nil,
network_flag = 0,
deliveries = {},
is_all = control.second_constant == 1,
--allows_all_trains = param.second_constant == 1,
accepted_layouts = {},
layout_pattern = nil,
}
set_station_from_comb_state(station)
map_data.stations[stop.unit_number] = station
update_station_if_auto(map_data, station, nil)
@@ -244,18 +245,18 @@ local function on_combinator_built(map_data, comb)
map_data.to_output[comb.unit_number] = out
map_data.to_stop[comb.unit_number] = stop
local a = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local control = a.parameters
local op = control.operation
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local param = control.parameters
local op = param.operation
if op == OPERATION_DEFAULT then
op = OPERATION_PRIMARY_IO
control.operation = op
control.first_signal = NETWORK_SIGNAL_DEFAULT
a.parameters = control
elseif op == OPERATION_PRIMARY_IO_ACTIVE then
param.operation = op
param.first_signal = NETWORK_SIGNAL_DEFAULT
control.parameters = param
elseif op == OPERATION_PRIMARY_IO_ACTIVE or op == OPERATION_PRIMARY_IO_NOT_FOUND then
op = OPERATION_PRIMARY_IO
control.operation = op
a.parameters = control
param.operation = op
control.parameters = param
end
if op == OPERATION_WAGON_MANIFEST then
if rail then
@@ -269,7 +270,7 @@ local function on_combinator_built(map_data, comb)
if depot or station then
--NOTE: repeated combinators are ignored
else
on_depot_built(map_data, stop, comb, control)
on_depot_built(map_data, stop, comb)
end
end
elseif op == OPERATION_SECONDARY_IO then
@@ -279,23 +280,23 @@ local function on_combinator_built(map_data, comb)
station.entity_comb2 = comb
end
end
elseif stop then
control.operation = OPERATION_PRIMARY_IO
local station = map_data.stations[stop.unit_number]
local depot = map_data.depots[stop.unit_number]
if station then
--NOTE: repeated combinators are ignored
else
if depot then
--NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way
map_data.depots[stop.unit_number] = nil
elseif op == OPERATION_PRIMARY_IO then
if stop then
local station = map_data.stations[stop.unit_number]
if station then
--NOTE: repeated combinators are ignored
else
local depot = map_data.depots[stop.unit_number]
if depot then
on_depot_broken(map_data, depot)
end
--no station or depot
--add station
local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb)
on_station_built(map_data, stop, comb, comb2)
end
--no station or depot
--add station
local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb)
on_station_built(map_data, stop, comb, comb2, control)
end
end
end
@@ -341,14 +342,12 @@ local function on_combinator_broken(map_data, comb)
local comb1 = search_for_station_combinator(map_data, stop, OPERATION_PRIMARY_IO, comb)
if comb1 then
station.entity_comb1 = comb1
local control = comb1.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
station.network_name = control.first_signal and control.first_signal.name
set_station_from_comb_state(station)
else
on_station_broken(map_data, stop.unit_number, station)
local depot_comb = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb)
if depot_comb then
local control = depot_comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
on_depot_built(map_data, stop, depot_comb, control.first_signal)
on_depot_built(map_data, stop, depot_comb)
end
end
elseif station.entity_comb2 == comb then
@@ -360,9 +359,8 @@ local function on_combinator_broken(map_data, comb)
--NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way
local depot_comb = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb)
if depot_comb then
local control = depot_comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
depot.entity_comb = depot_comb
depot.network_name = control.first_signal and control.first_signal.name
set_depot_from_comb_state(depot)
else
on_depot_broken(map_data, depot)
end
@@ -404,7 +402,7 @@ local function on_stop_built(map_data, stop)
map_data.to_stop[entity.unit_number] = stop
local control = entity.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
local op = control.operation
if op == OPERATION_PRIMARY_IO then
if op == OPERATION_PRIMARY_IO or op == OPERATION_PRIMARY_IO_ACTIVE or op == OPERATION_PRIMARY_IO_NOT_FOUND then
comb1 = entity
elseif op == OPERATION_SECONDARY_IO then
comb2 = entity
@@ -414,9 +412,9 @@ local function on_stop_built(map_data, stop)
end
end
if comb1 then
on_station_built(map_data, stop, comb1, comb2, comb1.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]])
on_station_built(map_data, stop, comb1, comb2)
elseif depot_comb then
on_depot_built(map_data, stop, depot_comb, depot_comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]])
on_depot_built(map_data, stop, depot_comb)
end
end
---@param map_data MapData
@@ -743,7 +741,6 @@ end
local function on_settings_changed(event)
mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value --[[@as int]]
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
mod_settings.p_threshold = settings.global["cybersyn-provide-threshold"].value--[[@as int]]
mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]]
if event.setting == "cybersyn-ticks-per-second" then
local nth_tick = math.ceil(60/mod_settings.tps);
@@ -773,7 +770,6 @@ local filter_broken = {
local function main()
mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value --[[@as int]]
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
mod_settings.p_threshold = settings.global["cybersyn-provide-threshold"].value--[[@as int]]
mod_settings.network_flag = settings.global["cybersyn-network-flag"].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