diff --git a/cybersyn/changelog.txt b/cybersyn/changelog.txt index 49a448c..cfee492 100644 --- a/cybersyn/changelog.txt +++ b/cybersyn/changelog.txt @@ -88,3 +88,8 @@ Version: 1.0.5 Date: 2022-11-30 Features: - Fixed a crash related to the central planner +--------------------------------------------------------------------------------------------------- +Version: 1.0.6 +Date: 2022-11-30 + Features: + - Added depot bypass diff --git a/cybersyn/info.json b/cybersyn/info.json index 1f60c47..34aa5e9 100644 --- a/cybersyn/info.json +++ b/cybersyn/info.json @@ -1,6 +1,6 @@ { "name": "cybersyn", - "version": "1.0.5", + "version": "1.0.6", "title": "Project Cybersyn", "author": "Mami", "factorio_version": "1.1", diff --git a/cybersyn/scripts/central-planning.lua b/cybersyn/scripts/central-planning.lua index fa4eee7..850a76c 100644 --- a/cybersyn/scripts/central-planning.lua +++ b/cybersyn/scripts/central-planning.lua @@ -7,7 +7,6 @@ local INF = math.huge local btest = bit32.btest local band = bit32.band local table_remove = table.remove -local table_sort = table.sort local random = math.random @@ -48,8 +47,8 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type, return nil, INF end - ---@type Depot|nil - local best_depot = nil + ---@type uint? + local best_train = nil local best_capacity = 0 local best_dist = INF local valid_train_exists = false @@ -57,8 +56,7 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type, local is_fluid = item_type == "fluid" local trains = map_data.available_trains[network_name] if trains then - for train_id, depot_id in pairs(trains) do - local depot = map_data.depots[depot_id] + for train_id, _ in pairs(trains) do local train = map_data.trains[train_id] local layout_id = train.layout_id --check cargo capabilities @@ -73,20 +71,20 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type, valid_train_exists = true --check if exists valid path --check if path is shortest so we prioritize locality - local d_to_p_dist = get_stop_dist(depot.entity_stop, p_station.entity_stop) - DEPOT_PRIORITY_MULT*train.priority + local d_to_p_dist = get_stop_dist(train.entity.front_stock, p_station.entity_stop) - DEPOT_PRIORITY_MULT*train.priority local dist = d_to_p_dist if capacity > best_capacity or (capacity == best_capacity and dist < best_dist) then best_capacity = capacity best_dist = dist - best_depot = depot + best_train = train_id end end end end if valid_train_exists then - return best_depot, best_dist + p_to_r_dist + return best_train, best_dist + p_to_r_dist else return nil, p_to_r_dist end @@ -96,14 +94,14 @@ end ---@param map_data MapData ---@param r_station_id uint ---@param p_station_id uint ----@param depot Depot +---@param train_id uint ---@param primary_item_name string -local function send_train_between(map_data, r_station_id, p_station_id, depot, primary_item_name) +local function send_train_between(map_data, r_station_id, p_station_id, train_id, primary_item_name) --trains and stations expected to be of the same network local economy = map_data.economy local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] - local train = map_data.trains[depot.available_train_id] + local train = map_data.trains[train_id] ---@type string local network_name = r_station.network_name @@ -192,14 +190,14 @@ local function send_train_between(map_data, r_station_id, p_station_id, depot, p end end - remove_available_train(map_data, train, depot) + remove_available_train(map_data, train_id, train) train.status = STATUS_D_TO_P train.p_station_id = p_station_id train.r_station_id = r_station_id train.manifest = manifest train.last_manifest_tick = map_data.total_ticks - set_manifest_schedule(train.entity, depot.entity_stop, p_station.entity_stop, r_station.entity_stop, manifest) + set_manifest_schedule(train.entity, train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest) set_comb2(map_data, p_station) set_comb2(map_data, r_station) if p_station.entity_comb1.valid then @@ -421,7 +419,7 @@ local function tick_dispatch(map_data, mod_settings) max_threshold = 0 local best_i = 0 - local best_depot = nil + local best_train = nil local best_dist = INF local best_prior = -INF local can_be_serviced = false @@ -432,12 +430,12 @@ local function tick_dispatch(map_data, mod_settings) if effective_count >= r_threshold then local prior = p_station.priority local slot_threshold = item_type == "fluid" and r_threshold or ceil(r_threshold/get_stack_size(map_data, item_name)) - local depot, d = get_valid_train(map_data, r_station_id, p_station_id, item_type, slot_threshold) + local train, d = get_valid_train(map_data, r_station_id, p_station_id, item_type, slot_threshold) if prior > best_prior or (prior == best_prior and d < best_dist) then - if depot then + if train then best_i = j best_dist = d - best_depot = depot + best_train = train best_prior = prior can_be_serviced = true elseif d < INF then @@ -451,12 +449,8 @@ local function tick_dispatch(map_data, mod_settings) end end end - if - best_depot and ( - best_depot.entity_comb.status == defines.entity_status.working or - best_depot.entity_comb.status == defines.entity_status.low_power) - then - send_train_between(map_data, r_station_id, table_remove(p_stations, best_i), best_depot, item_name) + if best_train then + send_train_between(map_data, r_station_id, table_remove(p_stations, best_i), best_train, item_name) return false else if can_be_serviced then diff --git a/cybersyn/scripts/factorio-api.lua b/cybersyn/scripts/factorio-api.lua index d910a71..116f0b6 100644 --- a/cybersyn/scripts/factorio-api.lua +++ b/cybersyn/scripts/factorio-api.lua @@ -11,12 +11,12 @@ function get_stack_size(map_data, item_name) end ----@param stop0 LuaEntity ----@param stop1 LuaEntity -function get_stop_dist(stop0, stop1) - local surface0 = stop0.surface.index - local surface1 = stop1.surface.index - return (surface0 == surface1 and get_distance(stop0.position, stop1.position) or DIFFERENT_SURFACE_DISTANCE) +---@param entity0 LuaEntity +---@param entity1 LuaEntity +function get_stop_dist(entity0, entity1) + local surface0 = entity0.surface.index + local surface1 = entity1.surface.index + return (surface0 == surface1 and get_distance(entity0.position, entity1.position) or DIFFERENT_SURFACE_DISTANCE) end @@ -107,13 +107,13 @@ function rename_manifest_schedule(train, stop, old_name) end ---@param train LuaTrain ----@param depot_stop LuaEntity +---@param depot_name string ---@param p_stop LuaEntity ---@param r_stop LuaEntity ---@param manifest Manifest -function set_manifest_schedule(train, depot_stop, p_stop, r_stop, manifest) +function set_manifest_schedule(train, depot_name, p_stop, r_stop, manifest) --NOTE: train must be on same surface as depot_stop - local d_surface = depot_stop.surface + local d_surface = train.front_stock.surface local p_surface = p_stop.surface local r_surface = r_stop.surface local d_surface_i = d_surface.index @@ -121,7 +121,7 @@ function set_manifest_schedule(train, depot_stop, p_stop, r_stop, manifest) local r_surface_i = r_surface.index if d_surface_i == p_surface_i and p_surface_i == r_surface_i then train.schedule = {current = 1, records = { - create_inactivity_order(depot_stop.backer_name), + 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), @@ -135,7 +135,7 @@ function set_manifest_schedule(train, depot_stop, p_stop, r_stop, manifest) if is_train_in_orbit or d_zone.orbit_index == other_zone.index then local elevator_name = se_get_space_elevator_name(d_surface) if elevator_name then - local records = {create_inactivity_order(depot_stop.backer_name)} + local records = {create_inactivity_order(depot_name)} if d_surface_i == p_surface_i then records[#records + 1] = create_direct_to_station_order(p_stop) else @@ -160,12 +160,12 @@ function set_manifest_schedule(train, depot_stop, p_stop, r_stop, manifest) 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_stop.backer_name), + create_inactivity_order(depot_name), create_loading_order(p_stop, manifest), create_unloading_order(r_stop), }} lock_train(train) - send_lost_train_alert(train, depot_stop.backer_name) + send_lost_train_alert(train, depot_name) end diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index 4404d60..3a25da6 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -11,7 +11,7 @@ ---@field public warmup_station_ids uint[] ---@field public depots {[uint]: Depot} ---@field public trains {[uint]: Train} ----@field public available_trains {[string]: {[uint]: uint}} --{[network_name]: {[train_id]: depot_id}} +---@field public available_trains {[string]: {[uint]: true?}} --{[network_name]: {[train_id]: depot_id}} ---@field public layouts {[uint]: int[]} ---@field public layout_train_count {[uint]: int} ---@field public tick_state uint @@ -58,6 +58,7 @@ ---@field public manifest Manifest ---@field public last_manifest_tick int ---@field public has_filtered_wagon boolean +---@field public is_available true? ---@field public depot_id uint? ---@field public depot_name string ---@field public network_name string? diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index 9927d61..58b943c 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -55,9 +55,11 @@ end ---@param train Train ---@param train_id uint function remove_train(map_data, train, train_id) - if train.status == STATUS_D then - local depot = map_data.depots[train.depot_id] - remove_available_train(map_data, train, depot) + local parked_at_depot_id = train.depot_id + if parked_at_depot_id then + local depot = map_data.depots[parked_at_depot_id] + remove_available_train(map_data, parked_at_depot_id, train) + depot.available_train_id = nil end local layout_id = train.layout_id local count = map_data.layout_train_count[layout_id] diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index f20b70d..c13c0a7 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -52,12 +52,28 @@ local function on_failed_delivery(map_data, train) end + +---@param map_data MapData +---@param train_id uint +---@param train Train +local 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 + end + network[train_id] = true + train.is_available = true + end +end ---@param map_data MapData ---@param depot_id uint +---@param depot Depot ---@param train_id uint -local function add_available_train(map_data, depot_id, train_id) - local depot = map_data.depots[depot_id] - local train = map_data.trains[train_id] +---@param train Train +local function add_available_train_to_depot(map_data, train_id, train, depot_id, depot) local comb = depot.entity_comb local network_name = get_comb_network_name(comb) if network_name then @@ -66,7 +82,8 @@ local function add_available_train(map_data, depot_id, train_id) network = {} map_data.available_trains[network_name] = network end - network[train_id] = depot_id + network[train_id] = true + train.is_available = true end depot.available_train_id = train_id train.status = STATUS_D @@ -94,13 +111,12 @@ local function add_available_train(map_data, depot_id, train_id) end end ---@param map_data MapData +---@param train_id uint ---@param train Train ----@param depot Depot -function remove_available_train(map_data, train, depot) +function remove_available_train(map_data, train_id, train) ---@type uint - local train_id = depot.available_train_id - if train.network_name then - local network = map_data.available_trains[train.network_name] + if train.is_available then + local network = map_data.available_trains[train.network_name--[[@as string]]] if network then network[train_id] = nil if next(network) == nil then @@ -108,7 +124,6 @@ function remove_available_train(map_data, train, depot) end end end - depot.available_train_id = nil end @@ -132,8 +147,9 @@ local function on_depot_broken(map_data, depot) local train = map_data.trains[train_id] lock_train(train.entity) send_lost_train_alert(train.entity, depot.entity_stop.backer_name) - remove_available_train(map_data, train, depot) + remove_available_train(map_data, train_id, train) map_data.trains[train_id] = nil + depot.available_train_id = nil end map_data.depots[depot.entity_stop.unit_number] = nil end @@ -350,8 +366,9 @@ function on_combinator_network_updated(map_data, comb, network_name) local train_id = depot.available_train_id if train_id then local train = map_data.trains[train_id] - remove_available_train(map_data, train, depot) - add_available_train(map_data, depot_id, train_id) + remove_available_train(map_data, train_id, train) + depot.available_train_id = nil + add_available_train_to_depot(map_data, train_id, train, depot_id, depot) end end end @@ -522,7 +539,7 @@ end ---@param old_name string local function on_station_rename(map_data, stop, old_name) --search for trains coming to the renamed station - local station_id = stop.unit_number + local station_id = stop.unit_number--[[@as uint]] local station = map_data.stations[station_id] if station and station.deliveries_total > 0 then for train_id, train in pairs(map_data.trains) do @@ -552,7 +569,7 @@ local function on_station_rename(map_data, stop, old_name) 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] + local train = map_data.trains[depot.available_train_id--[[@as uint]]] train.depot_name = stop.backer_name end end @@ -581,18 +598,19 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity) local train_id = train_entity.id local train = map_data.trains[train_id] if train then + remove_available_train(map_data, train_id, train) if train.manifest and train.status == STATUS_R_TO_D then --succeeded delivery train.p_station_id = 0 train.r_station_id = 0 train.manifest = nil - add_available_train(map_data, depot_id, train_id) + add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id]) else if train.manifest then on_failed_delivery(map_data, train) send_unexpected_train_alert(train.entity) end - add_available_train(map_data, depot_id, train_id) + add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id]) end if is_train_empty then set_depot_schedule(train_entity, train.depot_name) @@ -616,7 +634,7 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity) } update_train_layout(map_data, train) map_data.trains[train_id] = train - add_available_train(map_data, depot_id, train_id) + add_available_train_to_depot(map_data, train_id, train, depot_id, map_data.depots[depot_id]) set_depot_schedule(train_entity, train.depot_name) else @@ -661,8 +679,9 @@ local function on_train_arrives_buffer(map_data, stop, train) end end ---@param map_data MapData +---@param train_id uint ---@param train Train -local function on_train_leaves_station(map_data, train) +local function on_train_leaves_station(map_data, train_id, train) if train.manifest then if train.status == STATUS_P then train.status = STATUS_P_TO_R @@ -692,8 +711,9 @@ local function on_train_leaves_station(map_data, train) unset_wagon_combs(map_data, station) end elseif train.status == STATUS_D then - local depot = map_data.depots[train.depot_id] - remove_available_train(map_data, train, depot) + local depot = map_data.depots[train.depot_id--[[@as uint]]] + remove_available_train(map_data, train_id, train) + depot.available_train_id = nil end end @@ -789,9 +809,10 @@ local function on_train_built(event) end end local function on_train_changed(event) - local train_e = event.train + local train_e = event.train--[[@as LuaTrain]] if not train_e.valid then return end - local train = global.trains[train_e.id] + local train_id = train_e.id + local train = global.trains[train_id] if train_e.state == defines.train_state.wait_station then local stop = train_e.station if stop and stop.valid and stop.name == "train-stop" then @@ -800,7 +821,7 @@ local function on_train_changed(event) on_train_arrives_buffer(global, stop, train) end else - local depot_id = stop.unit_number + local depot_id = stop.unit_number--[[@as uint]] if global.depots[depot_id] then on_train_arrives_depot(global, depot_id, train_e) end @@ -808,7 +829,7 @@ local function on_train_changed(event) end elseif event.old_state == defines.train_state.wait_station then if train then - on_train_leaves_station(global, train) + on_train_leaves_station(global, train_id, train) end end end diff --git a/cybersyn/scripts/migrations.lua b/cybersyn/scripts/migrations.lua index 2606f85..98eb7df 100644 --- a/cybersyn/scripts/migrations.lua +++ b/cybersyn/scripts/migrations.lua @@ -124,6 +124,18 @@ local migrations_table = { map_data.tick_state = STATE_INIT map_data.tick_data = {} end, + ["1.0.6"] = function() + ---@type MapData + local map_data = global + map_data.tick_state = STATE_INIT + map_data.tick_data = {} + for k, v in pairs(map_data.available_trains) do + for id, _ in pairs(v) do + local train = map_data.trains[id] + train.is_available = true + end + end + end, } ---@param data ConfigurationChangedData