mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-10 16:08:13 -06:00
removed provide threshold
This commit is contained in:
@@ -3,3 +3,9 @@ Version: 0.1.0
|
||||
Date: 2022-11-04
|
||||
Features:
|
||||
- Pre-Alpha release
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Version: 0.2.0
|
||||
Date: 2022-11-04
|
||||
Features:
|
||||
- Removed provide-threshold
|
||||
- Added ability to specify station type on a cybernetic combinator
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
require("scripts.constants")
|
||||
require("scripts.global")
|
||||
require("scripts.combinator")
|
||||
require("scripts.central-planning")
|
||||
require("scripts.layout")
|
||||
require("scripts.gui")
|
||||
|
||||
@@ -16,7 +16,6 @@ data:extend({
|
||||
cybersyn_tech,
|
||||
subgroup_signal,
|
||||
priority_signal,
|
||||
p_threshold_signal,
|
||||
r_threshold_signal,
|
||||
locked_slots_signal,
|
||||
missing_train_icon,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
@@ -1,20 +1,18 @@
|
||||
[mod-setting-name]
|
||||
cybersyn-ticks-per-second=Dispatcher updates per second
|
||||
cybersyn-request-threshold=Default requester threshold
|
||||
cybersyn-provide-threshold=Default provider threshold
|
||||
cybersyn-network-flag=Default network flags
|
||||
|
||||
[mod-setting-description]
|
||||
cybersyn-ticks-per-second=How many times per second the dispather should check for new deliveries. Deliveries are made one at a time per update. This value will be rounded up to a divisor of 60.
|
||||
cybersyn-request-threshold=The default request threshold when a request threshold signal is not given to a station. Huge values will prevent stations from taking requests from the network unless an explicit threshold is set.
|
||||
cybersyn-provide-threshold=The default provide threshold when a provide threshold signal is not given to a station. Huge values will prevent stations from providing to the network unless an explicit threshold is set.
|
||||
cybersyn-network-flag=The default set of networks a station will service when no network signal is given to a station. This integer is interpretted bit-wise to give 32 possible network flags to choose from.
|
||||
|
||||
[item-name]
|
||||
cybersyn-combinator=Cybernetic combinator
|
||||
|
||||
[item-description]
|
||||
cybersyn-combinator=Place next to a train stop to add it to the cybersyn train network. This stop can now request or provide items using the circuit network. Be sure to set a threshold signal.
|
||||
cybersyn-combinator=Place next to a train stop to add it to the cybersyn train network. This stop can now request or provide items that are reported to it by the circuit network.
|
||||
|
||||
[entity-name]
|
||||
cybersyn-combinator=Cybernetic combinator
|
||||
@@ -32,7 +30,6 @@ cybersyn-train-network=Train stop controllers capable of coordinating the inputs
|
||||
|
||||
[virtual-signal-name]
|
||||
cybersyn-priority=Station priority
|
||||
cybersyn-provide-threshold=Provide threshold
|
||||
cybersyn-request-threshold=Request threshold
|
||||
cybersyn-locked-slots=Locked slots per cargo wagon
|
||||
|
||||
@@ -49,4 +46,10 @@ comb2=Optional station control
|
||||
depot=Depot control
|
||||
wagon-manifest=Wagon control
|
||||
network=Network
|
||||
auto-description=Station automatically decides which trains in the network it can service (all trains are allowed by default)
|
||||
network-tooltip=A signal is used to identify which network this combinator is a member of. Trains will only be dispatched from depots to provide and request stations if they are all identified with the same signal.
|
||||
auto-tooltip=When checked trains in the network are automatically blacklisted if they are not able to interact with all of the loading and unloading machines present along the station. When unchecked the blacklist is empty and all trains are allowed.
|
||||
auto-description=Allow automatic train blacklist
|
||||
switch-provide=Provide only
|
||||
switch-request=Request only
|
||||
switch-provide-tooltip=Lock this station to only provide items to the network. By default it both requests and provides.
|
||||
switch-request-tooltip=Lock this station to only request items from the network. By default it both requests and provides.
|
||||
|
||||
@@ -14,15 +14,6 @@ priority_signal = {
|
||||
subgroup = "cybersyn-signal",
|
||||
order = "a"
|
||||
}
|
||||
p_threshold_signal = {
|
||||
type = "virtual-signal",
|
||||
name = PROVIDE_THRESHOLD,
|
||||
icon = "__cybersyn__/graphics/icons/provide-threshold.png",
|
||||
icon_size = 64,
|
||||
icon_mipmaps = 4,
|
||||
subgroup = "cybersyn-signal",
|
||||
order = "b"
|
||||
}
|
||||
r_threshold_signal = {
|
||||
type = "virtual-signal",
|
||||
name = REQUEST_THRESHOLD,
|
||||
|
||||
@@ -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,33 +170,19 @@ 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
|
||||
for k, v in pairs(r_station.tick_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)}
|
||||
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
|
||||
@@ -263,12 +192,13 @@ local function send_train_between(map_data, r_station_id, p_station_id, depot, p
|
||||
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,8 +485,10 @@ 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
|
||||
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
|
||||
@@ -565,10 +501,11 @@ local function tick_dispatch(map_data, mod_settings)
|
||||
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
|
||||
|
||||
100
cybersyn/scripts/combinator.lua
Normal file
100
cybersyn/scripts/combinator.lua
Normal 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
|
||||
@@ -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 = "-"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -66,7 +77,8 @@ local window = flib_gui.build(rootgui, {
|
||||
}},
|
||||
--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={
|
||||
{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"},
|
||||
@@ -74,17 +86,21 @@ local window = flib_gui.build(rootgui, {
|
||||
{"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=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={
|
||||
{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="radiobutton", ref={"radiobutton"}, state=control.second_constant ~= 1, style_mods={top_margin=4}, actions={
|
||||
on_checked_state_changed={"radiobutton", 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="radiolabel", style_mods={single_line=false, maximal_width=330, left_padding=3}, ref={"radiolabel"}, caption={"cybersyn-gui.auto-description"}},
|
||||
{type="label", name="radio_label", style_mods={left_padding=3}, ref={"radio_label"}, caption={"cybersyn-gui.auto-description"}},
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
@@ -96,8 +112,9 @@ local window = flib_gui.build(rootgui, {
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
elseif op == OPERATION_PRIMARY_IO then
|
||||
if stop then
|
||||
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
|
||||
local depot = map_data.depots[stop.unit_number]
|
||||
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
|
||||
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, control)
|
||||
on_station_built(map_data, stop, comb, comb2)
|
||||
end
|
||||
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
|
||||
|
||||
@@ -14,16 +14,7 @@ data:extend({
|
||||
name = "cybersyn-request-threshold",
|
||||
order = "ab",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 2000000000,
|
||||
minimum_value = 1,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-provide-threshold",
|
||||
order = "ac",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 2000000000,
|
||||
default_value = 2000,
|
||||
minimum_value = 1,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user