134 lines
4.5 KiB
Lua
134 lines
4.5 KiB
Lua
--- Functions for working with trains.
|
|
--- ```lua
|
|
--- local flib_train = require("__flib__/train")
|
|
--- ```
|
|
--- @class flib_train
|
|
local flib_train = {}
|
|
|
|
local table = table
|
|
|
|
--- Get the main locomotive in a given train.
|
|
--- @param train LuaTrain
|
|
--- @return LuaEntity? locomotive The primary locomotive entity or `nil` when no locomotive was found
|
|
function flib_train.get_main_locomotive(train)
|
|
if
|
|
train.valid
|
|
and train.locomotives
|
|
and (#train.locomotives.front_movers > 0 or #train.locomotives.back_movers > 0)
|
|
then
|
|
return train.locomotives.front_movers and train.locomotives.front_movers[1] or train.locomotives.back_movers[1]
|
|
end
|
|
end
|
|
|
|
--- Get the backer_name of the main locomotive in a given train.
|
|
--- @param train LuaTrain
|
|
--- @return string? backer_name The backer_name of the primary locomotive or `nil` when no locomotive was found
|
|
function flib_train.get_backer_name(train)
|
|
local loco = flib_train.get_main_locomotive(train)
|
|
return loco and loco.backer_name
|
|
end
|
|
|
|
--- Rotate a single carriage of a train.
|
|
--- @param entity LuaEntity
|
|
--- @return boolean rotated `true` when rotation was successful.
|
|
function flib_train.rotate_carriage(entity)
|
|
local disconnected_back = entity.disconnect_rolling_stock(defines.rail_direction.back)
|
|
local disconnected_front = entity.disconnect_rolling_stock(defines.rail_direction.front)
|
|
entity.rotate()
|
|
-- Only reconnect the side that was disconnected
|
|
local reconnected_front = disconnected_front
|
|
local reconnected_back = disconnected_back
|
|
if disconnected_back then
|
|
reconnected_back = entity.connect_rolling_stock(defines.rail_direction.front)
|
|
end
|
|
if disconnected_front then
|
|
reconnected_front = entity.connect_rolling_stock(defines.rail_direction.back)
|
|
end
|
|
|
|
if disconnected_front and not reconnected_front then
|
|
return false
|
|
end
|
|
if disconnected_back and not reconnected_back then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
--- Create a string representing train composition, and return a count of locomotives and wagons in the train.
|
|
--- - `<L<`, `>L>`: Locomotives
|
|
--- - `C`: Cargo wagon
|
|
--- - `F`: Fluid wagon
|
|
--- - `A`: Artillery wagon
|
|
--- @param train LuaTrain
|
|
--- @return string? composition The composition string, or `nil` if the train was invalid.
|
|
--- @return TrainCompositionCounts?
|
|
function flib_train.get_composition_string(train)
|
|
if train and train.valid then
|
|
local carriages = train.carriages
|
|
local string_table = {}
|
|
local count_wagons, count_loco_front, count_loco_back, i = 0, 0, 0, 0
|
|
local locos_front = train.locomotives.front_movers
|
|
for _, carriage in pairs(carriages) do
|
|
i = i + 1
|
|
if carriage.type == "locomotive" then
|
|
local faces_forward = false
|
|
for _, loco in pairs(locos_front) do
|
|
if carriage.unit_number == loco.unit_number then
|
|
faces_forward = true
|
|
break
|
|
end
|
|
end
|
|
if faces_forward then
|
|
string_table[i] = "<L<"
|
|
count_loco_front = count_loco_front + 1
|
|
else
|
|
string_table[i] = ">L>"
|
|
count_loco_back = count_loco_back + 1
|
|
end
|
|
elseif carriage.type == "cargo-wagon" then
|
|
count_wagons = count_wagons + 1
|
|
string_table[i] = "C"
|
|
elseif carriage.type == "fluid-wagon" then
|
|
count_wagons = count_wagons + 1
|
|
string_table[i] = "F"
|
|
elseif carriage.type == "artillery-wagon" then
|
|
count_wagons = count_wagons + 1
|
|
string_table[i] = "A"
|
|
else
|
|
count_wagons = count_wagons + 1
|
|
string_table[i] = "?"
|
|
end
|
|
end
|
|
return table.concat(string_table),
|
|
{
|
|
total = i,
|
|
wagons = count_wagons,
|
|
front_movers = count_loco_front,
|
|
back_movers = count_loco_back,
|
|
}
|
|
end
|
|
end
|
|
|
|
--- Open train GUI for one player.
|
|
--- @param player_index number
|
|
--- @param train LuaTrain
|
|
--- @return boolean `true` if the GUI was opened.
|
|
function flib_train.open_gui(player_index, train)
|
|
if train and train.valid and game.players[player_index] then
|
|
local loco = flib_train.get_main_locomotive(train)
|
|
if loco and loco.valid then
|
|
game.players[player_index].opened = loco
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
return flib_train
|
|
|
|
--- @class TrainCompositionCounts
|
|
--- @field total number The total number of rolling stocks in the train.
|
|
--- @field wagons number The number of wagons in the train.
|
|
--- @field front_movers number The number of front-facing locomotives in the train.
|
|
--- @field back_movers number The number of back-facing locomotives in the train.
|