mirror of
https://github.com/factoriolib/flib.git
synced 2025-09-04 08:26:22 +00:00
122 lines
3.9 KiB
Lua
122 lines
3.9 KiB
Lua
if ... ~= "__flib__.technology" then
|
|
return require("__flib__.technology")
|
|
end
|
|
|
|
--- @class flib_technology
|
|
local flib_technology = {}
|
|
|
|
--- Gets the active or saved research progress for the given technology.
|
|
--- @param technology LuaTechnology
|
|
--- @param level uint
|
|
--- @return double
|
|
function flib_technology.get_research_progress(technology, level)
|
|
local force = technology.force
|
|
local current_research = force.current_research
|
|
if current_research and current_research.name == technology.name then
|
|
if technology.level == level or not flib_technology.is_multilevel(technology) then
|
|
return force.research_progress
|
|
else
|
|
return 0
|
|
end
|
|
elseif technology.level == level then
|
|
return technology.saved_progress
|
|
else
|
|
return 0
|
|
end
|
|
end
|
|
|
|
--- Gets the research unit count for the given technology.
|
|
--- @param technology LuaTechnology
|
|
--- @param level uint?
|
|
--- @return uint
|
|
function flib_technology.get_research_unit_count(technology, level)
|
|
local formula = technology.research_unit_count_formula
|
|
if formula then
|
|
local level = level or technology.level
|
|
return math.floor(helpers.evaluate_expression(formula, { l = level, L = level }))
|
|
end
|
|
return math.floor(technology.research_unit_count)
|
|
end
|
|
|
|
--- Returns whether the technology has multiple levels.
|
|
--- @param technology LuaTechnology|LuaTechnologyPrototype
|
|
--- @return boolean
|
|
function flib_technology.is_multilevel(technology)
|
|
if technology.object_name == "LuaTechnology" then
|
|
technology = technology.prototype
|
|
end
|
|
return technology.level ~= technology.max_level
|
|
end
|
|
|
|
--- Returns `true` if the first technology should be ordered before the second technology. For use in `table.sort`.
|
|
--- @param tech_a LuaTechnologyPrototype
|
|
--- @param tech_b LuaTechnologyPrototype
|
|
--- @return boolean
|
|
function flib_technology.sort_predicate(tech_a, tech_b)
|
|
local ingredients_a = tech_a.research_unit_ingredients
|
|
local ingredients_b = tech_b.research_unit_ingredients
|
|
local len_a = #ingredients_a
|
|
local len_b = #ingredients_b
|
|
-- Always put technologies with zero ingredients at the front
|
|
if (len_a == 0) ~= (len_b == 0) then
|
|
return len_a == 0
|
|
end
|
|
if #ingredients_a > 0 then
|
|
-- Compare ingredient order strings
|
|
-- Check the most expensive packs first, and sort based on the first difference
|
|
for i = 0, math.min(len_a, len_b) - 1 do
|
|
local ingredient_a = ingredients_a[len_a - i]
|
|
local ingredient_b = ingredients_b[len_b - i]
|
|
local order_a = prototypes.item[ingredient_a.name].order
|
|
local order_b = prototypes.item[ingredient_b.name].order
|
|
-- Cheaper pack goes in front
|
|
if order_a ~= order_b then
|
|
return order_a < order_b
|
|
end
|
|
end
|
|
-- Sort the technology with fewer ingredients in front
|
|
if len_a ~= len_b then
|
|
return len_a < len_b
|
|
end
|
|
end
|
|
-- Compare technology order strings
|
|
local order_a = tech_a.order
|
|
local order_b = tech_b.order
|
|
if order_a ~= order_b then
|
|
return order_a < order_b
|
|
end
|
|
-- Compare prototype names
|
|
return tech_a.name < tech_b.name
|
|
end
|
|
|
|
--- Returns the technology's prototype name with the level suffix stripped.
|
|
--- @param technology LuaTechnology|LuaTechnologyPrototype
|
|
--- @return string
|
|
function flib_technology.get_base_name(technology)
|
|
local result = string.gsub(technology.name, "%-%d*$", "")
|
|
return result
|
|
end
|
|
|
|
--- If the technology is multi-level, returns the technology's base name with that level appended, otherwise returns the technology name.
|
|
--- @param technology LuaTechnology
|
|
--- @param level uint
|
|
--- @return string
|
|
function flib_technology.get_leveled_name(technology, level)
|
|
if flib_technology.is_multilevel(technology) then
|
|
return flib_technology.get_base_name(technology) .. "-" .. level
|
|
else
|
|
return technology.name
|
|
end
|
|
end
|
|
|
|
--- @enum TechnologyResearchState
|
|
flib_technology.research_state = {
|
|
available = 1,
|
|
conditionally_available = 2,
|
|
not_available = 3,
|
|
researched = 4,
|
|
disabled = 5,
|
|
}
|
|
|
|
return flib_technology
|