Currently we would need to do some math to get that number:
Code: Select all
--[[
Current fuel consumption of a train's locomotives.
Math (Factorio wiki, "Locomotive" → Speed calculations), per tick:
v1 = max(0, |v| - friction / weight) -- friction
v2 = v1 + a_full -- engines at full power
v3 = v2 * r -- air resistance
v = min(v3, max_speed) -- top speed cap
a_full = (sum of pulling locomotives' max usage in J/tick / 1000) * fuel_acceleration_multiplier / weight
r = 1 - front_air_resistance * 1000 / weight
Locomotives only burn the acceleration they actually use:
a_used = min(a_full, max_speed / r - v1)
fraction = clamp(a_used / a_full, 0, 1)
consumption = max_usage * fraction -- per locomotive, J/tick
Below top speed fraction = 1 (full power). At top speed it drops to
(v * (1 - r) / r + friction / weight) / a_full
Assumes the train is throttling (automatic train on its path, or a player
holding accelerate). Braking, coasting and standing still burn 0.
]]
--- @param train LuaTrain
--- @return table<uint64, double> consumption J/tick per locomotive, keyed by unit_number (0 for locomotives that are not pulling)
--- @return double total J/tick of the whole train
local function get_current_consumption(train)
local consumption = {}
local total = 0
local speed = train.speed
local forward = speed >= 0
local movers = forward and train.locomotives.front_movers or train.locomotives.back_movers
local idle = forward and train.locomotives.back_movers or train.locomotives.front_movers
local front_stock = forward and train.front_stock or train.back_stock
local max_speed = forward and train.max_forward_speed or train.max_backward_speed
local weight = train.weight
for _, locomotive in pairs(idle) do
consumption[locomotive.unit_number] = 0
end
local friction = 0
for _, carriage in pairs(train.carriages) do
friction = friction + carriage.prototype.friction_force
end
local power = 0
local acceleration_multiplier
for _, locomotive in pairs(movers) do
power = power + locomotive.prototype.get_max_energy_usage(locomotive.quality)
local burning = locomotive.burner.currently_burning
if burning then acceleration_multiplier = burning.name.fuel_acceleration_multiplier end
end
local fraction = 0
if power > 0 and acceleration_multiplier then
local r = 1 - front_stock.prototype.air_resistance * 1000 / weight
local a_full = power / 1000 * acceleration_multiplier / weight
local v1 = math.max(0, math.abs(speed) - friction / weight)
local a_used = math.min(a_full, max_speed / r - v1)
fraction = math.max(0, math.min(1, a_used / a_full))
end
for _, locomotive in pairs(movers) do
local usage = locomotive.prototype.get_max_energy_usage(locomotive.quality) * fraction
consumption[locomotive.unit_number] = usage
total = total + usage
end
return consumption, total
endMy personal use case would be improving my mod https://mods.factorio.com/mod/Electronic_Locomotives.
Greetz,
Luzifer
