269 lines
10 KiB
Lua
269 lines
10 KiB
Lua
--[[ Copyright (c) 2017 Optera
|
|
* Part of Logistics Train Network
|
|
*
|
|
* See LICENSE.md in the project directory for license information.
|
|
--]]
|
|
|
|
on_stops_updated_event = script.generate_event_name()
|
|
on_dispatcher_updated_event = script.generate_event_name()
|
|
on_dispatcher_no_train_found_event = script.generate_event_name()
|
|
on_delivery_created_event = script.generate_event_name()
|
|
on_delivery_pickup_complete_event = script.generate_event_name()
|
|
on_delivery_completed_event = script.generate_event_name()
|
|
on_delivery_failed_event = script.generate_event_name()
|
|
|
|
on_provider_missing_cargo_alert = script.generate_event_name()
|
|
on_provider_unscheduled_cargo_alert = script.generate_event_name()
|
|
on_requester_unscheduled_cargo_alert = script.generate_event_name()
|
|
on_requester_remaining_cargo_alert = script.generate_event_name()
|
|
|
|
-- ltn_interface allows mods to register for update events
|
|
remote.add_interface("logistic-train-network", {
|
|
-- updates for ltn_stops
|
|
on_stops_updated = function() return on_stops_updated_event end,
|
|
|
|
-- updates for dispatcher
|
|
on_dispatcher_updated = function() return on_dispatcher_updated_event end,
|
|
on_dispatcher_no_train_found = function() return on_dispatcher_no_train_found_event end,
|
|
on_delivery_created = function() return on_delivery_created_event end,
|
|
|
|
-- update for updated deliveries after leaving provider
|
|
on_delivery_pickup_complete = function() return on_delivery_pickup_complete_event end,
|
|
|
|
-- update for completing deliveries
|
|
on_delivery_completed = function() return on_delivery_completed_event end,
|
|
on_delivery_failed = function() return on_delivery_failed_event end,
|
|
|
|
-- alerts
|
|
on_provider_missing_cargo = function() return on_provider_missing_cargo_alert end,
|
|
on_provider_unscheduled_cargo = function() return on_provider_unscheduled_cargo_alert end,
|
|
on_requester_unscheduled_cargo = function() return on_requester_unscheduled_cargo_alert end,
|
|
on_requester_remaining_cargo = function() return on_requester_remaining_cargo_alert end,
|
|
|
|
-- surface connections
|
|
connect_surfaces = ConnectSurfaces, -- function(entity1 :: LuaEntity, entity2 :: LuaEntity, network_id :: int32)
|
|
disconnect_surfaces = DisconnectSurfaces, -- function(entity1 :: LuaEntity, entity2 :: LuaEntity)
|
|
clear_all_surface_connections = ClearAllSurfaceConnections,
|
|
|
|
-- Re-assigns a delivery to a different train.
|
|
reassign_delivery = ReassignDelivery, -- function(old_train_id :: uint, new_train :: LuaTrain) :: bool
|
|
get_or_create_next_temp_stop = GetOrCreateNextTempStop, -- function(train :: LuaTrain, schedule_index :: uint?) :: uint
|
|
get_next_logistic_stop = GetNextLogisticStop, -- function(train :: LuaTrain, schedule_index :: uint?) :: uint?, uint?, string?
|
|
})
|
|
|
|
|
|
--[[ register events from LTN:
|
|
if remote.interfaces["logistic-train-network"] then
|
|
script.on_event(remote.call("logistic-train-network", "on_stops_updated"), on_stops_updated)
|
|
script.on_event(remote.call("logistic-train-network", "on_dispatcher_updated"), on_dispatcher_updated)
|
|
end
|
|
]]--
|
|
|
|
|
|
--[[ EVENTS
|
|
on_stops_updated
|
|
Raised every UpdateInterval, after delivery generation
|
|
-> Contains:
|
|
logistic_train_stops = { [stop_id :: uint], {
|
|
-- stop data
|
|
active_deliveries :: int,
|
|
entity :: LuaEntity,
|
|
input :: LuaEntity,
|
|
output :: LuaEntity,
|
|
lamp_control :: LuaEntity,
|
|
error_code :: int,
|
|
|
|
-- control signals
|
|
is_depot :: bool,
|
|
depot_priority :: int32,
|
|
network_id :: int32,
|
|
max_carriages :: int32,
|
|
min_carriages :: int32,
|
|
max_trains :: int32,
|
|
providing_threshold :: int32,
|
|
providing_threshold_stacks :: int32,
|
|
provider_priority :: int32,
|
|
requesting_threshold :: int32,
|
|
requesting_threshold_stacks :: int32,
|
|
requester_priority :: int32,
|
|
locked_slots :: int32,
|
|
no_warnings :: bool,
|
|
|
|
-- parked train data
|
|
parked_train :: LuaTrain,
|
|
parked_train_id :: uint,
|
|
parked_train_faces_stop :: bool,
|
|
}}
|
|
|
|
|
|
on_dispatcher_updated
|
|
Raised every UpdateInterval, after delivery generation
|
|
-> Contains:
|
|
update_interval = int -- time in ticks LTN needed to run all updates, varies depending on number of stops and requests
|
|
provided_by_stop = { [stop_id :: uint], { [item :: string], count :: int } }
|
|
requests_by_stop = { [stop_id :: uint], { [item :: string], count :: int } }
|
|
new_deliveries = { uint } -- train_ids of deliveries created this UpdateInterval
|
|
deliveries = { [train_id :: uint], {
|
|
force :: LuaForce,
|
|
train :: LuaTrain,
|
|
from :: string,
|
|
from_id :: uint,
|
|
to :: string,
|
|
to_id :: uint,
|
|
network_id: int32,
|
|
started :: uint, -- tick this delivery was created on
|
|
surface_connections = { entity1 :: LuaEntity, entity2 :: LuaEntity, network_id :: int32 },
|
|
shipment = { [item :: string], count :: int }
|
|
} }
|
|
available_trains = { [train_id :: uint], {
|
|
capacity :: int,
|
|
fluid_capacity :: int,
|
|
force :: LuaForce,
|
|
surface :: LuaSurface,
|
|
depot_priority :: int32,
|
|
network_id :: int32,
|
|
train :: LuaTrain
|
|
} }
|
|
|
|
|
|
on_dispatcher_no_train_found
|
|
Raised when no train was found to handle a request
|
|
-> Contains:
|
|
to :: string -- requester.backer_name
|
|
to_id :: uint -- requester.unit_number
|
|
network_id :: int32
|
|
(optional) item :: string
|
|
(optional) from :: string
|
|
(optional) from_id :: uint
|
|
(optional) min_carriages :: int32
|
|
(optional) max_carriages :: int32
|
|
(optional) shipment = { [item :: string], count :: int }
|
|
|
|
|
|
on_delivery_pickup_complete
|
|
Raised when a train leaves provider stop
|
|
-> Contains:
|
|
train_id :: uint
|
|
train :: LuaTrain
|
|
planned_shipment= { [item :: string], count :: int }
|
|
actual_shipment = { [item :: string], count :: int } -- shipment updated to train inventory
|
|
|
|
|
|
on_delivery_completed
|
|
Raised when train leaves requester stop
|
|
-> Contains:
|
|
train_id :: uint
|
|
train :: LuaTrain
|
|
shipment= { [item :: string], count :: int }
|
|
|
|
|
|
on_delivery_failed
|
|
Raised when rolling stock of a train gets removed, the delivery timed out, train enters depot stop with active delivery
|
|
-> Contains:
|
|
train_id :: uint
|
|
shipment= { [item :: string], count :: int } }
|
|
|
|
|
|
---- Alerts ----
|
|
|
|
on_dispatcher_no_train_found
|
|
Raised when depot was empty
|
|
-> Contains:
|
|
to :: string
|
|
to_id :: uint
|
|
network_id :: int32
|
|
item :: string -- <type,name>
|
|
|
|
on_dispatcher_no_train_found
|
|
Raised when no matching train was found
|
|
-> Contains:
|
|
to :: string
|
|
to_id :: uint
|
|
network_id :: int32
|
|
from :: string
|
|
from_id :: uint
|
|
min_carriages :: int32
|
|
max_carriages :: int32
|
|
shipment = { [item :: string], count :: int } }
|
|
|
|
on_provider_missing_cargo
|
|
Raised when trains leave provider with less than planned load
|
|
-> Contains:
|
|
train :: LuaTrain
|
|
station :: LuaEntity
|
|
planned_shipment = { [item :: string], count :: int } }
|
|
actual_shipment = { [item :: string], count :: int } }
|
|
|
|
on_provider_unscheduled_cargo
|
|
Raised when trains leave provider with wrong cargo
|
|
-> Contains:
|
|
train :: LuaTrain
|
|
station :: LuaEntity
|
|
planned_shipment = { [item :: string], count :: int } }
|
|
unscheduled_load = { [item :: string], count :: int } }
|
|
|
|
on_requester_unscheduled_cargo
|
|
Raised when trains arrive at requester with wrong cargo
|
|
-> Contains:
|
|
train :: LuaTrain
|
|
station :: LuaEntity
|
|
planned_shipment = { [item :: string], count :: int } }
|
|
unscheduled_load = { [item :: string], count :: int } }
|
|
|
|
on_requester_remaining_cargo
|
|
Raised when trains leave requester with remaining cargo
|
|
-> Contains:
|
|
train :: LuaTrain
|
|
station :: LuaEntity
|
|
remaining_load = { [item :: string], count :: int } }
|
|
|
|
--]]
|
|
|
|
--[[ REMOTE CALLS
|
|
|
|
usage:
|
|
if remote.interfaces["logistic-train-network"] then
|
|
remote.call("logistic-train-network", "<name>", <parameters>?)
|
|
end
|
|
|
|
connect_surfaces(entity1 :: LuaEntity, entity2 :: LuaEntity, network_id :: int32)
|
|
Designates two entities on different surfaces as forming a surface connection.
|
|
Connections are bi-directional but not transitive, i.e. surface A -> B implies B -> A, but A -> B and B -> C does not imply A -> C.
|
|
LTN will generate deliveries between depot and provider on one surface and requester on the other.
|
|
Network_id acts as additional mask for potential providers.
|
|
It is the caller's responsibility to ensure:
|
|
1) trains are moved between surfaces
|
|
2) deliveries are updated to the new train after surface transition, see reassign_delivery()
|
|
3) trains return to their original surface depot
|
|
|
|
disconnect_surfaces(entity1 :: LuaEntity, entity2 :: LuaEntity)
|
|
Removes a surface connection formed by the two given entities.
|
|
Active deliveries will not be affected.
|
|
It's not necessary to call this function when deleting one or both entities.
|
|
|
|
clear_all_surface_connections()
|
|
Clears all surface connections.
|
|
Active deliveries will not be affected
|
|
This function exists for debugging purposes, no event is raised to notify connection owners.
|
|
|
|
reassign_delivery(old_train_id :: uint, new_train :: LuaTrain) :: bool
|
|
Re-assigns a delivery to a different train.
|
|
Should be called after creating a train based on another train, for example after moving a train to a different surface.
|
|
Calls with an old_train_id without delivery have no effect.
|
|
Don't call this function when coupling trains via script, LTN already handles that through Factorio events.
|
|
This function does not add missing temp stops. See get_or_create_next_temp_stop for that.
|
|
|
|
get_or_create_next_temp_stop(train :: LuaTrain, schedule_index :: uint?) :: uint
|
|
Ensures the next logistic stop in the schedule has a temporary stop if it is on the same surface as the train.
|
|
If no schedule_index is given, the search for the next logistic stop starts from train.schedule.current
|
|
In case the train is currently stopping at that index, the search starts at the next higher index.
|
|
The result will be the schedule index of the temp stop of the next logistic stop or nil if there is no further logistic stop.
|
|
|
|
get_next_logistic_stop(train :: LuaTrain, schedule_index :: uint?) :: uint?, uint?, string?
|
|
Finds the next logistic stop in the schedule of the given train.
|
|
If no schedule_index is given, the search starts from train.schedule.current.
|
|
In case the train is currently stopping at that index, the search starts at the next higher index.
|
|
The result will be three values stop_schedule_index, stop_id and either the string "provider" or "requester".
|
|
If there is no further logistic stop in the schedule, the result will be nil.
|
|
|
|
--]] |