diff --git a/cybersyn/changelog.txt b/cybersyn/changelog.txt index 06125b2..5f0dc4a 100644 --- a/cybersyn/changelog.txt +++ b/cybersyn/changelog.txt @@ -119,3 +119,4 @@ Date: 2022-12-5 - Added refueler stations - Slightly more permissive allow-list logic - Fixed a crash relating to wagon control combinators on request stations + - Made non-backwards compatible improvements and bugfixes to the modding interface diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index aa19734..9ecb0d1 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -53,6 +53,7 @@ operation=Mode comb1=Primary station control comb2=Optional station control depot=Depot control +refueler=Refueling station control wagon-manifest=Wagon control 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 provide and request stations if they are all identified with the same signal. diff --git a/cybersyn/scripts/central-planning.lua b/cybersyn/scripts/central-planning.lua index dbe303f..b41ece5 100644 --- a/cybersyn/scripts/central-planning.lua +++ b/cybersyn/scripts/central-planning.lua @@ -95,9 +95,8 @@ end ---@param r_station_id uint ---@param p_station_id uint ---@param train_id uint ----@param primary_item_name string? -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 +---@param manifest Manifest +function create_delivery(map_data, r_station_id, p_station_id, train_id, manifest) local economy = map_data.economy local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] @@ -105,6 +104,69 @@ function send_train_between(map_data, r_station_id, p_station_id, train_id, prim ---@type string local network_name = r_station.network_name + 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(train.entity, train.depot_name, train.se_depot_surface_i, p_station.entity_stop, r_station.entity_stop, manifest, depot_id ~= nil) then + local old_status = train.status + train.status = STATUS_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 + + r_station.last_delivery_tick = map_data.total_ticks + p_station.last_delivery_tick = map_data.total_ticks + + r_station.deliveries_total = r_station.deliveries_total + 1 + p_station.deliveries_total = p_station.deliveries_total + 1 + + for item_i, item in ipairs(manifest) do + assert(item.count > 0, "main.lua error, transfer amount was not positive") + + r_station.deliveries[item.name] = (r_station.deliveries[item.name] or 0) + item.count + p_station.deliveries[item.name] = (p_station.deliveries[item.name] or 0) - item.count + + if item_i > 1 then + --prevent deliveries from being processed for these items until their stations are re-polled + local item_network_name = network_name..":"..item.name + economy.all_r_stations[item_network_name] = nil + economy.all_p_stations[item_network_name] = nil + end + end + + set_comb2(map_data, p_station) + set_comb2(map_data, r_station) + + if p_station.display_state < 2 then + p_station.display_state = 2 + update_display(map_data, p_station) + end + if r_station.display_state < 2 then + r_station.display_state = 2 + update_display(map_data, r_station) + end + interface_raise_train_status_changed(train_id, old_status, STATUS_TO_P) + else + interface_raise_train_dispatch_failed(train_id) + end +end +---@param map_data MapData +---@param r_station_id uint +---@param p_station_id uint +---@param train_id uint +---@param primary_item_name string? +function create_manifest(map_data, r_station_id, p_station_id, train_id, primary_item_name) + --trains and stations expected to be of the same network + 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] + + ---@type Manifest local manifest = {} for k, v in pairs(r_station.tick_signals) do @@ -167,55 +229,7 @@ function send_train_between(map_data, r_station_id, p_station_id, train_id, prim end end - 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(train.entity, train.depot_name, train.se_depot_surface_i, p_station.entity_stop, r_station.entity_stop, manifest, depot_id ~= nil) then - train.status = STATUS_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 - - r_station.last_delivery_tick = map_data.total_ticks - p_station.last_delivery_tick = map_data.total_ticks - - r_station.deliveries_total = r_station.deliveries_total + 1 - p_station.deliveries_total = p_station.deliveries_total + 1 - - for item_i, item in ipairs(manifest) do - assert(item.count > 0, "main.lua error, transfer amount was not positive") - - r_station.deliveries[item.name] = (r_station.deliveries[item.name] or 0) + item.count - p_station.deliveries[item.name] = (p_station.deliveries[item.name] or 0) - item.count - - if item_i > 1 then - --prevent deliveries from being processed for these items until their stations are re-polled - local item_network_name = network_name..":"..item.name - economy.all_r_stations[item_network_name] = nil - economy.all_p_stations[item_network_name] = nil - end - end - - set_comb2(map_data, p_station) - set_comb2(map_data, r_station) - - if p_station.display_state < 2 then - p_station.display_state = 2 - update_display(map_data, p_station) - end - if r_station.display_state < 2 then - r_station.display_state = 2 - update_display(map_data, r_station) - end - interface_raise_train_dispatched(train_id) - else - interface_raise_train_dispatch_failed(train_id) - end + return manifest end ---@param map_data MapData @@ -350,7 +364,9 @@ local function tick_dispatch(map_data, mod_settings) end end if best_train then - send_train_between(map_data, r_station_id, table_remove(p_stations, best_i), best_train, item_name) + local p_station_id = table_remove(p_stations, best_i) + local manifest = create_manifest(map_data, r_station_id, p_station_id, best_train, item_name) + create_delivery(map_data, r_station_id, p_station_id, best_train, manifest) return false else if can_be_serviced and mod_settings.missing_train_alert_enabled then diff --git a/cybersyn/scripts/factorio-api.lua b/cybersyn/scripts/factorio-api.lua index 340c28f..b68c63a 100644 --- a/cybersyn/scripts/factorio-api.lua +++ b/cybersyn/scripts/factorio-api.lua @@ -274,8 +274,10 @@ function get_comb_gui_settings(comb) selected_index = 2 elseif op == OPERATION_DEPOT then selected_index = 3 - elseif op == OPERATION_WAGON_MANIFEST then + elseif op == OPERATION_REFUELER then selected_index = 4 + elseif op == OPERATION_WAGON_MANIFEST then + selected_index = 5 end return selected_index, params.first_signal, not allows_all_trains, switch_state end diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index 5dd482f..786914e 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -13,7 +13,7 @@ ---@field public refuelers {[uint]: Refueler} ---@field public trains {[uint]: Train} ---@field public available_trains {[string]: {[uint]: true?}} --{[network_name]: {[train_id]: true}} ----@field public to_refueler {[string]: {[uint]: true?}} --{[network_name]: {[refeuler_id]: true}} +---@field public to_refuelers {[string]: {[uint]: true?}} --{[network_name]: {[refeuler_id]: true}} ---@field public layouts {[uint]: (0|1|2)[]} ---@field public layout_train_count {[uint]: int} ---@field public tick_state uint @@ -67,7 +67,7 @@ ---@field public layout_id uint ---@field public item_slot_capacity int ---@field public fluid_capacity int ----@field public status int +---@field public status uint ---@field public p_station_id uint? ---@field public r_station_id uint? ---@field public manifest Manifest? @@ -89,7 +89,7 @@ ---@class ManifestEntry ---@field public type string ---@field public name string ----@field public count uint +---@field public count int ---@class Economy ---could contain invalid stations or stations with modified settings from when they were first appended diff --git a/cybersyn/scripts/gui.lua b/cybersyn/scripts/gui.lua index 6d661c4..61436a1 100644 --- a/cybersyn/scripts/gui.lua +++ b/cybersyn/scripts/gui.lua @@ -62,6 +62,7 @@ function gui_opened(comb, player) {"cybersyn-gui.comb1"}, {"cybersyn-gui.comb2"}, {"cybersyn-gui.depot"}, + {"cybersyn-gui.refueler"}, {"cybersyn-gui.wagon-manifest"}, }}, {type="switch", name="switch", ref={"switch"}, allow_none_state=true, switch_state=switch_state, left_label_caption={"cybersyn-gui.switch-provide"}, right_label_caption={"cybersyn-gui.switch-request"}, left_label_tooltip={"cybersyn-gui.switch-provide-tooltip"}, right_label_tooltip={"cybersyn-gui.switch-request-tooltip"}, actions={ @@ -88,10 +89,12 @@ function gui_opened(comb, player) window.preview.entity = comb window.titlebar.drag_target = window.main_window window.main_window.force_auto_center() - window.network.visible = selected_index == 1 or selected_index == 3 - window.network_label.visible = selected_index == 1 or selected_index == 3 - window.radio_button.visible = selected_index == 1 - window.radio_label.visible = selected_index == 1 + local uses_network = selected_index == 1 or selected_index == 3 or selected_index == 4 + local uses_allow_list = selected_index == 1 or selected_index == 4 + window.network.visible = uses_network + window.network_label.visible = uses_network + window.radio_button.visible = uses_allow_list + window.radio_label.visible = uses_allow_list window.switch.visible = selected_index == 1 player.opened = window.main_window @@ -163,6 +166,13 @@ function register_gui_actions() bottom_flow["radio_button"].visible = false bottom_flow["radio_label"].visible = false elseif element.selected_index == 4 then + set_comb_operation(comb, OPERATION_REFUELER) + top_flow["switch"].visible = false + all_flow["network_label"].visible = true + bottom_flow["network"].visible = true + bottom_flow["radio_button"].visible = true + bottom_flow["radio_label"].visible = true + elseif element.selected_index == 5 then set_comb_operation(comb, OPERATION_WAGON_MANIFEST) top_flow["switch"].visible = false all_flow["network_label"].visible = false diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index bca4d35..dd2ce8b 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -54,7 +54,7 @@ local function on_refueler_built(map_data, stop, comb) local id = stop.unit_number--[[@as uint]] map_data.refuelers[id] = refueler update_stop_if_auto(map_data, refueler, false) - interface_raise_refueler_created(depot_id) + interface_raise_refueler_created(id) end ---@param map_data MapData ---@param refueler_id uint @@ -76,10 +76,10 @@ local function on_refueler_broken(map_data, refueler_id, refueler) end end if refueler.network_name then - local network = map_data.to_refueler[refueler.network_name] + local network = map_data.to_refuelers[refueler.network_name] network[refueler_id] = nil if next(network) == nil then - map_data.to_refueler[refueler.network_name] = nil + map_data.to_refuelers[refueler.network_name] = nil end end map_data.stations[refueler_id] = nil @@ -309,24 +309,25 @@ function on_combinator_network_updated(map_data, comb, network_name) local train = map_data.trains[train_id] remove_available_train(map_data, train_id, train) add_available_train_to_depot(map_data, mod_settings, train_id, train, id, depot) + interface_raise_train_status_changed(train_id, STATUS_D, STATUS_D) end end else local refueler = map_data.refuelers[id] if refueler and refueler.entity_comb == comb then if refueler.network_name then - local network = map_data.to_refueler[refueler.network_name] + local network = map_data.to_refuelers[refueler.network_name] network[id] = nil if next(network) == nil then - map_data.to_refueler[refueler.network_name] = nil + map_data.to_refuelers[refueler.network_name] = nil end end refueler.network_name = network_name if network_name then - local network = map_data.to_refueler[network_name] + local network = map_data.to_refuelers[network_name] if network == nil then network = {} - map_data.to_refueler[network_name] = network + map_data.to_refuelers[network_name] = network end network[id] = true end diff --git a/cybersyn/scripts/migrations.lua b/cybersyn/scripts/migrations.lua index 0a3a17e..e7df6df 100644 --- a/cybersyn/scripts/migrations.lua +++ b/cybersyn/scripts/migrations.lua @@ -73,9 +73,27 @@ local migrations_table = { local map_data = global map_data.tick_state = STATE_INIT map_data.tick_data = {} + map_data.refuelers = {} + map_data.to_refuelers = {} for id, station in pairs(map_data.stations) do station.p_count_or_r_threshold_per_item = nil end + + local OLD_STATUS_R_TO_D = 5 + local NEW_STATUS_TO_D = 5 + local NEW_STATUS_TO_D_BYPASS = 6 + for id, train in pairs(map_data.trains) do + if train.status == OLD_STATUS_R_TO_D then + train.manifest = nil + train.p_station_id = nil + train.r_station_id = nil + if train.is_available then + train.status = NEW_STATUS_TO_D_BYPASS + else + train.status = NEW_STATUS_TO_D + end + end + end end, } --STATUS_R_TO_D = 5 diff --git a/cybersyn/scripts/remote-interface.lua b/cybersyn/scripts/remote-interface.lua index f8cf2a5..657e8b2 100644 --- a/cybersyn/scripts/remote-interface.lua +++ b/cybersyn/scripts/remote-interface.lua @@ -13,16 +13,15 @@ local on_station_created = nil local on_station_removed = nil local on_depot_created = nil local on_depot_removed = nil +local on_refueler_created = nil +local on_refueler_removed = nil local on_train_created = nil local on_train_removed = nil local on_train_available = nil local on_train_nonempty_in_depot = nil -local on_train_dispatched = nil local on_train_dispatch_failed = nil local on_train_failed_delivery = nil -local on_train_completed_provide = nil -local on_train_completed_request = nil -local on_train_parked_at_depot = nil +local on_train_status_changed = nil local on_train_stuck = nil local on_train_teleport_started = nil local on_train_teleported = nil @@ -77,6 +76,25 @@ function interface_raise_depot_removed(old_depot_id, old_depot) end end +---@param refueler_id uint +function interface_raise_refueler_created(refueler_id) + if on_refueler_created then + raise_event(on_refueler_created, { + refueler_id = refueler_id, + }) + end +end +---@param old_refueler_id uint +---@param old_refueler Refueler +function interface_raise_refueler_removed(old_refueler_id, old_refueler) + if on_refueler_removed then + raise_event(on_refueler_removed, { + old_refueler_id = old_refueler_id, --this id is now invalid + old_refueler = old_refueler, --this is the data that used to be stored at the old id + }) + end +end + ---@param train_id uint ---@param depot_id uint function interface_raise_train_created(train_id, depot_id) @@ -118,14 +136,6 @@ function interface_raise_train_nonempty_in_depot(depot_id, train_entity, train_i end end ----@param train_id uint -function interface_raise_train_dispatched(train_id) - if on_train_dispatched then - raise_event(on_train_dispatched, { - train_id = train_id, - }) - end -end ---@param train_id uint function interface_raise_train_dispatch_failed(train_id) --this event is rare, it can only occur when a train is bypassing the depot and can't find a path to the provide station, that train is marked as unavailable but not dispatched @@ -154,28 +164,14 @@ function interface_raise_train_failed_delivery(train_id, was_p_in_progress, p_st end end ---@param train_id uint -function interface_raise_train_completed_provide(train_id) - if on_train_completed_provide then - raise_event(on_train_completed_provide, { +---@param old_status uint +---@param new_status uint +function interface_raise_train_status_changed(train_id, old_status, new_status) + if on_train_status_changed then + raise_event(on_train_status_changed, { train_id = train_id, - }) - end -end ----@param train_id uint -function interface_raise_train_completed_request(train_id) - if on_train_completed_request then - raise_event(on_train_completed_request, { - train_id = train_id, - }) - end -end ----@param train_id uint ----@param depot_id uint -function interface_raise_train_parked_at_depot(train_id, depot_id) - if on_train_parked_at_depot then - raise_event(on_train_parked_at_depot, { - train_id = train_id, - depot_id = depot_id, + old_status = old_status, + new_status = new_status, }) end end @@ -240,6 +236,14 @@ function interface.get_on_depot_removed() if not on_depot_removed then on_depot_removed = script_generate_event_name() end return on_depot_removed end +function interface.get_on_refueler_created() + if not on_refueler_created then on_refueler_created = script_generate_event_name() end + return on_refueler_created +end +function interface.get_on_refueler_removed() + if not on_refueler_removed then on_refueler_removed = script_generate_event_name() end + return on_refueler_removed +end function interface.get_on_train_created() if not on_train_created then on_train_created = script_generate_event_name() end return on_train_created @@ -256,10 +260,6 @@ function interface.get_on_train_nonempty_in_depot() if not on_train_nonempty_in_depot then on_train_nonempty_in_depot = script_generate_event_name() end return on_train_nonempty_in_depot end -function interface.get_on_train_dispatched() - if not on_train_dispatched then on_train_dispatched = script_generate_event_name() end - return on_train_dispatched -end function interface.get_on_train_dispatch_failed() if not on_train_dispatch_failed then on_train_dispatch_failed = script_generate_event_name() end return on_train_dispatch_failed @@ -268,17 +268,9 @@ function interface.get_on_train_failed_delivery() if not on_train_failed_delivery then on_train_failed_delivery = script_generate_event_name() end return on_train_failed_delivery end -function interface.get_on_train_completed_provide() - if not on_train_completed_provide then on_train_completed_provide = script_generate_event_name() end - return on_train_completed_provide -end -function interface.get_on_train_completed_request() - if not on_train_completed_request then on_train_completed_request = script_generate_event_name() end - return on_train_completed_request -end -function interface.get_on_train_parked_at_depot() - if not on_train_parked_at_depot then on_train_parked_at_depot = script_generate_event_name() end - return on_train_parked_at_depot +function interface.get_on_train_status_changed() + if not on_train_status_changed then on_train_status_changed = script_generate_event_name() end + return on_train_status_changed end function interface.get_on_train_stuck() if not on_train_stuck then on_train_stuck = script_generate_event_name() end @@ -298,11 +290,79 @@ function interface.get_on_tick_init() end +------------------------------------------------------------------ +--[[helper functions]] +------------------------------------------------------------------ +--NOTE: the policy of cybersyn is to give modders access to as much of the raw data of the mod as possible. Factorio only allows me to return copies of the original data rather than the actual thing, which sucks. The unsafe api has some tools to help you bypass this limitation. + +function interface.get_mod_settings() + return mod_settings +end +---@param key string +function interface.read_setting(key) + return mod_settings[key] +end +---@param ... string|int +function interface.read_global(...) + --this can read anything off of cybersyn's map_data + --so interface.read_global("trains", 31415, "manifest") == global.trains[31415].manifest (or nil if train 31415 does not exist) + --the second return value is how many parameters could be processed before a nil value was encountered (in the above example it's useful for telling apart global.trains[31415] == nil vs global.trains[31415].manifest == nil) + local base = global + local depth = 0 + for i, v in ipairs({...}) do + depth = i + base = base[v] + if not base then break end + end + return base, depth +end +---@param id uint +function interface.get_station(id) + return global.stations[id] +end +---@param id uint +function interface.get_depot(id) + return global.depots[id] +end +---@param id uint +function interface.get_refueler(id) + return global.refuelers[id] +end +---@param id uint +function interface.get_train(id) + return global.trains[id] +end +---@param train_entity LuaTrain +function interface.get_train_id_from_luatrain(train_entity) + return train_entity.id +end +---@param stop LuaEntity +function interface.get_id_from_stop(stop) + return stop.unit_number +end +---@param comb LuaEntity +function interface.get_id_from_comb(comb) + local stop = global.to_stop[comb.unit_number] + if stop then + return stop.unit_number + end +end + + ------------------------------------------------------------------ --[[safe API]] ------------------------------------------------------------------ --NOTE: These functions can be called whenever however so long as their parameters have the correct types. Their ability to cause harm is extremely minimal. +---@param key string +---@param value any +function interface.write_setting(key, value) + --be careful that the value you write is of the correct type specified in global.lua + --these settings are not saved and have to be set on load and on init + mod_settings[key] = value +end + + ---@param comb LuaEntity function interface.combinator_update(comb) combinator_update(global, comb) @@ -330,6 +390,11 @@ end function interface.is_layout_accepted(layout_pattern, layout) return is_layout_accepted(layout_pattern, layout) end +---@param layout_pattern (0|1|2|3)[] +---@param layout (0|1|2)[] +function interface.is_refuel_layout_accepted(layout_pattern, layout) + return is_refuel_layout_accepted(layout_pattern, layout) +end ---@param stop_id uint ---@param forbidden_entity LuaEntity? ---@param force_update boolean? @@ -358,14 +423,8 @@ end ------------------------------------------------------------------ --NOTE: The following functions can cause serious longterm damage to someone's world if they are given bad parameters. Please refer to global.lua for type information. Use caution. ----@param key string ---@param value any -function interface.write_setting(key, value) - --be careful that the value you write is of the correct type specified in global.lua - mod_settings[key] = value -end - ----@param ... string|uint|any +---@param ... string|int function interface.write_global(value, ...) --this can write anything into cybersyn's map_data, please be very careful with anything you write, it can cause permanent damage --so interface.read_global(nil, "trains", 31415, "manifest") will cause global.trains[31415].manifest = nil (or return false if train 31415 does not exist) @@ -393,11 +452,19 @@ end ---@param r_station_id uint ---@param p_station_id uint ---@param train_id uint ----@param primary_item_name string? -function interface.create_new_delivery_between_stations(r_station_id, p_station_id, train_id, primary_item_name) +function interface.create_manifest(r_station_id, p_station_id, train_id) local train = global.trains[train_id] assert(global.stations[r_station_id] and global.stations[p_station_id] and train and train.is_available) - send_train_between(global, r_station_id, p_station_id, train_id, primary_item_name) + create_manifest(global, r_station_id, p_station_id, train_id) +end +---@param r_station_id uint +---@param p_station_id uint +---@param train_id uint +---@param manifest Manifest +function interface.create_delivery(r_station_id, p_station_id, train_id, manifest) + local train = global.trains[train_id] + assert(global.stations[r_station_id] and global.stations[p_station_id] and train and train.is_available and manifest) + create_delivery(global, r_station_id, p_station_id, train_id, manifest) end ---@param train_id uint function interface.fail_delivery(train_id) @@ -453,6 +520,7 @@ interface.rename_manifest_schedule = rename_manifest_schedule interface.se_get_space_elevator_name = se_get_space_elevator_name interface.se_create_elevator_order = se_create_elevator_order interface.set_manifest_schedule = set_manifest_schedule +interface.add_refueler_schedule = add_refueler_schedule ------------------------------------------------------------------ --[[alerts]] @@ -464,58 +532,5 @@ interface.send_unexpected_train_alert = send_unexpected_train_alert interface.send_nonempty_train_in_depot_alert = send_nonempty_train_in_depot_alert interface.send_stuck_train_alert = send_stuck_train_alert ------------------------------------------------------------------- ---[[helper functions]] ------------------------------------------------------------------- ---NOTE: the policy of cybersyn is to give modders access to as much of the raw data of the mod as possible. Factorio only allows me to return copies of the original data rather than the actual thing, which sucks. The unsafe api has some tools to help you bypass this limitation. - -function interface.get_mod_settings() - return mod_settings -end ----@param key string -function interface.read_setting(key) - return mod_settings[key] -end ----@param ... string|uint -function interface.read_global(...) - --this can read anything off of cybersyn's map_data - --so interface.read_global("trains", 31415, "manifest") == global.trains[31415].manifest (or nil if train 31415 does not exist) - local base = global - local depth = 0 - for i, v in ipairs({...}) do - depth = i - base = base[v] - if not base then break end - end - return base, depth -end ----@param id uint -function interface.get_station(id) - return global.stations[id] -end ----@param id uint -function interface.get_depot(id) - return global.depots[id] -end ----@param id uint -function interface.get_train(id) - return global.trains[id] -end ----@param train_entity LuaTrain -function interface.get_train_id_from_luatrain(train_entity) - return train_entity.id -end ----@param stop LuaEntity -function interface.get_station_or_depot_id_from_stop(stop) - return stop.unit_number -end ----@param comb LuaEntity -function interface.get_station_or_depot_id_from_comb(comb) - local stop = global.to_stop[comb.unit_number] - if stop then - return stop.unit_number - end -end - remote.add_interface("cybersyn", interface) diff --git a/cybersyn/scripts/train-events.lua b/cybersyn/scripts/train-events.lua index d904e78..745304a 100644 --- a/cybersyn/scripts/train-events.lua +++ b/cybersyn/scripts/train-events.lua @@ -147,7 +147,8 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity) local train = map_data.trains[train_id] if train then if train.status == STATUS_TO_D then - elseif train.status == STATUS_TO_D_BYPASS then + elseif train.status == STATUS_TO_D_BYPASS or train.status == STATUS_D then + --shouldn't be possible to get train.status == STATUS_D remove_available_train(map_data, train_id, train) elseif mod_settings.react_to_train_early_to_depot then if train.manifest then @@ -158,9 +159,10 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity) return end if is_train_empty 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) - interface_raise_train_parked_at_depot(train_id, depot_id) + 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 @@ -217,6 +219,7 @@ local function on_train_arrives_station(map_data, station_id, train_id, train) local station = map_data.stations[station_id] set_comb1(map_data, station, train.manifest, 1) set_p_wagon_combs(map_data, station, train) + interface_raise_train_status_changed(train_id, STATUS_TO_P, STATUS_P) end elseif train.status == STATUS_TO_R then if train.r_station_id == station_id then @@ -224,6 +227,7 @@ local function on_train_arrives_station(map_data, station_id, train_id, train) local station = map_data.stations[station_id] set_comb1(map_data, station, train.manifest, -1) set_r_wagon_combs(map_data, station, train) + interface_raise_train_status_changed(train_id, STATUS_TO_R, STATUS_R) end elseif train.status == STATUS_P and train.p_station_id == station_id then --this is player intervention that is considered valid @@ -251,6 +255,7 @@ local function on_train_arrives_refueler(map_data, refueler_id, train_id, train) local refueler = map_data.refuelers[refueler_id] train.status = STATUS_F set_refueler_combs(map_data, refueler, train) + interface_raise_train_status_changed(train_id, STATUS_TO_F, STATUS_F) end end @@ -277,7 +282,7 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train) end end end - interface_raise_train_completed_provide(train_id) + interface_raise_train_status_changed(train_id, STATUS_P, STATUS_TO_R) elseif train.status == STATUS_R then local station = map_data.stations[train.r_station_id] remove_manifest(map_data, station, train.manifest, -1) @@ -311,12 +316,16 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train) if mod_settings.depot_bypass_threshold < 1 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 elseif fuel_fill/total_slots > mod_settings.depot_bypass_threshold 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 else - local refuelers = map_data.to_refueler[train.network_name] + local refuelers = map_data.to_refuelers[train.network_name] if refuelers then local best_refueler_id = nil local best_dist = INF @@ -344,14 +353,14 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train) local refueler = map_data.refuelers[best_refueler_id] refueler.trains_total = refueler.trains_total + 1 add_refueler_schedule(train.entity, refueler.entity_stop) + interface_raise_train_status_changed(train_id, STATUS_R, STATUS_TO_F) + return end end end - if train.status == STATUS_R then - --the train has not qualified for depot bypass nor refueling - train.status = STATUS_TO_D - end - interface_raise_train_completed_request(train_id) + --the train has not qualified for depot bypass nor refueling + train.status = STATUS_TO_D + interface_raise_train_status_changed(train_id, STATUS_R, STATUS_TO_D) elseif train.status == STATUS_F then local refueler = map_data.refuelers[train.refueler_id] train.status = STATUS_TO_D_BYPASS @@ -360,6 +369,7 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train) add_available_train(map_data, train_id, train) unset_wagon_combs(map_data, refueler) set_combinator_output(map_data, refueler.entity_comb, nil) + interface_raise_train_status_changed(train_id, STATUS_F, STATUS_TO_D_BYPASS) elseif train.status == STATUS_D then --The train is leaving the depot without a manifest, the player likely intervened local depot = map_data.depots[train.parked_at_depot_id--[[@as uint]]]