mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-15 08:12:47 -06:00
Experimental 1.2.2 (#21)
---------------------------------------------------------------------------------------------------
Version: 1.2.2
Date: 2022-12-29
Features:
- Added a station combinator setting to enable or disable the inactivity condition in a train's orders, disabled by default (but not in <=1.2.1 worlds)
- Added a depot combinator setting to enable depot bypass, enabled by default
- Added a depot combinator setting to force trains to park at the same depot, enabled by default
- Added network "each" for depots
- Added a map setting to modify the default locked slots per cargo wagon value
- Added a map setting to modify the default priority value
- Added a map setting to allow trains with cargo at depots, disabled by default
Changes:
- Inverted the sign of combinator outputs, a map setting has been added to maintain backwards compatibility with <=1.2.1 worlds
- Overhauled the wagon control combinator algorithm to spread items out between cargo wagons
- Trains with cargo held in the depot now check if they have been emptied and reset when they have
- Cargo capacity is now prioritized over distance when choosing trains
- Increased the default request threshold to 2000
- Improved English localization
Bugfixes:
- Fixed a bug where trains with cargo sometimes weren't getting held at depots
- Fixed a crash caused by changing a station combinator to the "each" network during a bad tick
- Fixed a crash when changing a refueler away from network each
- Multiple rare bugs and crashes relating to wagon control combinators are fixed
- Fixed a bug with refueler direct orders not being applied after moving through a space elevator
- Fixed a bug where filtered slots sometimes weren't being removed
---------------------------------------------------------------------------------------------------
This commit is contained in:
@@ -1,8 +1,33 @@
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Version: 1.2.2
|
||||
Date: 2022-12-29
|
||||
Features:
|
||||
- Added a station combinator setting to enable or disable the inactivity condition in a train's orders, disabled by default (but not in <=1.2.1 worlds)
|
||||
- Added a depot combinator setting to enable depot bypass, enabled by default
|
||||
- Added a depot combinator setting to force trains to park at the same depot, enabled by default
|
||||
- Added network "each" for depots
|
||||
- Added a map setting to modify the default locked slots per cargo wagon value
|
||||
- Added a map setting to modify the default priority value
|
||||
- Added a map setting to allow trains with cargo at depots, disabled by default
|
||||
Changes:
|
||||
- Inverted the sign of combinator outputs, a map setting has been added to maintain backwards compatibility with <=1.2.1 worlds
|
||||
- Overhauled the wagon control combinator algorithm to spread items out between cargo wagons
|
||||
- Trains with cargo held in the depot now check if they have been emptied and reset when they have
|
||||
- Cargo capacity is now prioritized over distance when choosing trains
|
||||
- Increased the default request threshold to 2000
|
||||
- Improved English localization
|
||||
Bugfixes:
|
||||
- Fixed a bug where trains with cargo sometimes weren't getting held at depots
|
||||
- Fixed a crash caused by changing a station combinator to the "each" network during a bad tick
|
||||
- Fixed a crash when changing a refueler away from network each
|
||||
- Multiple rare bugs and crashes relating to wagon control combinators are fixed
|
||||
- Fixed a bug with refueler direct orders not being applied after moving through a space elevator
|
||||
- Fixed a bug where filtered slots sometimes weren't being removed
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Version: 1.2.1
|
||||
Date: 2022-12-24
|
||||
Bugfixes:
|
||||
- Fixed an bug where sometimes refuelers would reject trains they should accept
|
||||
- Fixed a bug where sometimes refuelers would reject trains they should accept
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Version: 1.2.0
|
||||
Date: 2022-12-23
|
||||
@@ -49,7 +74,7 @@ Date: 2022-12-9
|
||||
Version: 1.1.3
|
||||
Date: 2022-12-8
|
||||
Bugfixes:
|
||||
- Fixed a crash when removing a fuel loader
|
||||
- Fixed a crash when removing a refueler
|
||||
- Fixed a gui bug
|
||||
- Fixed a crash on newly generated worlds
|
||||
- Fixed a crash with breaking combinators
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
--<goto p_continue> at line 310 jumps into the scope of local 'p_flag'
|
||||
require("scripts.constants")
|
||||
require("scripts.global")
|
||||
require("scripts.lib")
|
||||
require("scripts.factorio-api")
|
||||
require("scripts.layout")
|
||||
require("scripts.central-planning")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cybersyn",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.2",
|
||||
"title": "Project Cybersyn",
|
||||
"author": "Mami",
|
||||
"factorio_version": "1.1",
|
||||
|
||||
@@ -2,21 +2,29 @@
|
||||
cybersyn-ticks-per-second=Central planning updates per second
|
||||
cybersyn-update-rate=Central planning update rate
|
||||
cybersyn-request-threshold=Default request threshold
|
||||
cybersyn-priority=Default priority
|
||||
cybersyn-locked-slots=Default locked slots per cargo wagon
|
||||
cybersyn-network-flag=Default network mask
|
||||
cybersyn-fuel-threshold=Fuel threshold
|
||||
cybersyn-depot-bypass-enabled=Depot bypass enabled
|
||||
cybersyn-warmup-time=Station warmup time (sec)
|
||||
cybersyn-stuck-train-time=Stuck train timeout (sec)
|
||||
cybersyn-allow-cargo-in-depot=Allow cargo in depots
|
||||
cybersyn-invert-sign=Invert combinator output (deprecated)
|
||||
|
||||
[mod-setting-description]
|
||||
cybersyn-ticks-per-second=How many times per second the central planner should update the state of the network and schedule deliveries. This value will be rounded up to a divisor of 60. Setting this to 0 will stop all dispatches.
|
||||
cybersyn-update-rate=How many stations per tick can be polled at once or can have deliveries scheduled at once. Larger number allow the central planner to keep more up to date on the current state of the network, but at the cost of performance.
|
||||
cybersyn-request-threshold=The default request threshold when a request threshold signal is not given to a station. When a station receives a negative item signal that surpasses its request threshold, so long as any station exists with a positive signal greater than the request threshold, a delivery of that item will be scheduled between the two stations.
|
||||
cybersyn-priority=The default priority when a priority signal is not given to a station, depot or refueler. Stations with higher priorities will receive deliveries before stations with lower priorities.
|
||||
cybersyn-locked-slots=The default number of locked slots per cargo wagon when a "locked slots per cargo wagon" signal is not given to a station. When a provider station has locked slots per cargo wagon of X, any train attempting to make a delivery from it will have its orders modified so every cargo wagon will have at least X item slots left empty. This is necessary to make multi-item provider stations function correctly.
|
||||
cybersyn-network-flag=The default set of sub-networks a station will service when no network signal is given to a station. This integer is interpretted bit-wise to give 32 possible sub-networks to choose from.
|
||||
cybersyn-fuel-threshold=What percentage of a train's fuel inventory must be full to skip refueling. If this is set to 1, trains will always visit a fuel loader after completing a delivery.
|
||||
cybersyn-fuel-threshold=What percentage of a train's fuel inventory must be full to skip refueling. If this is set to 1, trains will always visit a refueler after completing a delivery.
|
||||
cybersyn-depot-bypass-enabled=If checked, when a train completes a delivery and refueling, it may take a new order from the network before having to return to its depot.
|
||||
cybersyn-warmup-time=How many seconds a cybernetic combinator will wait before connecting to the Cybersyn network. This is a grace period to modify or correct the circuit network before trains start dispatching to a newly blueprinted station.
|
||||
cybersyn-stuck-train-time=After this many seconds from a train's dispatch, an alert will be sent to let you know a train is probably stuck and has not completed its delivery. The player will likely have to debug their network to get the train unstuck.
|
||||
cybersyn-allow-cargo-in-depot=If checked, trains will be allowed to have cargo in depots; no alerts will be generated and the train will not be held. In addition, trains with orders to visit requester stations with "Inactivity condition" checked will wait for inactivity instead of waiting for empty cargo. Useful for creating train systems where depots handle excess cargo. For advanced users only.
|
||||
cybersyn-invert-sign=Flip the sign of the output of cybernetic combinators to be the same as it is in LTN or in earlier versions of Project Cybersyn.
|
||||
|
||||
[item-name]
|
||||
cybersyn-combinator=Cybernetic combinator
|
||||
@@ -48,7 +56,7 @@ unexpected-train=A train has unexpectedly returned to the depot before completin
|
||||
stuck-train=A train is stuck
|
||||
cannot-path-between-surfaces=A train is attempting to make a delivery between two unconnected surfaces, perhaps put them on separate networks
|
||||
depot-broken=A train is lost because its depot was broken
|
||||
refueler-broken=A train is lost because its fuel loader was broken
|
||||
refueler-broken=A train is lost because its refueler was broken
|
||||
station-broken=A train is lost because one of its delivery stations was broken
|
||||
train-at-incorrect=A train parked at a station it was not scheduled to delivered to
|
||||
missing-train=Could not find any train on the correct network to make a delivery from __2__ to __1__
|
||||
@@ -61,16 +69,22 @@ combinator-title=Cybernetic combinator
|
||||
operation=Mode
|
||||
comb1=Station
|
||||
depot=Depot
|
||||
refueler=Fuel loader
|
||||
refueler=Refueler
|
||||
comb2=Station control
|
||||
wagon-manifest=Wagon control
|
||||
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.
|
||||
network=Network
|
||||
network-tooltip=A signal is used to identify which network this combinator is a member of. Trains will only be dispatched from depots to provider and requester stations if they are all identified with the same signal.
|
||||
allow-list-description=Automatic allow-list
|
||||
allow-list-tooltip=When checked trains in the network are automatically added to the allow-list if every wagon of the train is able to be loaded or unloaded by this station. When unchecked the allow-list is not used and all trains are allowed to park here.
|
||||
is-stack-description=Stack thresholds
|
||||
is-stack-tooltip=When checked all request thresholds for this station are interpretted as a count of item stacks rather than a count of total items. Thresholds for fluids are unaffected.
|
||||
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.
|
||||
enable-inactive-description=Inactivity condition
|
||||
enable-inactive-tooltip=When checked a train at a provider is required to wait for inactivity even if its order has been fulfilled. This is frequently useful for preventing inserters from getting items stuck in their hands.
|
||||
use-same-depot-description=Require same depot
|
||||
use-same-depot-tooltip=When checked trains from this depot always return to this depot. When unchecked the train is allowed to return to any depot with the same name as this one.
|
||||
depot-bypass-description=Depot bypass
|
||||
depot-bypass-tooltip=When checked trains from this depot do not have to be parked at this depot to receive new orders, they just have to have no current active orders. They will still return to this depot if they are low on fuel and no refuelers are available.
|
||||
|
||||
@@ -40,15 +40,13 @@ function create_delivery(map_data, r_station_id, p_station_id, train_id, manifes
|
||||
local r_station = map_data.stations[r_station_id]
|
||||
local p_station = map_data.stations[p_station_id]
|
||||
local train = map_data.trains[train_id]
|
||||
local depot = map_data.depots[train.depot_id]
|
||||
|
||||
local is_at_depot = remove_available_train(map_data, train_id, train)
|
||||
|
||||
remove_available_train(map_data, train_id, train)
|
||||
local depot_id = train.parked_at_depot_id
|
||||
if depot_id then
|
||||
map_data.depots[depot_id].available_train_id = nil
|
||||
train.parked_at_depot_id = nil
|
||||
end
|
||||
--NOTE: we assume that the train is not being teleported at this time
|
||||
if set_manifest_schedule(map_data, train.entity, train.depot_name, train.se_depot_surface_i, p_station.entity_stop, r_station.entity_stop, manifest, depot_id ~= nil) then
|
||||
--NOTE: set_manifest_schedule is allowed to cancel the delivery at the last second if applying the schedule to the train makes it lost
|
||||
if set_manifest_schedule(map_data, train.entity, depot.entity_stop, not train.use_any_depot, p_station.entity_stop, p_station.enable_inactive, r_station.entity_stop, mod_settings.allow_cargo_in_depot and r_station.enable_inactive--[[@as boolean]], manifest, is_at_depot) then
|
||||
local old_status = train.status
|
||||
train.status = STATUS_TO_P
|
||||
train.p_station_id = p_station_id
|
||||
@@ -155,10 +153,12 @@ function create_manifest(map_data, r_station_id, p_station_id, train_id, primary
|
||||
|
||||
--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
|
||||
local total_item_slots
|
||||
if locked_slots > 0 then
|
||||
local total_cw = #train.entity.cargo_wagons
|
||||
total_slots_left = min(total_slots_left, max(total_slots_left - total_cw*locked_slots, total_cw))
|
||||
local total_cargo_wagons = #train.entity.cargo_wagons
|
||||
total_item_slots = max(train.item_slot_capacity - total_cargo_wagons*locked_slots, 1)
|
||||
else
|
||||
total_item_slots = train.item_slot_capacity
|
||||
end
|
||||
local total_liquid_left = train.fluid_capacity
|
||||
|
||||
@@ -174,13 +174,13 @@ function create_manifest(map_data, r_station_id, p_station_id, train_id, primary
|
||||
total_liquid_left = 0--no liquid merging
|
||||
keep_item = true
|
||||
end
|
||||
elseif total_slots_left > 0 then
|
||||
elseif total_item_slots > 0 then
|
||||
local stack_size = get_stack_size(map_data, item.name)
|
||||
local slots = ceil(item.count/stack_size)
|
||||
if slots > total_slots_left then
|
||||
item.count = total_slots_left*stack_size
|
||||
if slots > total_item_slots then
|
||||
item.count = total_item_slots*stack_size
|
||||
end
|
||||
total_slots_left = total_slots_left - slots
|
||||
total_item_slots = total_item_slots - slots
|
||||
keep_item = true
|
||||
end
|
||||
if keep_item then
|
||||
@@ -329,7 +329,7 @@ local function tick_dispatch(map_data, mod_settings)
|
||||
---@type uint
|
||||
local j = 1
|
||||
while j <= #p_stations do
|
||||
local p_flag, r_flag, netand, best_p_train_id, best_t_prior, best_t_to_p_dist, effective_count, override_threshold, p_prior, best_p_dist
|
||||
local p_flag, r_flag, netand, best_p_train_id, best_t_prior, best_capacity, best_t_to_p_dist, effective_count, override_threshold, p_prior, best_p_dist
|
||||
|
||||
local p_station_id = p_stations[j]
|
||||
local p_station = stations[p_station_id]
|
||||
@@ -337,8 +337,8 @@ local function tick_dispatch(map_data, mod_settings)
|
||||
goto p_continue
|
||||
end
|
||||
|
||||
p_flag = p_station.network_name == NETWORK_EACH and (p_station.network_flag[network_name] or 0) or p_station.network_flag
|
||||
r_flag = r_station.network_name == NETWORK_EACH and (r_station.network_flag[network_name] or 0) or r_station.network_flag
|
||||
p_flag = get_network_flag(p_station, network_name)
|
||||
r_flag = get_network_flag(r_station, network_name)
|
||||
netand = band(p_flag, r_flag)
|
||||
if netand == 0 then
|
||||
goto p_continue
|
||||
@@ -353,11 +353,13 @@ local function tick_dispatch(map_data, mod_settings)
|
||||
---@type uint?
|
||||
best_p_train_id = nil
|
||||
best_t_prior = -INF
|
||||
best_capacity = 0
|
||||
best_t_to_p_dist = INF
|
||||
if trains then
|
||||
for train_id, _ in pairs(trains) do
|
||||
local train = map_data.trains[train_id]
|
||||
if not btest(netand, train.network_flag) or train.se_is_being_teleported then
|
||||
local train_flag = get_network_flag(train, network_name)
|
||||
if not btest(netand, train_flag) or train.se_is_being_teleported then
|
||||
goto train_continue
|
||||
end
|
||||
if correctness < 2 then
|
||||
@@ -397,14 +399,19 @@ local function tick_dispatch(map_data, mod_settings)
|
||||
if train.priority < best_t_prior then
|
||||
goto train_continue
|
||||
end
|
||||
|
||||
if train.priority == best_t_prior and capacity < best_capacity then
|
||||
goto train_continue
|
||||
end
|
||||
|
||||
--check if path is shortest so we prioritize locality
|
||||
local t_to_p_dist = get_stop_dist(train.entity.front_stock, p_station.entity_stop) - DEPOT_PRIORITY_MULT*train.priority
|
||||
|
||||
if train.priority == best_t_prior and t_to_p_dist > best_t_to_p_dist then
|
||||
if capacity == best_capacity and t_to_p_dist > best_t_to_p_dist then
|
||||
goto train_continue
|
||||
end
|
||||
|
||||
best_p_train_id = train_id
|
||||
best_capacity = capacity
|
||||
best_t_prior = train.priority
|
||||
best_t_to_p_dist = t_to_p_dist
|
||||
::train_continue::
|
||||
@@ -507,10 +514,11 @@ local function tick_poll_station(map_data, mod_settings)
|
||||
end
|
||||
end
|
||||
station.r_threshold = mod_settings.r_threshold
|
||||
station.priority = 0
|
||||
station.priority = mod_settings.priority
|
||||
station.item_priority = nil
|
||||
station.locked_slots = 0
|
||||
if station.network_name == NETWORK_EACH then
|
||||
station.locked_slots = mod_settings.locked_slots
|
||||
local is_each = station.network_name == NETWORK_EACH
|
||||
if is_each then
|
||||
station.network_flag = {}
|
||||
else
|
||||
station.network_flag = mod_settings.network_flag
|
||||
@@ -548,12 +556,12 @@ local function tick_poll_station(map_data, mod_settings)
|
||||
if item_type == "virtual" then
|
||||
if item_name == SIGNAL_PRIORITY then
|
||||
station.priority = item_count
|
||||
elseif item_name == REQUEST_THRESHOLD and item_count ~= 0 then
|
||||
elseif item_name == REQUEST_THRESHOLD then
|
||||
--NOTE: thresholds must be >0 or they can cause a crash
|
||||
station.r_threshold = abs(item_count)
|
||||
elseif item_name == LOCKED_SLOTS then
|
||||
station.locked_slots = max(item_count, 0)
|
||||
elseif station.network_name == NETWORK_EACH then
|
||||
elseif is_each then
|
||||
station.network_flag[item_name] = item_count
|
||||
end
|
||||
comb1_signals[k] = nil
|
||||
@@ -645,8 +653,38 @@ local function tick_poll_station(map_data, mod_settings)
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param mod_settings CybersynModSettings
|
||||
local function tick_poll_train(map_data, mod_settings)
|
||||
function tick_init(map_data, mod_settings)
|
||||
local tick_data = map_data.tick_data
|
||||
|
||||
map_data.economy.all_p_stations = {}
|
||||
map_data.economy.all_r_stations = {}
|
||||
map_data.economy.all_names = {}
|
||||
|
||||
for i, id in pairs(map_data.warmup_station_ids) do
|
||||
local station = map_data.stations[id]
|
||||
if station then
|
||||
if station.last_delivery_tick + mod_settings.warmup_time*mod_settings.tps < map_data.total_ticks then
|
||||
map_data.active_station_ids[#map_data.active_station_ids + 1] = id
|
||||
map_data.warmup_station_ids[i] = nil
|
||||
end
|
||||
else
|
||||
map_data.warmup_station_ids[i] = nil
|
||||
end
|
||||
end
|
||||
if map_data.queue_station_update then
|
||||
for id, _ in pairs(map_data.queue_station_update) do
|
||||
local station = map_data.stations[id]
|
||||
if station then
|
||||
local pre = station.allows_all_trains
|
||||
set_station_from_comb(station)
|
||||
if station.allows_all_trains ~= pre then
|
||||
update_stop_if_auto(map_data, station, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
map_data.queue_station_update = nil
|
||||
end
|
||||
|
||||
--NOTE: the following has undefined behavior if last_train is deleted, this should be ok since the following doesn't care how inconsistent our access pattern is
|
||||
local train_id, train = next(map_data.trains, tick_data.last_train)
|
||||
tick_data.last_train = train_id
|
||||
@@ -657,10 +695,7 @@ local function tick_poll_train(map_data, mod_settings)
|
||||
end
|
||||
interface_raise_train_stuck(train_id)
|
||||
end
|
||||
end
|
||||
---@param map_data MapData
|
||||
local function tick_poll_comb(map_data, mod_settings)
|
||||
local tick_data = map_data.tick_data
|
||||
|
||||
--NOTE: the following has undefined behavior if last_comb is deleted
|
||||
local comb_id, comb = next(map_data.to_comb, tick_data.last_comb)
|
||||
tick_data.last_comb = comb_id
|
||||
@@ -673,6 +708,9 @@ local function tick_poll_comb(map_data, mod_settings)
|
||||
if refueler_id then
|
||||
set_refueler_from_comb(map_data, mod_settings, refueler_id)
|
||||
end
|
||||
|
||||
map_data.tick_state = STATE_POLL_STATIONS
|
||||
interface_raise_tick_init()
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param mod_settings CybersynModSettings
|
||||
@@ -680,30 +718,13 @@ 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%(8*mod_settings.tps) < 1 then
|
||||
process_active_alerts(map_data)
|
||||
end
|
||||
end
|
||||
|
||||
if map_data.tick_state == STATE_INIT then
|
||||
map_data.economy.all_p_stations = {}
|
||||
map_data.economy.all_r_stations = {}
|
||||
map_data.economy.all_names = {}
|
||||
for i, id in pairs(map_data.warmup_station_ids) do
|
||||
local station = map_data.stations[id]
|
||||
if station then
|
||||
if station.last_delivery_tick + mod_settings.warmup_time*mod_settings.tps < map_data.total_ticks then
|
||||
map_data.active_station_ids[#map_data.active_station_ids + 1] = id
|
||||
map_data.warmup_station_ids[i] = nil
|
||||
end
|
||||
else
|
||||
map_data.warmup_station_ids[i] = nil
|
||||
end
|
||||
end
|
||||
map_data.tick_state = STATE_POLL_STATIONS
|
||||
interface_raise_tick_init()
|
||||
tick_poll_train(map_data, mod_settings)
|
||||
tick_poll_comb(map_data)
|
||||
tick_init(map_data, mod_settings)
|
||||
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
|
||||
|
||||
@@ -22,6 +22,12 @@ MODE_DEPOT = "+"
|
||||
MODE_WAGON = "-"
|
||||
MODE_REFUELER = ">>"
|
||||
|
||||
SETTING_DISABLE_ALLOW_LIST = 2
|
||||
SETTING_IS_STACK = 3
|
||||
SETTING_ENABLE_INACTIVE = 4
|
||||
SETTING_USE_ANY_DEPOT = 5
|
||||
SETTING_DISABLE_DEPOT_BYPASS = 6
|
||||
|
||||
NETWORK_SIGNAL_DEFAULT = {name="signal-A", type="virtual"}
|
||||
NETWORK_EACH = "signal-each"
|
||||
INACTIVITY_TIME = 100
|
||||
|
||||
@@ -39,15 +39,32 @@ function se_get_space_elevator_name(surface)
|
||||
end
|
||||
|
||||
|
||||
---@param train LuaTrain
|
||||
function get_any_train_entity(train)
|
||||
return train.front_stock or train.back_stock or train.carriages[1]
|
||||
end
|
||||
|
||||
|
||||
---@param e Station|Refueler|Train
|
||||
---@param network_name string
|
||||
function get_network_flag(e, network_name)
|
||||
return e.network_name == NETWORK_EACH and (e.network_flag[network_name] or 0) or e.network_flag
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--[[train schedules]]--
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
local create_loading_order_condition = {type = "inactivity", compare_type = "and", ticks = INACTIVITY_TIME}
|
||||
local condition_wait_inactive = {type = "inactivity", compare_type = "and", ticks = INACTIVITY_TIME}
|
||||
local condition_only_inactive = {condition_wait_inactive}
|
||||
local condition_unloading_order = {{type = "empty", compare_type = "and"}}
|
||||
local condition_direct_to_station = {{type = "time", compare_type = "and", ticks = 1}}
|
||||
---@param stop LuaEntity
|
||||
---@param manifest Manifest
|
||||
function create_loading_order(stop, manifest)
|
||||
---@param enable_inactive boolean
|
||||
function create_loading_order(stop, manifest, enable_inactive)
|
||||
local condition = {}
|
||||
for _, item in ipairs(manifest) do
|
||||
local cond_type
|
||||
@@ -63,26 +80,30 @@ function create_loading_order(stop, manifest)
|
||||
condition = {comparator = "≥", first_signal = {type = item.type, name = item.name}, constant = item.count}
|
||||
}
|
||||
end
|
||||
condition[#condition + 1] = create_loading_order_condition
|
||||
if enable_inactive then
|
||||
condition[#condition + 1] = condition_wait_inactive
|
||||
end
|
||||
return {station = stop.backer_name, wait_conditions = condition}
|
||||
end
|
||||
|
||||
local create_unloading_order_condition = {{type = "empty", compare_type = "and"}}
|
||||
---@param stop LuaEntity
|
||||
function create_unloading_order(stop)
|
||||
return {station = stop.backer_name, wait_conditions = create_unloading_order_condition}
|
||||
---@param enable_inactive boolean
|
||||
function create_unloading_order(stop, enable_inactive)
|
||||
if enable_inactive then
|
||||
return {station = stop.backer_name, wait_conditions = condition_only_inactive}
|
||||
else
|
||||
return {station = stop.backer_name, wait_conditions = condition_unloading_order}
|
||||
end
|
||||
end
|
||||
|
||||
local create_inactivity_order_condition = {{type = "inactivity", compare_type = "and", ticks = INACTIVITY_TIME}}
|
||||
---@param depot_name string
|
||||
function create_inactivity_order(depot_name)
|
||||
return {station = depot_name, wait_conditions = create_inactivity_order_condition}
|
||||
return {station = depot_name, wait_conditions = condition_only_inactive}
|
||||
end
|
||||
|
||||
local create_direct_to_station_order_condition = {{type = "time", compare_type = "and", ticks = 1}}
|
||||
---@param stop LuaEntity
|
||||
function create_direct_to_station_order(stop)
|
||||
return {rail = stop.connected_rail, rail_direction = stop.connected_rail_direction, wait_conditions = create_direct_to_station_order_condition}
|
||||
return {rail = stop.connected_rail, rail_direction = stop.connected_rail_direction, wait_conditions = condition_direct_to_station}
|
||||
end
|
||||
|
||||
---@param train LuaTrain
|
||||
@@ -138,13 +159,15 @@ function se_create_elevator_order(elevator_name, is_train_in_orbit)
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param train LuaTrain
|
||||
---@param depot_name string
|
||||
---@param d_surface_i int
|
||||
---@param depot_stop LuaEntity
|
||||
---@param same_depot boolean
|
||||
---@param p_stop LuaEntity
|
||||
---@param p_enable_inactive boolean
|
||||
---@param r_stop LuaEntity
|
||||
---@param r_enable_inactive boolean
|
||||
---@param manifest Manifest
|
||||
---@param start_at_depot boolean?
|
||||
function set_manifest_schedule(map_data, train, depot_name, d_surface_i, p_stop, r_stop, manifest, start_at_depot)
|
||||
function set_manifest_schedule(map_data, train, depot_stop, same_depot, p_stop, p_enable_inactive, r_stop, r_enable_inactive, manifest, start_at_depot)
|
||||
--NOTE: can only return false if start_at_depot is false, it should be incredibly rare that this function returns false
|
||||
local old_schedule
|
||||
if not start_at_depot then
|
||||
@@ -153,6 +176,7 @@ function set_manifest_schedule(map_data, train, depot_name, d_surface_i, p_stop,
|
||||
local t_surface = train.front_stock.surface
|
||||
local p_surface = p_stop.surface
|
||||
local r_surface = r_stop.surface
|
||||
local d_surface_i = depot_stop.surface.index
|
||||
local t_surface_i = t_surface.index
|
||||
local p_surface_i = p_surface.index
|
||||
local r_surface_i = r_surface.index
|
||||
@@ -160,15 +184,19 @@ function set_manifest_schedule(map_data, train, depot_name, d_surface_i, p_stop,
|
||||
local is_r_on_t = t_surface_i == r_surface_i
|
||||
local is_d_on_t = t_surface_i == d_surface_i
|
||||
if is_p_on_t and is_r_on_t and is_d_on_t then
|
||||
local records = {
|
||||
create_inactivity_order(depot_stop.backer_name),
|
||||
create_direct_to_station_order(p_stop),
|
||||
create_loading_order(p_stop, manifest, p_enable_inactive),
|
||||
create_direct_to_station_order(r_stop),
|
||||
create_unloading_order(r_stop, r_enable_inactive),
|
||||
}
|
||||
if same_depot then
|
||||
records[6] = create_direct_to_station_order(depot_stop)
|
||||
end
|
||||
train.schedule = {
|
||||
current = start_at_depot and 1 or 2--[[@as uint]],
|
||||
records = {
|
||||
create_inactivity_order(depot_name),
|
||||
create_direct_to_station_order(p_stop),
|
||||
create_loading_order(p_stop, manifest),
|
||||
create_direct_to_station_order(r_stop),
|
||||
create_unloading_order(r_stop),
|
||||
}
|
||||
records = records
|
||||
}
|
||||
if old_schedule and not train.has_path then
|
||||
train.schedule = old_schedule
|
||||
@@ -186,14 +214,14 @@ function set_manifest_schedule(map_data, train, depot_name, d_surface_i, p_stop,
|
||||
if is_train_in_orbit or t_zone.orbit_index == other_zone.index then
|
||||
local elevator_name = se_get_space_elevator_name(t_surface)
|
||||
if elevator_name then
|
||||
local records = {create_inactivity_order(depot_name)}
|
||||
local records = {create_inactivity_order(depot_stop.backer_name)}
|
||||
if t_surface_i == p_surface_i then
|
||||
records[#records + 1] = create_direct_to_station_order(p_stop)
|
||||
else
|
||||
records[#records + 1] = se_create_elevator_order(elevator_name, is_train_in_orbit)
|
||||
is_train_in_orbit = not is_train_in_orbit
|
||||
end
|
||||
records[#records + 1] = create_loading_order(p_stop, manifest)
|
||||
records[#records + 1] = create_loading_order(p_stop, manifest, p_enable_inactive)
|
||||
|
||||
if p_surface_i ~= r_surface_i then
|
||||
records[#records + 1] = se_create_elevator_order(elevator_name, is_train_in_orbit)
|
||||
@@ -201,7 +229,7 @@ function set_manifest_schedule(map_data, train, depot_name, d_surface_i, p_stop,
|
||||
elseif t_surface_i == r_surface_i then
|
||||
records[#records + 1] = create_direct_to_station_order(r_stop)
|
||||
end
|
||||
records[#records + 1] = create_unloading_order(r_stop)
|
||||
records[#records + 1] = create_unloading_order(r_stop, r_enable_inactive)
|
||||
if r_surface_i ~= d_surface_i then
|
||||
records[#records + 1] = se_create_elevator_order(elevator_name, is_train_in_orbit)
|
||||
is_train_in_orbit = not is_train_in_orbit
|
||||
@@ -221,9 +249,9 @@ function set_manifest_schedule(map_data, train, depot_name, d_surface_i, p_stop,
|
||||
end
|
||||
--NOTE: create a schedule that cannot be fulfilled, the train will be stuck but it will give the player information what went wrong
|
||||
train.schedule = {current = 1, records = {
|
||||
create_inactivity_order(depot_name),
|
||||
create_loading_order(p_stop, manifest),
|
||||
create_unloading_order(r_stop),
|
||||
create_inactivity_order(depot_stop.backer_name),
|
||||
create_loading_order(p_stop, manifest, p_enable_inactive),
|
||||
create_unloading_order(r_stop, r_enable_inactive),
|
||||
}}
|
||||
lock_train(train)
|
||||
send_alert_cannot_path_between_surfaces(map_data, train)
|
||||
@@ -306,6 +334,78 @@ function get_comb_network_name(comb)
|
||||
|
||||
return signal and signal.name or nil
|
||||
end
|
||||
|
||||
---@param station Station
|
||||
function set_station_from_comb(station)
|
||||
--NOTE: this does nothing to update currently active deliveries
|
||||
--NOTE: this can only be called at the tick init boundary
|
||||
local params = get_comb_params(station.entity_comb1)
|
||||
local signal = params.first_signal
|
||||
|
||||
local bits = params.second_constant or 0
|
||||
local is_pr_state = bit_extract(bits, 0, 2)
|
||||
local allows_all_trains = bit_extract(bits, SETTING_DISABLE_ALLOW_LIST) > 0
|
||||
local is_stack = bit_extract(bits, SETTING_IS_STACK) > 0
|
||||
local enable_inactive = bit_extract(bits, SETTING_ENABLE_INACTIVE) > 0
|
||||
|
||||
station.network_name = signal and signal.name or nil
|
||||
station.allows_all_trains = allows_all_trains
|
||||
station.is_stack = is_stack
|
||||
station.enable_inactive = enable_inactive
|
||||
station.is_p = (is_pr_state == 0 or is_pr_state == 1) or nil
|
||||
station.is_r = (is_pr_state == 0 or is_pr_state == 2) or nil
|
||||
|
||||
if station.network_name == NETWORK_EACH then
|
||||
station.network_flag = {}
|
||||
end
|
||||
end
|
||||
---@param mod_settings CybersynModSettings
|
||||
---@param train Train
|
||||
---@param comb LuaEntity
|
||||
function set_train_from_comb(mod_settings, train, comb)
|
||||
--NOTE: this does nothing to update currently active deliveries
|
||||
local params = get_comb_params(comb)
|
||||
local signal = params.first_signal
|
||||
local network_name = signal and signal.name or nil
|
||||
|
||||
local bits = params.second_constant or 0
|
||||
local disable_bypass = bit_extract(bits, SETTING_DISABLE_DEPOT_BYPASS) > 0
|
||||
local use_any_depot = bit_extract(bits, SETTING_USE_ANY_DEPOT) > 0
|
||||
|
||||
train.network_name = network_name
|
||||
train.disable_bypass = disable_bypass
|
||||
train.use_any_depot = use_any_depot
|
||||
|
||||
local is_each = train.network_name == NETWORK_EACH
|
||||
if is_each then
|
||||
train.network_flag = {}
|
||||
else
|
||||
train.network_flag = mod_settings.network_flag
|
||||
end
|
||||
train.priority = mod_settings.priority
|
||||
local signals = comb.get_merged_signals(defines.circuit_connector_id.combinator_input)
|
||||
if signals then
|
||||
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_type == "virtual" then
|
||||
if item_name == SIGNAL_PRIORITY then
|
||||
train.priority = item_count
|
||||
elseif is_each then
|
||||
if item_name ~= REQUEST_THRESHOLD and item_name ~= LOCKED_SLOTS then
|
||||
train.network_flag[item_name] = item_count
|
||||
end
|
||||
end
|
||||
end
|
||||
if item_name == network_name then
|
||||
train.network_flag = item_count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param mod_settings CybersynModSettings
|
||||
---@param id uint
|
||||
@@ -316,12 +416,14 @@ function set_refueler_from_comb(map_data, mod_settings, id)
|
||||
local bits = params.second_constant or 0
|
||||
local signal = params.first_signal
|
||||
local old_network = refueler.network_name
|
||||
local old_network_flag = refueler.network_flag
|
||||
|
||||
refueler.network_name = signal and signal.name or nil
|
||||
refueler.allows_all_trains = bit_extract(bits, 2) > 0
|
||||
refueler.priority = 0
|
||||
refueler.allows_all_trains = bit_extract(bits, SETTING_DISABLE_ALLOW_LIST) > 0
|
||||
refueler.priority = mod_settings.priority
|
||||
|
||||
if refueler.network_name == NETWORK_EACH then
|
||||
local is_each = refueler.network_name == NETWORK_EACH
|
||||
if is_each then
|
||||
map_data.each_refuelers[id] = true
|
||||
refueler.network_flag = {}
|
||||
else
|
||||
@@ -339,8 +441,10 @@ function set_refueler_from_comb(map_data, mod_settings, id)
|
||||
if item_type == "virtual" then
|
||||
if item_name == SIGNAL_PRIORITY then
|
||||
refueler.priority = item_count
|
||||
elseif refueler.network_name == NETWORK_EACH then
|
||||
refueler.network_flag[item_name] = item_count
|
||||
elseif is_each then
|
||||
if item_name ~= REQUEST_THRESHOLD and item_name ~= LOCKED_SLOTS then
|
||||
refueler.network_flag[item_name] = item_count
|
||||
end
|
||||
end
|
||||
end
|
||||
if item_name == refueler.network_name then
|
||||
@@ -352,7 +456,7 @@ function set_refueler_from_comb(map_data, mod_settings, id)
|
||||
|
||||
local f, a
|
||||
if old_network == NETWORK_EACH then
|
||||
f, a = pairs(refueler.network_flag--[[@as {[string]: int}]])
|
||||
f, a = pairs(old_network_flag--[[@as {[string]: int}]])
|
||||
elseif old_network ~= refueler.network_name then
|
||||
f, a = once, old_network
|
||||
else
|
||||
@@ -406,24 +510,6 @@ function update_display(map_data, station)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---@param station Station
|
||||
function set_station_from_comb_state(station)
|
||||
--NOTE: this does nothing to update currently active deliveries
|
||||
local params = get_comb_params(station.entity_comb1)
|
||||
local signal = params.first_signal
|
||||
|
||||
local bits = params.second_constant or 0
|
||||
local is_pr_state = bit_extract(bits, 0, 2)
|
||||
local allows_all_trains = bit_extract(bits, 2) > 0
|
||||
local is_stack = bit_extract(bits, 3) > 0
|
||||
|
||||
station.network_name = signal and signal.name or nil
|
||||
station.allows_all_trains = allows_all_trains
|
||||
station.is_stack = is_stack
|
||||
station.is_p = (is_pr_state == 0 or is_pr_state == 1) or nil
|
||||
station.is_r = (is_pr_state == 0 or is_pr_state == 2) or nil
|
||||
end
|
||||
---@param comb LuaEntity
|
||||
function get_comb_gui_settings(comb)
|
||||
local params = get_comb_params(comb)
|
||||
@@ -433,8 +519,6 @@ function get_comb_gui_settings(comb)
|
||||
local switch_state = "none"
|
||||
local bits = params.second_constant or 0
|
||||
local is_pr_state = bit_extract(bits, 0, 2)
|
||||
local allows_all_trains = bit_extract(bits, 2) > 0
|
||||
local is_stack = bit_extract(bits, 3) > 0
|
||||
if is_pr_state == 0 then
|
||||
switch_state = "none"
|
||||
elseif is_pr_state == 1 then
|
||||
@@ -454,7 +538,7 @@ function get_comb_gui_settings(comb)
|
||||
elseif op == MODE_WAGON then
|
||||
selected_index = 5
|
||||
end
|
||||
return selected_index, params.first_signal, switch_state, not allows_all_trains, is_stack
|
||||
return selected_index, params.first_signal, switch_state, bits
|
||||
end
|
||||
---@param comb LuaEntity
|
||||
---@param is_pr_state 0|1|2
|
||||
@@ -467,23 +551,14 @@ function set_comb_is_pr_state(comb, is_pr_state)
|
||||
control.parameters = param
|
||||
end
|
||||
---@param comb LuaEntity
|
||||
---@param allows_all_trains boolean
|
||||
function set_comb_allows_all_trains(comb, allows_all_trains)
|
||||
---@param n int
|
||||
---@param bit boolean
|
||||
function set_comb_setting(comb, n, bit)
|
||||
local control = get_comb_control(comb)
|
||||
local param = control.parameters
|
||||
local bits = param.second_constant or 0
|
||||
|
||||
param.second_constant = bit_replace(bits, allows_all_trains and 1 or 0, 2)
|
||||
control.parameters = param
|
||||
end
|
||||
---@param comb LuaEntity
|
||||
---@param is_stack boolean
|
||||
function set_comb_is_stack(comb, is_stack)
|
||||
local control = get_comb_control(comb)
|
||||
local param = control.parameters
|
||||
local bits = param.second_constant or 0
|
||||
|
||||
param.second_constant = bit_replace(bits, is_stack and 1 or 0, 3)
|
||||
param.second_constant = bit_replace(bits, bit and 1 or 0, n)
|
||||
control.parameters = param
|
||||
end
|
||||
---@param comb LuaEntity
|
||||
@@ -540,22 +615,25 @@ end
|
||||
---@param map_data MapData
|
||||
---@param station Station
|
||||
function set_comb2(map_data, station)
|
||||
local sign = mod_settings.invert_sign and -1 or 1
|
||||
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}
|
||||
signals[i] = {index = i, signal = {type = is_fluid and "fluid" or "item", name = item_name}, count = sign*count}
|
||||
end
|
||||
set_combinator_output(map_data, station.entity_comb2, signals)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--[[alerts]]--
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
---@param train LuaTrain
|
||||
---@param icon {}
|
||||
---@param message string
|
||||
@@ -694,7 +772,14 @@ function process_active_alerts(map_data)
|
||||
if id == 1 then
|
||||
send_alert_for_train(train, send_stuck_train_alert_icon, "cybersyn-messages.stuck-train")
|
||||
elseif id == 2 then
|
||||
send_alert_for_train(train, send_nonempty_train_in_depot_alert_icon, "cybersyn-messages.nonempty-train")
|
||||
--this is an alert that we have to actively check if we can clear
|
||||
local is_train_empty = next(train.get_contents()) == nil and next(train.get_fluid_contents()) == nil
|
||||
if is_train_empty then
|
||||
--NOTE: this function could get confused being called internally, be sure it can handle that
|
||||
on_train_changed({train = train})
|
||||
else
|
||||
send_alert_for_train(train, send_nonempty_train_in_depot_alert_icon, "cybersyn-messages.nonempty-train")
|
||||
end
|
||||
elseif id == 3 then
|
||||
send_alert_for_train(train, send_lost_train_alert_icon, "cybersyn-messages.depot-broken")
|
||||
elseif id == 4 then
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
---@field public stations {[uint]: Station}
|
||||
---@field public active_station_ids uint[]
|
||||
---@field public warmup_station_ids uint[]
|
||||
---@field public queue_station_update {[uint]: true?}?
|
||||
---@field public depots {[uint]: Depot}
|
||||
---@field public refuelers {[uint]: Refueler}
|
||||
---@field public trains {[uint]: Train}
|
||||
@@ -29,6 +30,7 @@
|
||||
---@field public is_p true?
|
||||
---@field public is_r true?
|
||||
---@field public is_stack true?
|
||||
---@field public enable_inactive true?
|
||||
---@field public allows_all_trains true?
|
||||
---@field public deliveries_total int
|
||||
---@field public last_delivery_tick int
|
||||
@@ -50,7 +52,7 @@
|
||||
---@class Depot
|
||||
---@field public entity_stop LuaEntity
|
||||
---@field public entity_comb LuaEntity
|
||||
---@field public available_train_id uint?--train_id
|
||||
---@field public available_train_id uint?--train_id, only present when a train is parked here
|
||||
|
||||
---@class Refueler
|
||||
---@field public entity_stop LuaEntity
|
||||
@@ -76,13 +78,13 @@
|
||||
---@field public last_manifest_tick int
|
||||
---@field public has_filtered_wagon true?
|
||||
---@field public is_available true?
|
||||
---@field public parked_at_depot_id uint?
|
||||
---@field public depot_name string
|
||||
---@field public depot_id uint
|
||||
---@field public use_any_depot true?
|
||||
---@field public disable_bypass true?
|
||||
---@field public network_name string? --can only be nil when the train is parked at a depot
|
||||
---@field public network_flag int
|
||||
---@field public priority int
|
||||
---@field public refueler_id uint?
|
||||
---@field public se_depot_surface_i uint --se only
|
||||
---@field public se_is_being_teleported true? --se only
|
||||
---@field public se_awaiting_removal any? --se only
|
||||
---@field public se_awaiting_rename any? --se only
|
||||
@@ -105,17 +107,21 @@
|
||||
---@field public tps double
|
||||
---@field public update_rate int
|
||||
---@field public r_threshold int
|
||||
---@field public priority int
|
||||
---@field public locked_slots int
|
||||
---@field public network_flag int
|
||||
---@field public warmup_time double
|
||||
---@field public stuck_train_time double
|
||||
---@field public fuel_threshold double
|
||||
---@field public depot_bypass_enabled boolean
|
||||
---@field public invert_sign boolean
|
||||
---@field public allow_cargo_in_depot boolean
|
||||
---@field public missing_train_alert_enabled boolean --interface setting
|
||||
---@field public stuck_train_alert_enabled boolean --interface setting
|
||||
---@field public react_to_nonempty_train_in_depot boolean --interface setting
|
||||
---@field public react_to_train_at_incorrect_station boolean --interface setting
|
||||
---@field public react_to_train_early_to_depot boolean --interface setting
|
||||
|
||||
--if this is uncommented it means there are migrations to write
|
||||
|
||||
---@alias cybersyn.global MapData
|
||||
---@type CybersynModSettings
|
||||
mod_settings = {}
|
||||
@@ -150,9 +156,3 @@ function init_global()
|
||||
|
||||
IS_SE_PRESENT = remote.interfaces["space-exploration"] ~= nil
|
||||
end
|
||||
|
||||
---@param v string
|
||||
---@param h string?
|
||||
function once(v, h)
|
||||
return not h and v or nil--[[@as string|nil]]
|
||||
end
|
||||
|
||||
@@ -26,25 +26,37 @@ STATUS_NAMES[defines.entity_status.disabled_by_script] = "entity-status.disabled
|
||||
STATUS_NAMES[defines.entity_status.marked_for_deconstruction] = "entity-status.marked-for-deconstruction"
|
||||
STATUS_NAMES_DEFAULT = "entity-status.disabled"
|
||||
|
||||
|
||||
local bit_extract = bit32.extract
|
||||
local function setting(bits, n)
|
||||
return bit_extract(bits, n) > 0
|
||||
end
|
||||
local function setting_flip(bits, n)
|
||||
return bit_extract(bits, n) == 0
|
||||
end
|
||||
|
||||
|
||||
---@param main_window LuaGuiElement
|
||||
---@param selected_index int
|
||||
local function set_visibility(main_window, selected_index)
|
||||
local uses_network = selected_index == 1 or selected_index == 2 or selected_index == 3
|
||||
local uses_allow_list = selected_index == 1 or selected_index == 3
|
||||
local is_station = selected_index == 1
|
||||
local is_depot = selected_index == 2
|
||||
local uses_network = is_station or is_depot or selected_index == 3
|
||||
local uses_allow_list = is_station or selected_index == 3
|
||||
|
||||
local vflow = main_window.frame.vflow--[[@as LuaGuiElement]]
|
||||
local top_flow = vflow.top--[[@as LuaGuiElement]]
|
||||
local bottom_flow = vflow.bottom--[[@as LuaGuiElement]]
|
||||
local right_flow = bottom_flow.right--[[@as LuaGuiElement]]
|
||||
local first_settings = bottom_flow.first--[[@as LuaGuiElement]]
|
||||
local depot_settings = bottom_flow.depot--[[@as LuaGuiElement]]
|
||||
|
||||
top_flow.is_pr_switch.visible = is_station
|
||||
vflow.network_label.visible = uses_network
|
||||
bottom_flow.network.visible = uses_network
|
||||
right_flow.allow_list.visible = uses_allow_list
|
||||
--right_flow.allow_list_label.visible = uses_allow_list
|
||||
right_flow.is_stack.visible = is_station
|
||||
--right_flow.is_stack_label.visible = is_station
|
||||
first_settings.allow_list.visible = uses_allow_list
|
||||
first_settings.is_stack.visible = is_station
|
||||
bottom_flow.enable_inactive.visible = is_station
|
||||
depot_settings.visible = is_depot
|
||||
end
|
||||
|
||||
---@param comb LuaEntity
|
||||
@@ -53,7 +65,7 @@ function gui_opened(comb, player)
|
||||
combinator_update(global, comb, true)
|
||||
|
||||
local rootgui = player.gui.screen
|
||||
local selected_index, signal, switch_state, allow_list, is_stack = get_comb_gui_settings(comb)
|
||||
local selected_index, signal, switch_state, bits = get_comb_gui_settings(comb)
|
||||
|
||||
local window = flib_gui.build(rootgui, {
|
||||
{type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, children={
|
||||
@@ -69,8 +81,8 @@ function gui_opened(comb, player)
|
||||
{type="flow", name="vflow", 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="sprite", sprite=STATUS_SPRITES[comb.status] or STATUS_SPRITES_DEFAULT, style="status_image", style_mods={stretch_image_to_widget_size=true}},
|
||||
{type="label", caption={STATUS_NAMES[comb.status] or STATUS_NAMES_DEFAULT}}
|
||||
}},
|
||||
--preview
|
||||
{type="frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={
|
||||
@@ -94,25 +106,45 @@ function gui_opened(comb, player)
|
||||
}},
|
||||
---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=signal, style_mods={bottom_margin=1, right_margin=6, top_margin=2}, actions={
|
||||
{type="label", name="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="top"}, children={
|
||||
{type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", elem_type="signal", tooltip={"cybersyn-gui.network-tooltip"}, signal=signal, style_mods={bottom_margin=1, right_margin=6, top_margin=2}, actions={
|
||||
on_elem_changed={"choose-elem-button", comb.unit_number}
|
||||
}},
|
||||
{type="flow", name="right", direction="vertical", style_mods={horizontal_align="left"}, children={
|
||||
{type="flow", name="allow_list", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="allow_list", ref={"allow_list"}, state=allow_list, tooltip={"cybersyn-gui.allow-list-tooltip"}, actions={
|
||||
on_checked_state_changed={"allow_list", comb.unit_number}
|
||||
{type="flow", name="depot", direction="vertical", style_mods={horizontal_align="left"}, children={
|
||||
{type="flow", name="use_any_depot", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="use_same_depot", state=setting_flip(bits, SETTING_USE_ANY_DEPOT), tooltip={"cybersyn-gui.use-same-depot-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting-flip", comb.unit_number, SETTING_USE_ANY_DEPOT}
|
||||
}},
|
||||
{type="label", name="allow_list_label", style_mods={left_padding=3}, ref={"allow_list_label"}, caption={"cybersyn-gui.allow-list-description"}},
|
||||
{type="label", name="use_same_depot_label", style_mods={left_padding=3}, caption={"cybersyn-gui.use-same-depot-description"}},
|
||||
}},
|
||||
{type="flow", name="depot_bypass", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="depot_bypass", state=setting_flip(bits, SETTING_DISABLE_DEPOT_BYPASS), tooltip={"cybersyn-gui.depot-bypass-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting-flip", comb.unit_number, SETTING_DISABLE_DEPOT_BYPASS}
|
||||
}},
|
||||
{type="label", name="depot_bypass_label", style_mods={left_padding=3}, caption={"cybersyn-gui.depot-bypass-description"}},
|
||||
}},
|
||||
}},
|
||||
{type="flow", name="first", direction="vertical", style_mods={horizontal_align="left", right_margin=8}, children={
|
||||
{type="flow", name="allow_list", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="allow_list", state=setting_flip(bits, SETTING_DISABLE_ALLOW_LIST), tooltip={"cybersyn-gui.allow-list-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting-flip", comb.unit_number, SETTING_DISABLE_ALLOW_LIST}
|
||||
}},
|
||||
{type="label", name="allow_list_label", style_mods={left_padding=3}, caption={"cybersyn-gui.allow-list-description"}},
|
||||
}},
|
||||
{type="flow", name="is_stack", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="is_stack", ref={"is_stack"}, state=is_stack, tooltip={"cybersyn-gui.is-stack-tooltip"}, actions={
|
||||
on_checked_state_changed={"is_stack", comb.unit_number}
|
||||
{type="checkbox", name="is_stack", state=setting(bits, SETTING_IS_STACK), tooltip={"cybersyn-gui.is-stack-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting", comb.unit_number, SETTING_IS_STACK}
|
||||
}},
|
||||
{type="label", name="is_stack_label", style_mods={left_padding=3}, ref={"is_stack_label"}, caption={"cybersyn-gui.is-stack-description"}},
|
||||
{type="label", name="is_stack_label", style_mods={left_padding=3}, caption={"cybersyn-gui.is-stack-description"}},
|
||||
}},
|
||||
}}
|
||||
}},
|
||||
{type="flow", name="enable_inactive", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="enable_inactive", state=setting(bits, SETTING_ENABLE_INACTIVE), tooltip={"cybersyn-gui.enable-inactive-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting", comb.unit_number, SETTING_ENABLE_INACTIVE}
|
||||
}},
|
||||
{type="label", name="enable_inactive_label", style_mods={left_padding=3}, caption={"cybersyn-gui.enable-inactive-description"}},
|
||||
}},
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
@@ -197,38 +229,30 @@ 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
|
||||
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_EACH
|
||||
else
|
||||
signal = nil
|
||||
end
|
||||
signal.name = NETWORK_EACH
|
||||
element.elem_value = signal
|
||||
end
|
||||
set_comb_network_name(comb, signal)
|
||||
|
||||
combinator_update(global, comb)
|
||||
elseif msg[1] == "allow_list" then
|
||||
elseif msg[1] == "setting" 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 allows_all_trains = not element.state
|
||||
set_comb_allows_all_trains(comb, allows_all_trains)
|
||||
set_comb_setting(comb, msg[3], element.state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
elseif msg[1] == "is_stack" then
|
||||
elseif msg[1] == "setting-flip" 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_stack = element.state
|
||||
set_comb_is_stack(comb, is_stack)
|
||||
set_comb_setting(comb, msg[3], not element.state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
elseif msg[1] == "is_pr_switch" then
|
||||
|
||||
@@ -3,37 +3,10 @@ local area = require("__flib__.area")
|
||||
local abs = math.abs
|
||||
local floor = math.floor
|
||||
local ceil = math.ceil
|
||||
local min = math.min
|
||||
local max = math.max
|
||||
|
||||
|
||||
local function table_compare(t0, t1)
|
||||
if #t0 ~= #t1 then
|
||||
return false
|
||||
end
|
||||
for i = 0, #t0 do
|
||||
if t0[i] ~= t1[i] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
---@param a any[]
|
||||
---@param i uint
|
||||
local function iterr(a, i)
|
||||
i = i + 1
|
||||
if i <= #a then
|
||||
local r = a[#a - i + 1]
|
||||
return i, r
|
||||
else
|
||||
return nil, nil
|
||||
end
|
||||
end
|
||||
|
||||
---@param a any[]
|
||||
local function irpairs(a)
|
||||
return iterr, a, 0
|
||||
end
|
||||
|
||||
---@param layout_pattern (0|1|2|3)[]
|
||||
---@param layout (0|1|2)[]
|
||||
function is_refuel_layout_accepted(layout_pattern, layout)
|
||||
@@ -81,11 +54,6 @@ end
|
||||
---@param train_id uint
|
||||
---@param train Train
|
||||
function remove_train(map_data, train_id, train)
|
||||
local parked_at_depot_id = train.parked_at_depot_id
|
||||
if parked_at_depot_id then
|
||||
local depot = map_data.depots[parked_at_depot_id]
|
||||
depot.available_train_id = nil
|
||||
end
|
||||
remove_available_train(map_data, train_id, train)
|
||||
|
||||
local layout_id = train.layout_id
|
||||
@@ -191,9 +159,31 @@ function set_p_wagon_combs(map_data, station, train)
|
||||
if not station.wagon_combs or not next(station.wagon_combs) then return end
|
||||
local carriages = train.entity.carriages
|
||||
local manifest = train.manifest--[[@as Manifest]]
|
||||
if not manifest[1] then return end
|
||||
local sign = mod_settings.invert_sign and 1 or -1
|
||||
|
||||
local is_reversed = get_train_direction(station.entity_stop, train.entity)
|
||||
|
||||
local locked_slots = station.locked_slots
|
||||
local percent_slots_to_use_per_wagon = 1.0
|
||||
if train.item_slot_capacity > 0 then
|
||||
local total_item_slots
|
||||
if locked_slots > 0 then
|
||||
local total_cargo_wagons = #train.entity.cargo_wagons
|
||||
total_item_slots = max(train.item_slot_capacity - total_cargo_wagons*locked_slots, 1)
|
||||
else
|
||||
total_item_slots = train.item_slot_capacity
|
||||
end
|
||||
|
||||
local to_be_used_item_slots = 0
|
||||
for i, item in ipairs(train.manifest) do
|
||||
if item.type == "item" then
|
||||
to_be_used_item_slots = to_be_used_item_slots + ceil(item.count/get_stack_size(map_data, item.name))
|
||||
end
|
||||
end
|
||||
percent_slots_to_use_per_wagon = min(to_be_used_item_slots/total_item_slots, 1.0)
|
||||
end
|
||||
|
||||
local item_i = 1
|
||||
local item = manifest[item_i]
|
||||
local item_count = item.count
|
||||
@@ -215,39 +205,29 @@ function set_p_wagon_combs(map_data, station, train)
|
||||
end
|
||||
end
|
||||
if carriage.type == "cargo-wagon" and item_i <= #manifest then
|
||||
local signals = {}
|
||||
|
||||
local inv = carriage.get_inventory(defines.inventory.cargo_wagon)
|
||||
if inv then
|
||||
local signals = {}
|
||||
|
||||
local inv_filter_i = 1
|
||||
local item_slots_capacity = #inv - station.locked_slots
|
||||
local item_slots_capacity = max(ceil((#inv - locked_slots)*percent_slots_to_use_per_wagon), 1)
|
||||
while item_slots_capacity > 0 do
|
||||
local do_inc = false
|
||||
local do_inc
|
||||
if item.type == "item" then
|
||||
local stack_size = get_stack_size(map_data, item.name)
|
||||
local item_slots = ceil(item_count/stack_size)
|
||||
local i = #signals + 1
|
||||
local slots_to_filter
|
||||
if item_slots > item_slots_capacity then
|
||||
if comb then
|
||||
signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = item_slots_capacity*stack_size}
|
||||
end
|
||||
item_slots_capacity = 0
|
||||
item_count = item_count - item_slots_capacity*stack_size
|
||||
slots_to_filter = item_slots_capacity
|
||||
else
|
||||
if comb then
|
||||
signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = item_count}
|
||||
end
|
||||
item_slots_capacity = item_slots_capacity - item_slots
|
||||
do_inc = true
|
||||
slots_to_filter = item_slots
|
||||
end
|
||||
for j = 1, slots_to_filter do
|
||||
local count_to_fill = min(item_slots_capacity*stack_size, item_count)
|
||||
local slots_to_fill = ceil(count_to_fill/stack_size)
|
||||
|
||||
signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = sign*count_to_fill}
|
||||
item_count = item_count - count_to_fill
|
||||
item_slots_capacity = item_slots_capacity - slots_to_fill
|
||||
for j = 1, slots_to_fill do
|
||||
inv.set_filter(inv_filter_i, item.name)
|
||||
inv_filter_i = inv_filter_i + 1
|
||||
end
|
||||
train.has_filtered_wagon = true
|
||||
do_inc = item_count == 0
|
||||
else
|
||||
do_inc = true
|
||||
end
|
||||
@@ -271,27 +251,18 @@ function set_p_wagon_combs(map_data, station, train)
|
||||
local signals = {}
|
||||
|
||||
while fluid_capacity > 0 do
|
||||
local do_inc = false
|
||||
local do_inc
|
||||
if fluid.type == "fluid" then
|
||||
if fluid_count > fluid_capacity then
|
||||
if comb then
|
||||
signals[1] = {index = 1, signal = {type = fluid.type, name = fluid.name}, count = fluid_capacity}
|
||||
end
|
||||
fluid_capacity = 0
|
||||
fluid_count = fluid_count - fluid_capacity
|
||||
else
|
||||
if comb then
|
||||
signals[1] = {index = 1, signal = {type = fluid.type, name = fluid.name}, count = item_count}
|
||||
end
|
||||
fluid_capacity = fluid_capacity - fluid_count
|
||||
fluid_i = fluid_i + 1
|
||||
if fluid_i <= #manifest then
|
||||
fluid = manifest[fluid_i]
|
||||
fluid_count = fluid.count
|
||||
end
|
||||
end
|
||||
break
|
||||
local count_to_fill = min(fluid_count, fluid_capacity)
|
||||
|
||||
signals[1] = {index = 1, signal = {type = fluid.type, name = fluid.name}, count = sign*count_to_fill}
|
||||
fluid_count = fluid_count - count_to_fill
|
||||
fluid_capacity = 0
|
||||
do_inc = fluid_count == 0
|
||||
else
|
||||
do_inc = true
|
||||
end
|
||||
if do_inc then
|
||||
fluid_i = fluid_i + 1
|
||||
if fluid_i <= #manifest then
|
||||
fluid = manifest[fluid_i]
|
||||
@@ -315,6 +286,7 @@ function set_r_wagon_combs(map_data, station, train)
|
||||
local carriages = train.entity.carriages
|
||||
|
||||
local is_reversed = get_train_direction(station.entity_stop, train.entity)
|
||||
local sign = mod_settings.invert_sign and -1 or 1
|
||||
|
||||
local ivpairs = is_reversed and irpairs or ipairs
|
||||
for carriage_i, carriage in ivpairs(carriages) do
|
||||
@@ -336,7 +308,7 @@ function set_r_wagon_combs(map_data, station, train)
|
||||
local stack = inv[stack_i]
|
||||
if stack.valid_for_read then
|
||||
local i = #signals + 1
|
||||
signals[i] = {index = i, signal = {type = "item", name = stack.name}, count = -stack.count}
|
||||
signals[i] = {index = i, signal = {type = "item", name = stack.name}, count = sign*stack.count}
|
||||
end
|
||||
end
|
||||
set_combinator_output(map_data, comb, signals)
|
||||
@@ -347,7 +319,7 @@ function set_r_wagon_combs(map_data, station, train)
|
||||
local inv = carriage.get_fluid_contents()
|
||||
for fluid_name, count in pairs(inv) do
|
||||
local i = #signals + 1
|
||||
signals[i] = {index = i, signal = {type = "fluid", name = fluid_name}, count = -floor(count)}
|
||||
signals[i] = {index = i, signal = {type = "fluid", name = fluid_name}, count = sign*floor(count)}
|
||||
end
|
||||
set_combinator_output(map_data, comb, signals)
|
||||
end
|
||||
|
||||
51
cybersyn/scripts/lib.lua
Normal file
51
cybersyn/scripts/lib.lua
Normal file
@@ -0,0 +1,51 @@
|
||||
--By Mami
|
||||
---@param v string
|
||||
---@param h string?
|
||||
function once(v, h)
|
||||
return not h and v or nil--[[@as string|nil]]
|
||||
end
|
||||
---@param t any[]
|
||||
---@return any
|
||||
function rnext_consume(t)
|
||||
local len = #t
|
||||
if len > 1 then
|
||||
local i = math.random(1, len)
|
||||
local v = t[i]
|
||||
t[i] = t[len]
|
||||
t[len] = nil
|
||||
return v
|
||||
else
|
||||
local v = t[1]
|
||||
t[1] = nil
|
||||
return v
|
||||
end
|
||||
end
|
||||
|
||||
function table_compare(t0, t1)
|
||||
if #t0 ~= #t1 then
|
||||
return false
|
||||
end
|
||||
for i = 0, #t0 do
|
||||
if t0[i] ~= t1[i] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
---@param a any[]
|
||||
---@param i uint
|
||||
function irnext(a, i)
|
||||
i = i + 1
|
||||
if i <= #a then
|
||||
local r = a[#a - i + 1]
|
||||
return i, r
|
||||
else
|
||||
return nil, nil
|
||||
end
|
||||
end
|
||||
|
||||
---@param a any[]
|
||||
function irpairs(a)
|
||||
return irnext, a, 0
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
function log_dispatch(network_name, r_stop, p_stop)
|
||||
end
|
||||
|
||||
function log_refuel(network_name, refuel_stop)
|
||||
end
|
||||
@@ -1,5 +1,4 @@
|
||||
--By Mami
|
||||
local floor = math.floor
|
||||
local ceil = math.ceil
|
||||
local table_insert = table.insert
|
||||
|
||||
@@ -23,12 +22,24 @@ end
|
||||
---@param depot_id uint
|
||||
---@param depot Depot
|
||||
local function on_depot_broken(map_data, depot_id, depot)
|
||||
local train_id = depot.available_train_id
|
||||
if train_id then
|
||||
local train = map_data.trains[train_id]
|
||||
lock_train(train.entity)
|
||||
send_alert_depot_of_train_broken(map_data, train.entity)
|
||||
remove_train(map_data, train_id, train)
|
||||
for train_id, train in pairs(map_data.trains) do
|
||||
if train.depot_id == depot_id then
|
||||
if train.use_any_depot then
|
||||
local e = get_any_train_entity(train.entity)
|
||||
local stops = e.force.get_train_stops({name = depot.entity_stop.backer_name, surface = e.surface})
|
||||
for stop in rnext_consume, stops do
|
||||
local new_depot_id = stop.unit_number
|
||||
if map_data.depots[new_depot_id] then
|
||||
train.depot_id = new_depot_id--[[@as uint]]
|
||||
goto continue
|
||||
end
|
||||
end
|
||||
end
|
||||
lock_train(train.entity)
|
||||
send_alert_depot_of_train_broken(map_data, train.entity)
|
||||
remove_train(map_data, train_id, train)
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
map_data.depots[depot_id] = nil
|
||||
interface_raise_depot_removed(depot_id, depot)
|
||||
@@ -105,17 +116,17 @@ local function on_station_built(map_data, stop, comb1, comb2)
|
||||
entity_stop = stop,
|
||||
entity_comb1 = comb1,
|
||||
entity_comb2 = comb2,
|
||||
--is_p = set_station_from_comb_state,
|
||||
--is_r = set_station_from_comb_state,
|
||||
--allows_all_trains = set_station_from_comb_state,
|
||||
--is_p = set_station_from_comb,
|
||||
--is_r = set_station_from_comb,
|
||||
--allows_all_trains = set_station_from_comb,
|
||||
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,
|
||||
network_flag = 0,
|
||||
--network_name = set_station_from_comb,
|
||||
--network_flag = set_station_from_comb,
|
||||
wagon_combs = nil,
|
||||
deliveries = {},
|
||||
accepted_layouts = {},
|
||||
@@ -125,7 +136,6 @@ local function on_station_built(map_data, stop, comb1, comb2)
|
||||
item_thresholds = nil,
|
||||
display_state = 0,
|
||||
}
|
||||
set_station_from_comb_state(station)
|
||||
local id = stop.unit_number--[[@as uint]]
|
||||
map_data.stations[id] = station
|
||||
map_data.warmup_station_ids[#map_data.warmup_station_ids + 1] = id
|
||||
@@ -350,8 +360,8 @@ function combinator_update(map_data, comb, reset_display)
|
||||
local params = control.parameters
|
||||
local old_params = map_data.to_comb_params[unit_number]
|
||||
local has_changed = false
|
||||
local station
|
||||
local id
|
||||
local station = nil
|
||||
local id = nil
|
||||
|
||||
|
||||
if params.operation == MODE_PRIMARY_IO_ACTIVE or params.operation == MODE_PRIMARY_IO_FAILED_REQUEST or params.operation == MODE_PRIMARY_IO then
|
||||
@@ -361,7 +371,10 @@ function combinator_update(map_data, comb, reset_display)
|
||||
if stop then
|
||||
id = stop.unit_number--[[@as uint]]
|
||||
station = map_data.stations[id]
|
||||
if should_reset and station and station.entity_comb1 == comb then
|
||||
if station.entity_comb1 ~= comb then
|
||||
station = nil
|
||||
end
|
||||
if should_reset and station then
|
||||
--make sure only MODE_PRIMARY_IO gets stored on map_data.to_comb_params
|
||||
if station.display_state == 0 then
|
||||
params.operation = MODE_PRIMARY_IO
|
||||
@@ -396,12 +409,12 @@ function combinator_update(map_data, comb, reset_display)
|
||||
|
||||
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
|
||||
--NOTE: these updates have to be queued to occur at tick init since central planning is expecting them not to change between ticks
|
||||
if not map_data.queue_station_update then
|
||||
map_data.queue_station_update = {}
|
||||
end
|
||||
map_data.queue_station_update[id] = true
|
||||
else
|
||||
local depot = map_data.depots[id]
|
||||
if depot then
|
||||
@@ -426,11 +439,11 @@ function combinator_update(map_data, comb, reset_display)
|
||||
if params.second_constant ~= old_params.second_constant then
|
||||
has_changed = true
|
||||
if station then
|
||||
local pre = station.allows_all_trains
|
||||
set_station_from_comb_state(station)
|
||||
if station.allows_all_trains ~= pre then
|
||||
update_stop_if_auto(map_data, station, true)
|
||||
--NOTE: these updates have to be queued to occur at tick init since central planning is expecting them not to change between ticks
|
||||
if not map_data.queue_station_update then
|
||||
map_data.queue_station_update = {}
|
||||
end
|
||||
map_data.queue_station_update[id] = true
|
||||
else
|
||||
local refueler = map_data.refuelers[id]
|
||||
if refueler then
|
||||
@@ -553,13 +566,6 @@ local function on_stop_rename(map_data, stop, old_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local depot = map_data.depots[station_id]
|
||||
if depot and depot.available_train_id then
|
||||
local train = map_data.trains[depot.available_train_id--[[@as uint]]]
|
||||
train.depot_name = stop.backer_name
|
||||
--train.se_depot_surface_i = stop.surface.index
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -653,28 +659,28 @@ local function on_rename(event)
|
||||
end
|
||||
|
||||
|
||||
local function on_settings_changed(event)
|
||||
mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value --[[@as double]]
|
||||
mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]]
|
||||
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
|
||||
mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]]
|
||||
mod_settings.fuel_threshold = settings.global["cybersyn-fuel-threshold"].value--[[@as double]]
|
||||
mod_settings.depot_bypass_enabled = settings.global["cybersyn-depot-bypass-enabled"].value--[[@as boolean]]
|
||||
mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]]
|
||||
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
|
||||
if event.setting == "cybersyn-ticks-per-second" then
|
||||
if mod_settings.tps > DELTA then
|
||||
local nth_tick = ceil(60/mod_settings.tps)--[[@as uint]];
|
||||
script.on_nth_tick(nth_tick, function()
|
||||
tick(global, mod_settings)
|
||||
end)
|
||||
else
|
||||
script.on_nth_tick(nil)
|
||||
---@param schedule TrainSchedule
|
||||
---@param stop LuaEntity
|
||||
---@param old_surface_index uint
|
||||
local function se_add_direct_to_station_order(schedule, stop, old_surface_index)
|
||||
local surface_i = stop.surface.index
|
||||
if surface_i ~= old_surface_index then
|
||||
local name = stop.backer_name
|
||||
local records = schedule.records
|
||||
for i = schedule.current, #records do
|
||||
if records[i].station == name then
|
||||
if i == 1 then
|
||||
--we are assuming this is the depot order
|
||||
records[#records + 1] = create_direct_to_station_order(stop)
|
||||
schedule.current = #records--[[@as uint]]
|
||||
else
|
||||
table_insert(records, i, create_direct_to_station_order(stop))
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
interface_raise_on_mod_settings_changed(event)
|
||||
end
|
||||
|
||||
local function setup_se_compat()
|
||||
IS_SE_PRESENT = remote.interfaces["space-exploration"] ~= nil
|
||||
if not IS_SE_PRESENT then return end
|
||||
@@ -687,9 +693,6 @@ local function setup_se_compat()
|
||||
---@type MapData
|
||||
local map_data = global
|
||||
local old_id = event.old_train_id_1
|
||||
--NOTE: this is not guaranteed to be unique, it should be fine since the window of time for another train to mistakenly steal this train's event data is miniscule
|
||||
--NOTE: please SE dev if you read this fix the issue where se_on_train_teleport_finished_event is returning the wrong old train id
|
||||
local train_unique_identifier = event.train.front_stock.backer_name
|
||||
|
||||
local train = map_data.trains[old_id]
|
||||
if not train then return end
|
||||
@@ -706,19 +709,27 @@ local function setup_se_compat()
|
||||
---@type uint
|
||||
local new_id = train_entity.id
|
||||
local old_surface_index = event.old_surface_index
|
||||
local train_unique_identifier = event.train.front_stock.backer_name
|
||||
|
||||
--NOTE: event.old_train_id_1 from this event is useless, it's for one of the many transient trains SE spawns while teleporting the old train, only se_on_train_teleport_started_event returns the correct old train id
|
||||
--NOTE: please SE dev if you read this fix the issue where se_on_train_teleport_finished_event is returning the wrong old train id
|
||||
local old_id = event.old_train_id_1
|
||||
local train = map_data.trains[old_id]
|
||||
if not train then return end
|
||||
|
||||
if train.is_available then
|
||||
local network = map_data.available_trains[train.network_name--[[@as string]]]
|
||||
if network then
|
||||
network[new_id] = true
|
||||
network[old_id] = nil
|
||||
local f, a
|
||||
if train.network_name == NETWORK_EACH then
|
||||
f, a = next, train.network_flag
|
||||
else
|
||||
f, a = once, train.network_name
|
||||
end
|
||||
for network_name in f, a do
|
||||
local network = map_data.available_trains[network_name]
|
||||
if network then
|
||||
network[new_id] = true
|
||||
network[old_id] = nil
|
||||
if next(network) == nil then
|
||||
map_data.available_trains[network_name] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -737,51 +748,60 @@ local function setup_se_compat()
|
||||
train.se_awaiting_rename = nil
|
||||
end
|
||||
|
||||
if not (train.status == STATUS_TO_P or train.status == STATUS_TO_R) then return end
|
||||
|
||||
local schedule = train_entity.schedule
|
||||
if schedule then
|
||||
if train.status == STATUS_TO_P or train.status == STATUS_TO_R then
|
||||
local p_station = map_data.stations[train.p_station_id]
|
||||
local p_name = p_station.entity_stop.backer_name
|
||||
local p_surface_i = p_station.entity_stop.surface.index
|
||||
local r_station = map_data.stations[train.r_station_id]
|
||||
local r_name = r_station.entity_stop.backer_name
|
||||
local r_surface_i = r_station.entity_stop.surface.index
|
||||
local records = schedule.records
|
||||
local i = schedule.current
|
||||
while i <= #records do
|
||||
if records[i].station == p_name and p_surface_i ~= old_surface_index then
|
||||
table_insert(records, i, create_direct_to_station_order(p_station.entity_stop))
|
||||
i = i + 1
|
||||
elseif records[i].station == r_name and r_surface_i ~= old_surface_index then
|
||||
table_insert(records, i, create_direct_to_station_order(r_station.entity_stop))
|
||||
i = i + 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
train_entity.schedule = schedule
|
||||
elseif train.status == STATUS_TO_F then
|
||||
local refueler = map_data.refuelers[train.refueler_id]
|
||||
local f_name = refueler.entity_stop.backer_name
|
||||
local f_surface_i = refueler.entity_stop.surface.index
|
||||
local records = schedule.records
|
||||
local i = schedule.current
|
||||
while i <= #records do
|
||||
if records[i].station == f_name and f_surface_i ~= old_surface_index then
|
||||
table_insert(records, i, create_direct_to_station_order(refueler.entity_stop))
|
||||
i = i + 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
train_entity.schedule = schedule
|
||||
if train.status == STATUS_TO_P then
|
||||
local stop = map_data.stations[train.p_station_id].entity_stop
|
||||
se_add_direct_to_station_order(schedule, stop, old_surface_index)
|
||||
end
|
||||
if train.status == STATUS_TO_P or train.status == STATUS_TO_R then
|
||||
local stop = map_data.stations[train.r_station_id].entity_stop
|
||||
se_add_direct_to_station_order(schedule, stop, old_surface_index)
|
||||
end
|
||||
if train.status == STATUS_TO_F then
|
||||
local stop = map_data.refuelers[train.refueler_id].entity_stop
|
||||
se_add_direct_to_station_order(schedule, stop, old_surface_index)
|
||||
end
|
||||
if not train.use_any_depot then
|
||||
local depot = map_data.depots[train.depot_id]
|
||||
se_add_direct_to_station_order(schedule, depot.entity_stop, old_surface_index)
|
||||
end
|
||||
train_entity.schedule = schedule
|
||||
end
|
||||
interface_raise_train_teleported(new_id, old_id)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
local function grab_all_settings()
|
||||
mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value --[[@as double]]
|
||||
mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]]
|
||||
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
|
||||
mod_settings.priority = settings.global["cybersyn-priority"].value--[[@as int]]
|
||||
mod_settings.locked_slots = settings.global["cybersyn-locked-slots"].value--[[@as int]]
|
||||
mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]]
|
||||
mod_settings.fuel_threshold = settings.global["cybersyn-fuel-threshold"].value--[[@as double]]
|
||||
mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]]
|
||||
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
|
||||
mod_settings.allow_cargo_in_depot = settings.global["cybersyn-allow-cargo-in-depot"].value--[[@as boolean]]
|
||||
mod_settings.invert_sign = settings.global["cybersyn-invert-sign"].value--[[@as boolean]]
|
||||
end
|
||||
local function on_settings_changed(event)
|
||||
grab_all_settings()
|
||||
if event.setting == "cybersyn-ticks-per-second" then
|
||||
if mod_settings.tps > DELTA then
|
||||
local nth_tick = ceil(60/mod_settings.tps)--[[@as uint]];
|
||||
script.on_nth_tick(nth_tick, function()
|
||||
tick(global, mod_settings)
|
||||
end)
|
||||
else
|
||||
script.on_nth_tick(nil)
|
||||
end
|
||||
end
|
||||
interface_raise_on_mod_settings_changed(event)
|
||||
end
|
||||
|
||||
|
||||
local filter_built = {
|
||||
{filter = "name", name = "train-stop"},
|
||||
{filter = "name", name = COMBINATOR_NAME},
|
||||
@@ -798,18 +818,10 @@ local filter_broken = {
|
||||
{filter = "rolling-stock"},
|
||||
}
|
||||
local function main()
|
||||
mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value --[[@as double]]
|
||||
mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]]
|
||||
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
|
||||
mod_settings.network_flag = settings.global["cybersyn-network-flag"].value--[[@as int]]
|
||||
mod_settings.fuel_threshold = settings.global["cybersyn-fuel-threshold"].value--[[@as double]]
|
||||
mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]]
|
||||
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
|
||||
mod_settings.depot_bypass_enabled = settings.global["cybersyn-depot-bypass-enabled"].value--[[@as boolean]]
|
||||
grab_all_settings()
|
||||
|
||||
mod_settings.missing_train_alert_enabled = true
|
||||
mod_settings.stuck_train_alert_enabled = true
|
||||
mod_settings.react_to_nonempty_train_in_depot = true
|
||||
mod_settings.react_to_train_at_incorrect_station = true
|
||||
mod_settings.react_to_train_early_to_depot = true
|
||||
|
||||
@@ -848,6 +860,10 @@ local function main()
|
||||
register_gui_actions()
|
||||
|
||||
script.on_init(function()
|
||||
local setting = settings.global["cybersyn-invert-sign"]
|
||||
setting.value = false
|
||||
settings.global["cybersyn-invert-sign"] = setting
|
||||
mod_settings.invert_sign = false
|
||||
init_global()
|
||||
setup_se_compat()
|
||||
end)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
--By Mami
|
||||
local flib_migration = require("__flib__.migration")
|
||||
|
||||
|
||||
@@ -103,23 +104,40 @@ local migrations_table = {
|
||||
map_data.each_refuelers = {}
|
||||
map_data.se_tele_old_id = nil
|
||||
|
||||
for k, comb in pairs(map_data.to_comb) do
|
||||
for id, comb in pairs(map_data.to_comb) do
|
||||
local control = get_comb_control(comb)
|
||||
local params = control.parameters
|
||||
local params_old = map_data.to_comb_params[id]
|
||||
local bits = params.second_constant or 0
|
||||
local bits_old = params_old.second_constant or 0
|
||||
|
||||
local allows_all_trains = bits%2
|
||||
local is_pr_state = math.floor(bits/2)%3
|
||||
local allows_all_trains_old = bits_old%2
|
||||
local is_pr_state_old = math.floor(bits_old/2)%3
|
||||
|
||||
local new_bits = bit32.bor(is_pr_state, allows_all_trains*4)
|
||||
params.second_constant = new_bits
|
||||
bits = bit32.bor(is_pr_state, allows_all_trains*4)
|
||||
bits_old = bit32.bor(is_pr_state_old, allows_all_trains_old*4)
|
||||
params.second_constant = bits
|
||||
params_old.second_constant = bits_old
|
||||
|
||||
control.parameters = params
|
||||
map_data.to_comb_params[id] = params_old
|
||||
end
|
||||
for id, station in pairs(map_data.stations) do
|
||||
station.display_state = (station.display_state >= 2 and 1 or 0) + (station.display_state%2)*2
|
||||
|
||||
set_station_from_comb_state(station)
|
||||
update_stop_if_auto(map_data, station, true)
|
||||
local params = get_comb_params(station.entity_comb1)
|
||||
|
||||
local bits = params.second_constant or 0
|
||||
local is_pr_state = bit32.extract(bits, 0, 2)
|
||||
local allows_all_trains = bit32.extract(bits, SETTING_DISABLE_ALLOW_LIST) > 0
|
||||
local is_stack = bit32.extract(bits, SETTING_IS_STACK) > 0
|
||||
|
||||
station.allows_all_trains = allows_all_trains
|
||||
station.is_stack = is_stack
|
||||
station.is_p = (is_pr_state == 0 or is_pr_state == 1) or nil
|
||||
station.is_r = (is_pr_state == 0 or is_pr_state == 2) or nil
|
||||
end
|
||||
|
||||
map_data.layout_train_count = {}
|
||||
@@ -135,6 +153,77 @@ local migrations_table = {
|
||||
end
|
||||
end
|
||||
end,
|
||||
["1.2.2"] = function()
|
||||
---@type MapData
|
||||
local map_data = global
|
||||
local setting = settings.global["cybersyn-invert-sign"]
|
||||
setting.value = true
|
||||
settings.global["cybersyn-invert-sign"] = setting
|
||||
|
||||
for id, comb in pairs(map_data.to_comb) do
|
||||
local control = get_comb_control(comb)
|
||||
local params = control.parameters
|
||||
local params_old = map_data.to_comb_params[id]
|
||||
local bits = params.second_constant or 0
|
||||
local bits_old = params_old.second_constant or 0
|
||||
|
||||
bits = bit32.replace(bits, 1, SETTING_ENABLE_INACTIVE)--[[@as int]]
|
||||
bits = bit32.replace(bits, 1, SETTING_ENABLE_INACTIVE)--[[@as int]]
|
||||
bits_old = bit32.replace(bits_old, 1, SETTING_USE_ANY_DEPOT)--[[@as int]]
|
||||
bits_old = bit32.replace(bits_old, 1, SETTING_USE_ANY_DEPOT)--[[@as int]]
|
||||
params.second_constant = bits
|
||||
params_old.second_constant = bits_old
|
||||
|
||||
control.parameters = params
|
||||
map_data.to_comb_params[id] = params_old
|
||||
end
|
||||
for _, station in pairs(map_data.stations) do
|
||||
station.enable_inactive = true
|
||||
end
|
||||
for train_id, train in pairs(map_data.trains) do
|
||||
train.depot_id = train.parked_at_depot_id
|
||||
if not train.depot_id then
|
||||
local e = get_any_train_entity(train.entity)
|
||||
local stops = e.force.get_train_stops({name = train.depot_name, surface = e.surface})
|
||||
for stop in rnext_consume, stops do
|
||||
local new_depot_id = stop.unit_number
|
||||
if map_data.depots[new_depot_id] then
|
||||
train.depot_id = new_depot_id--[[@as uint]]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not train.depot_id then
|
||||
train.depot_id = next(map_data.depots)
|
||||
end
|
||||
if not train.depot_id then
|
||||
train.entity.manual_mode = true
|
||||
send_alert_depot_of_train_broken(map_data, train.entity)
|
||||
local layout_id = train.layout_id
|
||||
local count = global.layout_train_count[layout_id]
|
||||
if count <= 1 then
|
||||
global.layout_train_count[layout_id] = nil
|
||||
global.layouts[layout_id] = nil
|
||||
for _, stop in pairs(global.stations) do
|
||||
stop.accepted_layouts[layout_id] = nil
|
||||
end
|
||||
for _, stop in pairs(global.refuelers) do
|
||||
stop.accepted_layouts[layout_id] = nil
|
||||
end
|
||||
else
|
||||
global.layout_train_count[layout_id] = count - 1
|
||||
end
|
||||
map_data.trains[train_id] = nil
|
||||
end
|
||||
|
||||
train.use_any_depot = true
|
||||
train.disable_bypass = nil
|
||||
|
||||
train.depot_name = nil
|
||||
train.se_depot_surface_i = nil
|
||||
train.parked_at_depot_id = nil
|
||||
end
|
||||
end
|
||||
}
|
||||
--STATUS_R_TO_D = 5
|
||||
|
||||
|
||||
@@ -48,6 +48,18 @@ function on_failed_delivery(map_data, train_id, train)
|
||||
unset_wagon_combs(map_data, station)
|
||||
end
|
||||
end
|
||||
if train.has_filtered_wagon then
|
||||
train.has_filtered_wagon = nil
|
||||
for carriage_i, carriage in ipairs(train.entity.cargo_wagons) do
|
||||
local inv = carriage.get_inventory(defines.inventory.cargo_wagon)
|
||||
if inv and inv.is_filtered() then
|
||||
---@type uint
|
||||
for i = 1, #inv do
|
||||
inv.set_filter(i, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
train.r_station_id = nil
|
||||
train.p_station_id = nil
|
||||
train.manifest = nil
|
||||
@@ -60,14 +72,21 @@ end
|
||||
---@param train_id uint
|
||||
---@param train Train
|
||||
function add_available_train(map_data, train_id, train)
|
||||
local network_name = train.network_name
|
||||
if network_name then
|
||||
local network = map_data.available_trains[network_name]
|
||||
if not network then
|
||||
network = {}
|
||||
map_data.available_trains[network_name] = network
|
||||
if train.network_name then
|
||||
local f, a
|
||||
if train.network_name == NETWORK_EACH then
|
||||
f, a = next, train.network_flag
|
||||
else
|
||||
f, a = once, train.network_name
|
||||
end
|
||||
for network_name in f, a do
|
||||
local network = map_data.available_trains[network_name]
|
||||
if not network then
|
||||
network = {}
|
||||
map_data.available_trains[network_name] = network
|
||||
end
|
||||
network[train_id] = true
|
||||
end
|
||||
network[train_id] = true
|
||||
train.is_available = true
|
||||
interface_raise_train_available(train_id)
|
||||
end
|
||||
@@ -80,77 +99,56 @@ end
|
||||
---@param train Train
|
||||
function add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot)
|
||||
local comb = depot.entity_comb
|
||||
local network_name = get_comb_network_name(comb)
|
||||
if network_name then
|
||||
local network = map_data.available_trains[network_name]
|
||||
if not network then
|
||||
network = {}
|
||||
map_data.available_trains[network_name] = network
|
||||
end
|
||||
network[train_id] = true
|
||||
train.is_available = true
|
||||
end
|
||||
set_train_from_comb(mod_settings, train, comb)
|
||||
depot.available_train_id = train_id
|
||||
train.depot_id = depot_id
|
||||
train.status = STATUS_D
|
||||
train.parked_at_depot_id = depot_id
|
||||
train.depot_name = depot.entity_stop.backer_name
|
||||
train.se_depot_surface_i = depot.entity_stop.surface.index
|
||||
train.network_name = network_name
|
||||
train.network_flag = mod_settings.network_flag
|
||||
train.priority = 0
|
||||
if network_name then
|
||||
local signals = comb.get_merged_signals(defines.circuit_connector_id.combinator_input)
|
||||
if signals then
|
||||
for k, v in pairs(signals) do
|
||||
local item_name = v.signal.name
|
||||
local item_count = v.count
|
||||
if item_name then
|
||||
if item_name == SIGNAL_PRIORITY then
|
||||
train.priority = item_count
|
||||
end
|
||||
if item_name == network_name then
|
||||
train.network_flag = item_count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
interface_raise_train_available(train_id)
|
||||
end
|
||||
|
||||
add_available_train(map_data, train_id, train)
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param train_id uint
|
||||
---@param train Train
|
||||
function remove_available_train(map_data, train_id, train)
|
||||
---@type uint
|
||||
if train.is_available and train.network_name then
|
||||
local network = map_data.available_trains[train.network_name--[[@as string]]]
|
||||
if network then
|
||||
network[train_id] = nil
|
||||
if next(network) == nil then
|
||||
map_data.available_trains[train.network_name] = nil
|
||||
if train.is_available then
|
||||
train.is_available = nil
|
||||
local f, a
|
||||
if train.network_name == NETWORK_EACH then
|
||||
f, a = next, train.network_flag
|
||||
else
|
||||
f, a = once, train.network_name
|
||||
end
|
||||
for network_name in f, a do
|
||||
local network = map_data.available_trains[network_name]
|
||||
if network then
|
||||
network[train_id] = nil
|
||||
if next(network) == nil then
|
||||
map_data.available_trains[network_name] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
train.is_available = nil
|
||||
local depot = map_data.depots[train.depot_id]
|
||||
if depot.available_train_id == train_id then
|
||||
depot.available_train_id = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---@param map_data MapData
|
||||
---@param depot_id uint
|
||||
---@param train_entity LuaTrain
|
||||
local function on_train_arrives_depot(map_data, depot_id, train_entity)
|
||||
local contents = train_entity.get_contents()
|
||||
local fluid_contents = train_entity.get_fluid_contents()
|
||||
local is_train_empty = next(contents) == nil and next(fluid_contents) == nil
|
||||
local is_train_empty = next(train_entity.get_contents()) == nil and next(train_entity.get_fluid_contents()) == nil
|
||||
local train_id = train_entity.id
|
||||
local train = map_data.trains[train_id]
|
||||
if train then
|
||||
if train.status == STATUS_TO_D then
|
||||
elseif train.status == STATUS_TO_D_BYPASS or train.status == STATUS_D then
|
||||
--shouldn't be possible to get train.status == STATUS_D
|
||||
elseif train.status == STATUS_TO_D_BYPASS or train.status == STATUS_D then
|
||||
remove_available_train(map_data, train_id, train)
|
||||
elseif mod_settings.react_to_train_early_to_depot then
|
||||
if train.manifest then
|
||||
@@ -160,21 +158,19 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
|
||||
else
|
||||
return
|
||||
end
|
||||
if is_train_empty then
|
||||
if is_train_empty or mod_settings.allow_cargo_in_depot then
|
||||
local old_status = train.status
|
||||
add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, map_data.depots[depot_id])
|
||||
set_depot_schedule(train_entity, train.depot_name)
|
||||
local depot = map_data.depots[depot_id]
|
||||
add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot)
|
||||
set_depot_schedule(train_entity, depot.entity_stop.backer_name)
|
||||
interface_raise_train_status_changed(train_id, old_status, STATUS_D)
|
||||
else
|
||||
--train still has cargo
|
||||
if mod_settings.react_to_nonempty_train_in_depot then
|
||||
lock_train_to_depot(train_entity)
|
||||
remove_train(map_data, train_id, train)
|
||||
send_alert_nonempty_train_in_depot(map_data, train_entity)
|
||||
end
|
||||
interface_raise_train_nonempty_in_depot(depot_id, train_entity, train_id)
|
||||
lock_train_to_depot(train_entity)
|
||||
remove_train(map_data, train_id, train)
|
||||
send_alert_nonempty_train_in_depot(map_data, train_entity)
|
||||
end
|
||||
elseif is_train_empty then
|
||||
elseif is_train_empty or mod_settings.allow_cargo_in_depot then
|
||||
--NOTE: only place where new Train
|
||||
train = {
|
||||
entity = train_entity,
|
||||
@@ -188,22 +184,25 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
|
||||
last_manifest_tick = map_data.total_ticks,
|
||||
has_filtered_wagon = nil,
|
||||
--is_available = add_available_train_to_depot,
|
||||
--parked_at_depot_id = add_available_train_to_depot,
|
||||
--depot_name = add_available_train_to_depot,
|
||||
--depot_id = add_available_train_to_depot,
|
||||
--use_any_depot = add_available_train_to_depot,
|
||||
--disable_bypass = add_available_train_to_depot,
|
||||
--network_name = add_available_train_to_depot,
|
||||
--network_flag = add_available_train_to_depot,
|
||||
--priority = add_available_train_to_depot,
|
||||
}
|
||||
}--[[@as Train]]
|
||||
set_train_layout(map_data, train)
|
||||
map_data.trains[train_id] = train
|
||||
add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, map_data.depots[depot_id])
|
||||
local depot = map_data.depots[depot_id]
|
||||
add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, depot)
|
||||
|
||||
set_depot_schedule(train_entity, train.depot_name)
|
||||
set_depot_schedule(train_entity, depot.entity_stop.backer_name)
|
||||
interface_raise_train_created(train_id, depot_id)
|
||||
else
|
||||
if mod_settings.react_to_nonempty_train_in_depot then
|
||||
send_alert_nonempty_train_in_depot(map_data, train_entity)
|
||||
end
|
||||
lock_train_to_depot(train_entity)
|
||||
send_alert_nonempty_train_in_depot(map_data, train_entity)
|
||||
end
|
||||
if not is_train_empty then
|
||||
interface_raise_train_nonempty_in_depot(depot_id, train_entity)
|
||||
end
|
||||
end
|
||||
@@ -218,7 +217,7 @@ local function on_train_arrives_station(map_data, station_id, train_id, train)
|
||||
if train.p_station_id == station_id then
|
||||
train.status = STATUS_P
|
||||
local station = map_data.stations[station_id]
|
||||
set_comb1(map_data, station, train.manifest, 1)
|
||||
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and 1 or -1)
|
||||
set_p_wagon_combs(map_data, station, train)
|
||||
interface_raise_train_status_changed(train_id, STATUS_TO_P, STATUS_P)
|
||||
end
|
||||
@@ -226,7 +225,7 @@ local function on_train_arrives_station(map_data, station_id, train_id, train)
|
||||
if train.r_station_id == station_id then
|
||||
train.status = STATUS_R
|
||||
local station = map_data.stations[station_id]
|
||||
set_comb1(map_data, station, train.manifest, -1)
|
||||
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and -1 or 1)
|
||||
set_r_wagon_combs(map_data, station, train)
|
||||
interface_raise_train_status_changed(train_id, STATUS_TO_R, STATUS_R)
|
||||
end
|
||||
@@ -316,45 +315,54 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
|
||||
end
|
||||
if fuel_fill > mod_settings.fuel_threshold then
|
||||
--if fuel_fill == INF, it's probably a modded electric train
|
||||
if mod_settings.depot_bypass_enabled then
|
||||
if not train.disable_bypass then
|
||||
train.status = STATUS_TO_D_BYPASS
|
||||
add_available_train(map_data, train_id, train)
|
||||
interface_raise_train_status_changed(train_id, STATUS_R, STATUS_TO_D_BYPASS)
|
||||
return
|
||||
end
|
||||
else
|
||||
local refuelers = map_data.to_refuelers[train.network_name]
|
||||
if refuelers then
|
||||
local best_refueler_id = nil
|
||||
local best_dist = INF
|
||||
local best_prior = -INF
|
||||
for id, _ in pairs(refuelers) do
|
||||
local refueler = map_data.refuelers[id]
|
||||
set_refueler_from_comb(map_data, mod_settings, id)
|
||||
local f, a
|
||||
if train.network_name == NETWORK_EACH then
|
||||
f, a = next, train.network_flag
|
||||
else
|
||||
f, a = once, train.network_name
|
||||
end
|
||||
for network_name in f, a do
|
||||
local refuelers = map_data.to_refuelers[network_name]
|
||||
if refuelers then
|
||||
local best_refueler_id = nil
|
||||
local best_dist = INF
|
||||
local best_prior = -INF
|
||||
for id, _ in pairs(refuelers) do
|
||||
local refueler = map_data.refuelers[id]
|
||||
set_refueler_from_comb(map_data, mod_settings, id)
|
||||
|
||||
local refueler_network_flag = refueler.network_name == NETWORK_EACH and (refueler.network_flag[train.network_name] or 0) 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
|
||||
dist = get_stop_dist(train.entity.front_stock, refueler.entity_stop)
|
||||
accepted = dist < best_dist
|
||||
end
|
||||
if accepted or refueler.priority > best_prior then
|
||||
best_refueler_id = id
|
||||
best_dist = dist or get_stop_dist(train.entity.front_stock, refueler.entity_stop)
|
||||
best_prior = refueler.priority
|
||||
local refueler_network_flag = get_network_flag(refueler, network_name)
|
||||
local train_network_flag = get_network_flag(train, network_name)
|
||||
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
|
||||
dist = get_stop_dist(train.entity.front_stock, refueler.entity_stop)
|
||||
accepted = dist < best_dist
|
||||
end
|
||||
if accepted or refueler.priority > best_prior then
|
||||
best_refueler_id = id
|
||||
best_dist = dist or get_stop_dist(train.entity.front_stock, refueler.entity_stop)
|
||||
best_prior = refueler.priority
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if best_refueler_id then
|
||||
train.status = STATUS_TO_F
|
||||
train.refueler_id = best_refueler_id
|
||||
local refueler = map_data.refuelers[best_refueler_id]
|
||||
refueler.trains_total = refueler.trains_total + 1
|
||||
add_refueler_schedule(map_data, train.entity, refueler.entity_stop)
|
||||
interface_raise_train_status_changed(train_id, STATUS_R, STATUS_TO_F)
|
||||
return
|
||||
if best_refueler_id then
|
||||
train.status = STATUS_TO_F
|
||||
train.refueler_id = best_refueler_id
|
||||
local refueler = map_data.refuelers[best_refueler_id]
|
||||
refueler.trains_total = refueler.trains_total + 1
|
||||
add_refueler_schedule(map_data, train.entity, refueler.entity_stop)
|
||||
interface_raise_train_status_changed(train_id, STATUS_R, STATUS_TO_F)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -367,7 +375,7 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
|
||||
refueler.trains_total = refueler.trains_total - 1
|
||||
unset_wagon_combs(map_data, refueler)
|
||||
set_combinator_output(map_data, refueler.entity_comb, nil)
|
||||
if mod_settings.depot_bypass_enabled then
|
||||
if not train.disable_bypass then
|
||||
train.status = STATUS_TO_D_BYPASS
|
||||
add_available_train(map_data, train_id, train)
|
||||
else
|
||||
|
||||
@@ -18,28 +18,37 @@ data:extend({
|
||||
minimum_value = 1,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
--{
|
||||
-- type = "int-setting",
|
||||
-- name = "cybersyn-wait-time",
|
||||
-- order = "ab",
|
||||
-- setting_type = "runtime-global",
|
||||
-- default_value = 2000,
|
||||
-- minimum_value = 1,
|
||||
-- maximum_value = 2147483647,
|
||||
--},
|
||||
{
|
||||
type = "double-setting",
|
||||
type = "int-setting",
|
||||
name = "cybersyn-request-threshold",
|
||||
order = "ac",
|
||||
order = "ba",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 1,
|
||||
minimum_value = 0,
|
||||
default_value = 2000,
|
||||
minimum_value = 1,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-priority",
|
||||
order = "bb",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 0,
|
||||
minimum_value = -2147483648,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-locked-slots",
|
||||
order = "bc",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 0,
|
||||
minimum_value = 0,
|
||||
maximum_value = 1000,
|
||||
},
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-network-flag",
|
||||
order = "ad",
|
||||
order = "bd",
|
||||
setting_type = "runtime-global",
|
||||
default_value = -1,
|
||||
minimum_value = -2147483648,
|
||||
@@ -48,23 +57,16 @@ data:extend({
|
||||
{
|
||||
type = "double-setting",
|
||||
name = "cybersyn-fuel-threshold",
|
||||
order = "ae",
|
||||
order = "be",
|
||||
setting_type = "runtime-global",
|
||||
default_value = .5,
|
||||
minimum_value = 0,
|
||||
maximum_value = 1,
|
||||
},
|
||||
{
|
||||
type = "bool-setting",
|
||||
name = "cybersyn-depot-bypass-enabled",
|
||||
order = "af",
|
||||
setting_type = "runtime-global",
|
||||
default_value = true,
|
||||
},
|
||||
{
|
||||
type = "double-setting",
|
||||
name = "cybersyn-warmup-time",
|
||||
order = "ag",
|
||||
order = "ca",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 20,
|
||||
minimum_value = 0,
|
||||
@@ -73,10 +75,24 @@ data:extend({
|
||||
{
|
||||
type = "double-setting",
|
||||
name = "cybersyn-stuck-train-time",
|
||||
order = "ah",
|
||||
order = "cb",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 600,
|
||||
minimum_value = 0,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
{
|
||||
type = "bool-setting",
|
||||
name = "cybersyn-allow-cargo-in-depot",
|
||||
order = "cc",
|
||||
setting_type = "runtime-global",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
type = "bool-setting",
|
||||
name = "cybersyn-invert-sign",
|
||||
order = "da",
|
||||
setting_type = "runtime-global",
|
||||
default_value = false,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user