mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-10 14:08:16 -06:00
improved the modding interface
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]]]
|
||||
|
||||
Reference in New Issue
Block a user