improved modding interface

This commit is contained in:
Monica Moniot
2022-12-03 13:03:33 -05:00
parent 7ef59f00ff
commit b3442920ff
8 changed files with 183 additions and 142 deletions

2
TODO
View File

@@ -4,7 +4,7 @@ bugs:
major:
do hardcore testing
models & art
add a modding interface (the moment someone asks for this I will make sure it's in the next update)
add a refueling option on depots
minor:
railloader compat

View File

@@ -212,9 +212,9 @@ function send_train_between(map_data, r_station_id, p_station_id, train_id, prim
r_station.display_state = 2
update_display(map_data, r_station)
end
interface_raise_train_dispatched(map_data, train_id)
interface_raise_train_dispatched(train_id)
else
interface_raise_train_dispatch_failed(map_data, train_id)
interface_raise_train_dispatch_failed(train_id)
end
end
@@ -341,8 +341,8 @@ local function tick_dispatch(map_data, mod_settings)
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
send_missing_train_alert_for_stops(r_station.entity_stop, stations[p_stations[best_i]].entity_stop)
if can_be_serviced and mod_settings.missing_train_alert_enabled then
send_missing_train_alert(r_station.entity_stop, stations[p_stations[best_i]].entity_stop)
end
if r_station.display_state%2 == 0 then
r_station.display_state = r_station.display_state + 1
@@ -471,8 +471,10 @@ local function tick_poll_train(map_data, mod_settings)
tick_data.last_train = train_id
if train and train.manifest and not train.se_is_being_teleported and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
send_stuck_train_alert(train.entity, train.depot_name)
interface_raise_train_stuck(map_data, train_id)
if mod_settings.stuck_train_alert_enabled then
send_stuck_train_alert(train.entity, train.depot_name)
end
interface_raise_train_stuck(train_id)
end
end
---@param map_data MapData
@@ -506,7 +508,7 @@ function tick(map_data, mod_settings)
end
end
map_data.tick_state = STATE_POLL_STATIONS
interface_raise_tick_init(map_data)
interface_raise_tick_init()
tick_poll_train(map_data, mod_settings)
tick_poll_comb(map_data)
end

View File

@@ -34,6 +34,7 @@ STATUS_P = 2
STATUS_P_TO_R = 3
STATUS_R = 4
STATUS_R_TO_D = 5
STATUS_CUSTOM = 256 --this status and any status greater than it can be used by other mods (I've reserved the lower integers for myself in case I want to add more statuses)
LONGEST_INSERTER_REACH = 2

View File

@@ -397,7 +397,7 @@ end
local send_missing_train_alert_for_stop_icon = {name = MISSING_TRAIN_NAME, type = "fluid"}
---@param r_stop LuaEntity
---@param p_stop LuaEntity
function send_missing_train_alert_for_stops(r_stop, p_stop)
function send_missing_train_alert(r_stop, p_stop)
for _, player in pairs(r_stop.force.players) do
player.add_custom_alert(
r_stop,

View File

@@ -12,7 +12,7 @@
---@field public depots {[uint]: Depot}
---@field public trains {[uint]: Train}
---@field public available_trains {[string]: {[uint]: true?}} --{[network_name]: {[train_id]: depot_id}}
---@field public layouts {[uint]: int[]}
---@field public layouts {[uint]: (0|1|2)[]}
---@field public layout_train_count {[uint]: int}
---@field public tick_state uint
---@field public tick_data {}
@@ -36,7 +36,7 @@
---@field public wagon_combs {[int]: LuaEntity}?--NOTE: allowed to be invalid entities or combinators with the wrong operation, these must be checked and lazy deleted when found
---@field public deliveries {[string]: int}
---@field public accepted_layouts {[uint]: true?}
---@field public layout_pattern {[uint]: int}
---@field public layout_pattern (0|1|2|3)[]?
---@field public tick_signals {[uint]: Signal}? --transient
---@field public p_count_or_r_threshold_per_item {[string]: int} --transient
---@field public display_state 0|1|2|3 --low bit is if this station's request has failed, high bit is if a train is heading to this station
@@ -68,8 +68,11 @@
---@field public se_awaiting_removal any? --se only
---@field public se_awaiting_rename any? --se only
---@alias Manifest {}[]
---@alias cybersyn.global MapData
---@alias Manifest ManifestEntry[]
---@class ManifestEntry
---@field public type string
---@field public name string
---@field public count uint
---@class Economy
---could contain invalid stations or stations with modified settings from when they were first appended
@@ -77,6 +80,7 @@
---@field public all_p_stations {[string]: uint[]} --{[network_name:item_name]: station_id}
---@field public all_names (string|SignalID)[]
--NOTE: any setting labeled as an interface setting can only be changed through the remote-interface, these settings are not save and have to be set at initialization
---@class CybersynModSettings
---@field public tps double
---@field public update_rate int
@@ -85,7 +89,13 @@
---@field public warmup_time double
---@field public stuck_train_time double
---@field public depot_bypass_threshold double
---@field public missing_train_alert_enabled boolean --interface setting
---@field public stuck_train_alert_enabled boolean --interface setting
---@field public react_to_nonempty_train_in_depot boolean --interface setting
---@field public react_to_train_at_incorrect_station boolean --interface setting
---@field public react_to_train_early_to_depot boolean --interface setting
---@alias cybersyn.global MapData
---@type CybersynModSettings
mod_settings = {}

View File

@@ -28,8 +28,9 @@ local function irpairs(a)
return iterr, a, 0
end
local function is_layout_accepted(layout_pattern, layout)
---@param layout_pattern (0|1|2|3)[]
---@param layout (0|1|2)[]
function is_layout_accepted(layout_pattern, layout)
local valid = true
for i, v in ipairs(layout) do
local p = layout_pattern[i] or 0
@@ -59,25 +60,14 @@ function remove_train(map_data, train_id, train)
depot.available_train_id = nil
end
remove_available_train(map_data, train_id, train)
local layout_id = train.layout_id
local count = map_data.layout_train_count[layout_id]
if count <= 1 then
map_data.layout_train_count[layout_id] = nil
map_data.layouts[layout_id] = nil
for station_id, station in pairs(map_data.stations) do
station.accepted_layouts[layout_id] = nil
end
else
map_data.layout_train_count[layout_id] = count - 1
end
map_data.trains[train_id] = nil
interface_raise_train_removed(map_data, train_id, train)
interface_raise_train_removed(train_id, train)
end
---@param map_data MapData
---@param train Train
function update_train_layout(map_data, train)
function set_train_layout(map_data, train)
local carriages = train.entity.carriages
local layout = {}
local i = 1
@@ -186,7 +176,7 @@ function set_p_wagon_combs(map_data, station, train)
while item_slots_capacity > 0 do
local do_inc = false
if item.type == "item" then
local stack_size = game.item_prototypes[item.name].stack_size
local stack_size = get_stack_size(map_data, item.name)
local item_slots = ceil(item_count/stack_size)
local i = #signals + 1
local slots_to_filter

View File

@@ -28,9 +28,10 @@ end
---@param train_id uint
---@param train Train
function on_failed_delivery(map_data, train_id, train)
--NOTE: must change train status to STATUS_D or remove it from tracked trains after this call
local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P
if not is_p_delivery_made then
--NOTE: must either change this train's status or remove it after this call
local is_p_in_progress = train.status == STATUS_D_TO_P or train.status == STATUS_P
local is_r_in_progress = is_p_in_progress or train.status == STATUS_P_TO_R or train.status == STATUS_R
if is_p_in_progress then
local station = map_data.stations[train.p_station_id]
remove_manifest(map_data, station, train.manifest, 1)
if train.status == STATUS_P then
@@ -38,8 +39,7 @@ function on_failed_delivery(map_data, train_id, train)
unset_wagon_combs(map_data, station)
end
end
local is_r_delivery_made = train.status == STATUS_R_TO_D
if not is_r_delivery_made then
if is_r_in_progress then
local station = map_data.stations[train.r_station_id]
remove_manifest(map_data, station, train.manifest, -1)
if train.status == STATUS_R then
@@ -47,10 +47,10 @@ function on_failed_delivery(map_data, train_id, train)
unset_wagon_combs(map_data, station)
end
end
interface_raise_train_failed_delivery(train_id, is_p_in_progress, is_r_in_progress)
train.r_station_id = 0
train.p_station_id = 0
train.manifest = nil
interface_raise_train_failed_delivery(map_data, train_id, is_p_delivery_made, is_r_delivery_made)
end
@@ -68,7 +68,7 @@ function add_available_train(map_data, train_id, train)
end
network[train_id] = true
train.is_available = true
interface_raise_train_available(map_data, train_id)
interface_raise_train_available(train_id)
end
end
---@param map_data MapData
@@ -113,7 +113,7 @@ function add_available_train_to_depot(map_data, mod_settings, train_id, train, d
end
end
end
interface_raise_train_available(map_data, train_id)
interface_raise_train_available(train_id)
end
end
---@param map_data MapData
@@ -146,7 +146,7 @@ local function on_depot_built(map_data, stop, comb)
}
local depot_id = stop.unit_number--[[@as uint]]
map_data.depots[depot_id] = depot
interface_raise_depot_created(map_data, depot_id)
interface_raise_depot_created(depot_id)
end
---@param map_data MapData
@@ -161,7 +161,7 @@ local function on_depot_broken(map_data, depot)
end
local depot_id = depot.entity_stop.unit_number--[[@as uint]]
map_data.depots[depot_id] = nil
interface_raise_depot_removed(map_data, depot_id, depot)
interface_raise_depot_removed(depot_id, depot)
end
---@param map_data MapData
@@ -198,7 +198,7 @@ local function on_station_built(map_data, stop, comb1, comb2)
map_data.warmup_station_ids[#map_data.warmup_station_ids + 1] = id
update_station_if_auto(map_data, station, nil)
interface_raise_station_created(map_data, id)
interface_raise_station_created(id)
end
---@param map_data MapData
---@param station_id uint
@@ -210,9 +210,10 @@ local function on_station_broken(map_data, station_id, station)
local is_r = train.r_station_id == station_id
local is_p = train.p_station_id == station_id
if is_p or is_r then
local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P
local is_r_delivery_made = train.status == STATUS_R_TO_D
if (is_r and not is_r_delivery_made) or (is_p and not is_p_delivery_made) then
local is_p_in_progress = train.status == STATUS_D_TO_P or train.status == STATUS_P
local is_r_in_progress = is_p_in_progress or train.status == STATUS_P_TO_R or train.status == STATUS_R
if (is_p and is_p_in_progress) or (is_r and is_r_in_progress) then
--train is attempting delivery to a stop that was destroyed, stop it
on_failed_delivery(map_data, train_id, train)
if not train.se_is_being_teleported then
@@ -227,7 +228,7 @@ local function on_station_broken(map_data, station_id, station)
end
end
map_data.stations[station_id] = nil
interface_raise_station_removed(map_data, station_id, station)
interface_raise_station_removed(station_id, station)
end
---@param map_data MapData
@@ -461,7 +462,7 @@ function combinator_update(map_data, comb)
--NOTE: This is rather dangerous, we may need to actually implement operation changing
on_combinator_broken(map_data, comb)
on_combinator_built(map_data, comb)
interface_raise_combinator_changed(map_data, comb, old_params)
interface_raise_combinator_changed(comb, old_params)
return
end
end
@@ -491,7 +492,7 @@ function combinator_update(map_data, comb)
end
if has_changed then
map_data.to_comb_params[unit_number] = params
interface_raise_combinator_changed(map_data, comb, old_params)
interface_raise_combinator_changed(comb, old_params)
end
end
@@ -568,16 +569,16 @@ local function on_station_rename(map_data, stop, old_name)
local is_p = train.p_station_id == station_id
local is_r = train.r_station_id == station_id
if is_p or is_r then
local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P
local is_r_delivery_made = train.status == STATUS_R_TO_D
if is_r and not is_r_delivery_made then
local is_p_in_progress = train.status == STATUS_D_TO_P or train.status == STATUS_P
local is_r_in_progress = is_p_in_progress or train.status == STATUS_P_TO_R or train.status == STATUS_R
if is_r and is_r_in_progress then
local r_station = map_data.stations[train.r_station_id]
if not train.se_is_being_teleported then
rename_manifest_schedule(train.entity, r_station.entity_stop, old_name)
else
train.se_awaiting_rename = {r_station.entity_stop, old_name}
end
elseif is_p and not is_p_delivery_made then
elseif is_p and is_p_in_progress then
--train is attempting delivery to a stop that was renamed
local p_station = map_data.stations[train.p_station_id]
if not train.se_is_being_teleported then
@@ -627,30 +628,34 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
train.p_station_id = 0
train.r_station_id = 0
train.manifest = nil
else
elseif mod_settings.react_to_train_early_to_depot then
on_failed_delivery(map_data, train_id, train)
send_unexpected_train_alert(train.entity)
else
return
end
end
if is_train_empty then
remove_available_train(map_data, train_id, train)
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(map_data, train_id, depot_id)
interface_raise_train_parked_at_depot(train_id, depot_id)
else
--train still has cargo
lock_train(train_entity)
remove_train(map_data, train_id, train)
send_nonempty_train_in_depot_alert(train_entity)
interface_raise_train_nonempty_in_depot(map_data, depot_id, train_entity, train_id)
if mod_settings.react_to_nonempty_train_in_depot then
lock_train(train_entity)
remove_train(map_data, train_id, train)
send_nonempty_train_in_depot_alert(train_entity)
end
interface_raise_train_nonempty_in_depot(depot_id, train_entity, train_id)
end
elseif is_train_empty then
--NOTE: only place where new Train
train = {
entity = train_entity,
--layout_id = update_train_layout,
--item_slot_capacity = update_train_layout,
--fluid_capacity = update_train_layout,
--layout_id = set_train_layout,
--item_slot_capacity = set_train_layout,
--fluid_capacity = set_train_layout,
--status = add_available_train_to_depot,
p_station_id = 0,
r_station_id = 0,
@@ -664,16 +669,18 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
--network_flag = add_available_train_to_depot,
--priority = add_available_train_to_depot,
}
update_train_layout(map_data, train)
set_train_layout(map_data, train)
map_data.trains[train_id] = train
add_available_train_to_depot(map_data, mod_settings, train_id, train, depot_id, map_data.depots[depot_id])
set_depot_schedule(train_entity, train.depot_name)
interface_raise_train_created(map_data, train_id, depot_id)
interface_raise_train_created(train_id, depot_id)
else
lock_train(train_entity)
send_nonempty_train_in_depot_alert(train_entity)
interface_raise_train_nonempty_in_depot(map_data, depot_id, train_entity)
if mod_settings.react_to_nonempty_train_in_depot then
lock_train(train_entity)
send_nonempty_train_in_depot_alert(train_entity)
end
interface_raise_train_nonempty_in_depot(depot_id, train_entity)
end
end
---@param map_data MapData
@@ -702,15 +709,16 @@ local function on_train_arrives_buffer(map_data, stop, train_id, train)
--this player intervention that is considered valid
elseif (train.status == STATUS_R or train.status == STATUS_R_TO_D) and train.r_station_id == station_id then
--this player intervention that is considered valid
else
elseif mod_settings.react_to_train_at_incorrect_station then
on_failed_delivery(map_data, train_id, train)
remove_train(map_data, train_id, train)
lock_train(train.entity)
send_lost_train_alert(train.entity, train.depot_name)
end
else
elseif mod_settings.react_to_train_at_incorrect_station then
--train is lost somehow, probably from player intervention
remove_train(map_data, train_id, train)
send_lost_train_alert(train.entity, train.depot_name)
end
end
---@param map_data MapData
@@ -737,7 +745,7 @@ local function on_train_leaves_station(map_data, mod_settings, train_id, train)
end
end
end
interface_raise_train_completed_provide(map_data, train_id)
interface_raise_train_completed_provide(train_id)
elseif train.status == STATUS_R then
train.status = STATUS_R_TO_D
local station = map_data.stations[train.r_station_id]
@@ -771,13 +779,13 @@ local function on_train_leaves_station(map_data, mod_settings, train_id, train)
elseif fuel_fill/total_slots > mod_settings.depot_bypass_threshold then
add_available_train(map_data, train_id, train)
end
interface_raise_train_completed_request(map_data, train_id)
interface_raise_train_completed_request(train_id)
end
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]]]
send_lost_train_alert(train.entity, depot.entity_stop.backer_name)
remove_train(map_data, train_id, train)
send_lost_train_alert(train.entity, depot.entity_stop.backer_name)
end
end
@@ -962,6 +970,12 @@ local function main()
mod_settings.warmup_time = settings.global["cybersyn-warmup-time"].value--[[@as double]]
mod_settings.stuck_train_time = settings.global["cybersyn-stuck-train-time"].value--[[@as double]]
mod_settings.missing_train_alert_enabled = true
mod_settings.stuck_train_alert_enabled = true
mod_settings.react_to_nonempty_train_in_depot = true
mod_settings.react_to_train_at_incorrect_station = true
mod_settings.react_to_train_early_to_depot = true
--NOTE: There is a concern that it is possible to build or destroy important entities without one of these events being triggered, in which case the mod will have undefined behavior
flib_event.register(defines.events.on_built_entity, on_built, filter_built)
flib_event.register(defines.events.on_robot_built_entity, on_built, filter_built)
@@ -1020,7 +1034,7 @@ local function main()
--NOTE: IMPORTANT, until se_on_train_teleport_finished_event is called map_data.trains[old_id] will reference an invalid train entity; our events have either been set up to account for this or should be impossible to trigger until teleportation is finished
train.se_is_being_teleported = true
map_data.se_tele_old_id[train_unique_identifier] = old_id
interface_raise_train_teleport_started(map_data, old_id)
interface_raise_train_teleport_started(old_id)
end)
flib_event.register(se_on_train_teleport_finished_event, function(event)
---@type MapData
@@ -1086,7 +1100,7 @@ local function main()
end
train_entity.schedule = schedule
end
interface_raise_train_teleported(map_data, new_id, old_id)
interface_raise_train_teleported(new_id, old_id)
end)
end)
end

