mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-11 04:08:10 -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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user