View File

@@ -28,107 +28,89 @@ local on_train_teleported = nil
local on_train_stuck = nil
local on_tick_init = nil
---@param map_data MapData
---@param entity LuaEntity
---@param old_parameters ArithmeticCombinatorParameters
function interface_raise_combinator_changed(map_data, entity, old_parameters)
function interface_raise_combinator_changed(entity, old_parameters)
if on_combinator_changed then
raise_event(on_combinator_changed, {
map_data = map_data,
entity = entity,
old_parameters = old_parameters,
})
end
end
---@param map_data MapData
---@param station_id uint
function interface_raise_station_created(map_data, station_id)
function interface_raise_station_created(station_id)
if on_station_created then
raise_event(on_station_created, {
map_data = map_data,
station_id = station_id,
})
end
end
---@param map_data MapData
---@param old_station_id uint
---@param old_station Station
function interface_raise_station_removed(map_data, old_station_id, old_station)
function interface_raise_station_removed(old_station_id, old_station)
if on_station_removed then
raise_event(on_station_removed, {
map_data = map_data,
old_station_id = old_station_id, --this id is now invalid
old_station = old_station, --this is the data that used to be stored at the old id
})
end
end
---@param map_data MapData
---@param depot_id uint
function interface_raise_depot_created(map_data, depot_id)
function interface_raise_depot_created(depot_id)
if on_depot_created then
raise_event(on_depot_created, {
map_data = map_data,
depot_id = depot_id,
})
end
end
---@param map_data MapData
---@param old_depot_id uint
---@param old_depot Depot
function interface_raise_depot_removed(map_data, old_depot_id, old_depot)
function interface_raise_depot_removed(old_depot_id, old_depot)
if on_depot_removed then
raise_event(on_depot_removed, {
map_data = map_data,
old_depot_id = old_depot_id, --this id is now invalid
old_depot = old_depot, --this is the data that used to be stored at the old id
})
end
end
---@param map_data MapData
---@param train_id uint
---@param depot_id uint
function interface_raise_train_created(map_data, train_id, depot_id)
function interface_raise_train_created(train_id, depot_id)
if on_train_created then
raise_event(on_train_created, {
map_data = map_data,
train_id = train_id,
depot_id = depot_id,
})
end
end
---@param map_data MapData
---@param old_train_id uint
---@param old_train Train
function interface_raise_train_removed(map_data, old_train_id, old_train)
function interface_raise_train_removed(old_train_id, old_train)
if on_train_removed then
raise_event(on_train_removed, {
map_data = map_data,
old_train_id = old_train_id, --this id is now invalid
old_train = old_train, --this is the data that used to be stored at the old id
})
end
end
---@param map_data MapData
---@param train_id uint
function interface_raise_train_available(map_data, train_id)
function interface_raise_train_available(train_id)
if on_train_available then
raise_event(on_train_available, {
map_data = map_data,
train_id = train_id,
})
end
end
---@param map_data MapData
---@param depot_id uint
---@param train_entity LuaTrain
---@param train_id uint?
function interface_raise_train_nonempty_in_depot(map_data, depot_id, train_entity, train_id)
function interface_raise_train_nonempty_in_depot(depot_id, train_entity, train_id)
if on_train_nonempty_in_depot then
raise_event(on_train_nonempty_in_depot, {
map_data = map_data,
train_entity = train_entity,
train_id = train_id,
depot_id = depot_id,
@@ -136,110 +118,90 @@ function interface_raise_train_nonempty_in_depot(map_data, depot_id, train_entit
end
end
---@param map_data MapData
---@param train_id uint
function interface_raise_train_dispatched(map_data, train_id)
function interface_raise_train_dispatched(train_id)
if on_train_dispatched then
raise_event(on_train_dispatched, {
map_data = map_data,
train_id = train_id,
})
end
end
---@param map_data MapData
---@param train_id uint
function interface_raise_train_dispatch_failed(map_data, train_id)
function interface_raise_train_dispatch_failed(train_id)
if on_train_dispatch_failed then
raise_event(on_train_dispatch_failed, {
map_data = map_data,
train_id = train_id,
})
end
end
---@param map_data MapData
---@param train_id uint
---@param is_p_delivery_made boolean
---@param is_r_delivery_made boolean
function interface_raise_train_failed_delivery(map_data, train_id, is_p_delivery_made, is_r_delivery_made)
---@param was_p_in_progress boolean
---@param was_r_in_progress boolean
function interface_raise_train_failed_delivery(train_id, was_p_in_progress, was_r_in_progress)
if on_train_failed_delivery then
raise_event(on_train_failed_delivery, {
map_data = map_data,
train_id = train_id,
is_p_delivery_made = is_p_delivery_made,
is_r_delivery_made = is_r_delivery_made,
was_p_in_progress = was_p_in_progress,
was_r_in_progress = was_r_in_progress,
})
end
end
---@param map_data MapData
---@param train_id uint
function interface_raise_train_completed_provide(map_data, train_id)
function interface_raise_train_completed_provide(train_id)
if on_train_completed_provide then
raise_event(on_train_completed_provide, {
map_data = map_data,
train_id = train_id,
})
end
end
---@param map_data MapData
---@param train_id uint
function interface_raise_train_completed_request(map_data, train_id)
function interface_raise_train_completed_request(train_id)
if on_train_completed_request then
raise_event(on_train_completed_request, {
map_data = map_data,
train_id = train_id,
})
end
end
---@param map_data MapData
---@param train_id uint
---@param depot_id uint
function interface_raise_train_parked_at_depot(map_data, train_id, depot_id)
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, {
map_data = map_data,
train_id = train_id,
depot_id = depot_id,
})
end
end
---@param map_data MapData
---@param train_id uint
function interface_raise_train_stuck(map_data, train_id)
function interface_raise_train_stuck(train_id)
if on_train_stuck then
raise_event(on_train_stuck, {
map_data = map_data,
train_id = train_id,
})
end
end
---@param map_data MapData
---@param old_train_id uint
function interface_raise_train_teleport_started(map_data, old_train_id)
function interface_raise_train_teleport_started(old_train_id)
if on_train_teleport_started then
raise_event(on_train_teleport_started, {
map_data = map_data,
old_train_id = old_train_id,--this id is currently valid but will become valid just before on_train_teleported is raised
})
end
end
---@param map_data MapData
---@param new_train_id uint
---@param old_train_id uint
function interface_raise_train_teleported(map_data, new_train_id, old_train_id)
function interface_raise_train_teleported(new_train_id, old_train_id)
if on_train_teleported then
raise_event(on_train_teleported, {
map_data = map_data,
new_train_id = new_train_id,--this id stores the train
old_train_id = old_train_id,--this id is now invalid
})
end
end
---@param map_data MapData
function interface_raise_tick_init(map_data)
function interface_raise_tick_init()
if on_tick_init then
raise_event(on_tick_init, {
map_data = map_data,
})
end
end
@@ -330,14 +292,63 @@ end
------------------------------------------------------------------
--[[internal API access]]
--[[safe API]]
------------------------------------------------------------------
--NOTE: The following, while they can be called from outside the mod safely, can cause serious longterm damage if they are given bad parameters. Extercise caution.
--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 comb LuaEntity
function interface.combinator_update(comb)
combinator_update(global, comb)
end
---@param train_id uint
function interface.update_train_layout(train_id)
local train = global.trains[train_id]
assert(train)
local old_layout_id = train.layout_id
local count = global.layout_train_count[old_layout_id]
if count <= 1 then
global.layout_train_count[old_layout_id] = nil
global.layouts[old_layout_id] = nil
for station_id, station in pairs(global.stations) do
station.accepted_layouts[old_layout_id] = nil
end
else
global.layout_train_count[old_layout_id] = count - 1
end
set_train_layout(global, train)
end
---@param layout_pattern (0|1|2|3)[]
---@param layout (0|1|2)[]
function interface.is_layout_accepted(layout_pattern, layout)
return is_layout_accepted(layout_pattern, layout)
end
---@param station_id uint
---@param forbidden_entity LuaEntity?
---@param force_update boolean?
function interface.reset_station_layout(station_id, forbidden_entity, force_update)
local station = global.stations[station_id]
assert(station)
if force_update or not station.allows_all_trains then
reset_station_layout(global, station, forbidden_entity)
end
end
---@param rail LuaEntity
---@param forbidden_entity LuaEntity?
---@param force_update boolean?
function interface.update_station_from_rail(rail, forbidden_entity, force_update)
update_station_from_rail(global, rail, forbidden_entity, force_update)
end
------------------------------------------------------------------
--[[unsafe API]]
------------------------------------------------------------------
--NOTE: The following functions can cause serious longterm damage to someone's world if they are given bad parameters. Use caution.
---@param station_id Station
---@param manifest Manifest
---@param sign -1|1
function interface.remove_manifest(station_id, manifest, sign)
function interface.remove_manifest_from_station_deliveries(station_id, manifest, sign)
local station = global.stations[station_id]
assert(station)
remove_manifest(global, station, manifest, sign)
@@ -346,17 +357,23 @@ end
---@param p_station_id uint
---@param train_id uint
---@param primary_item_name string?
function interface.send_train_between(r_station_id, p_station_id, train_id, primary_item_name)
function interface.create_new_delivery_between_stations(r_station_id, p_station_id, train_id, primary_item_name)
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)
end
---@param train_id uint
function interface.failed_delivery(train_id)
function interface.fail_delivery(train_id)
local train = global.trains[train_id]
assert(train)
on_failed_delivery(global, train_id, train)
end
---@param train_id uint
function interface.remove_train(train_id)
local train = global.trains[train_id]
assert(train)
remove_train(global, train_id, train)
end
---@param train_id uint
function interface.add_available_train(train_id)
@@ -378,16 +395,23 @@ function interface.remove_available_train(train_id)
assert(train)
remove_available_train(global, train_id, train)
end
---@param comb LuaEntity
function interface.combinator_update(comb)
combinator_update(global, comb)
end
------------------------------------------------------------------
--[[alerts]]
------------------------------------------------------------------
interface.send_missing_train_alert = send_missing_train_alert
interface.send_lost_train_alert = send_lost_train_alert
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 the raw data of the mod, please either treat all tables returned from the modding interface as "read only", or if you do modify them take responsibility that your modification does not result in an error occuring in cybersyn later on.
--NOTE: the follow functions are unnecessary, the are provided more as a guide how the mod api works rather than as practical functions.
--NOTE: the follow functions aren't strictly necessary; they are provided more as a guide how the mod api works rather than as practical functions.
function interface.get_map_data()
return global