z_mirror/flib

git clone https://git.raiguard.me/z_mirror/flib

Caleb HeuerRemove require guardsa9f2be7

trunk
3.8 KiB117 linesraw
1--- @class flib_technology
2local flib_technology = {}
3
4--- Gets the active or saved research progress for the given technology.
5--- @param technology LuaTechnology
6--- @param level uint
7--- @return double
8function flib_technology.get_research_progress(technology, level)
9  local force = technology.force
10  local current_research = force.current_research
11  if current_research and current_research.name == technology.name then
12    if technology.level == level or not flib_technology.is_multilevel(technology) then
13      return force.research_progress
14    else
15      return 0
16    end
17  elseif technology.level == level then
18    return technology.saved_progress
19  else
20    return 0
21  end
22end
23
24--- Gets the research unit count for the given technology.
25--- @param technology LuaTechnology
26--- @param level uint?
27--- @return uint
28function flib_technology.get_research_unit_count(technology, level)
29  local formula = technology.research_unit_count_formula
30  if formula then
31    local level = level or technology.level
32    return math.floor(helpers.evaluate_expression(formula, { l = level, L = level }))
33  end
34  return math.floor(technology.research_unit_count)
35end
36
37--- Returns whether the technology has multiple levels.
38--- @param technology LuaTechnology|LuaTechnologyPrototype
39--- @return boolean
40function flib_technology.is_multilevel(technology)
41  if technology.object_name == "LuaTechnology" then
42    technology = technology.prototype
43  end
44  return technology.level ~= technology.max_level
45end
46
47--- Returns `true` if the first technology should be ordered before the second technology. For use in `table.sort`.
48--- @param tech_a LuaTechnologyPrototype
49--- @param tech_b LuaTechnologyPrototype
50--- @return boolean
51function flib_technology.sort_predicate(tech_a, tech_b)
52  local ingredients_a = tech_a.research_unit_ingredients
53  local ingredients_b = tech_b.research_unit_ingredients
54  local len_a = #ingredients_a
55  local len_b = #ingredients_b
56  -- Always put technologies with zero ingredients at the front
57  if (len_a == 0) ~= (len_b == 0) then
58    return len_a == 0
59  end
60  if #ingredients_a > 0 then
61    -- Compare ingredient order strings
62    -- Check the most expensive packs first, and sort based on the first difference
63    for i = 0, math.min(len_a, len_b) - 1 do
64      local ingredient_a = ingredients_a[len_a - i]
65      local ingredient_b = ingredients_b[len_b - i]
66      local order_a = prototypes.item[ingredient_a.name].order
67      local order_b = prototypes.item[ingredient_b.name].order
68      -- Cheaper pack goes in front
69      if order_a ~= order_b then
70        return order_a < order_b
71      end
72    end
73    -- Sort the technology with fewer ingredients in front
74    if len_a ~= len_b then
75      return len_a < len_b
76    end
77  end
78  -- Compare technology order strings
79  local order_a = tech_a.order
80  local order_b = tech_b.order
81  if order_a ~= order_b then
82    return order_a < order_b
83  end
84  -- Compare prototype names
85  return tech_a.name < tech_b.name
86end
87
88--- Returns the technology's prototype name with the level suffix stripped.
89--- @param technology LuaTechnology|LuaTechnologyPrototype
90--- @return string
91function flib_technology.get_base_name(technology)
92  local result = string.gsub(technology.name, "%-%d*$", "")
93  return result
94end
95
96--- If the technology is multi-level, returns the technology's base name with that level appended, otherwise returns the technology name.
97--- @param technology LuaTechnology
98--- @param level uint
99--- @return string
100function flib_technology.get_leveled_name(technology, level)
101  if flib_technology.is_multilevel(technology) then
102    return flib_technology.get_base_name(technology) .. "-" .. level
103  else
104    return technology.name
105  end
106end
107
108--- @enum TechnologyResearchState
109flib_technology.research_state = {
110  available = 1,
111  conditionally_available = 2,
112  not_available = 3,
113  researched = 4,
114  disabled = 5,
115}
116
117return flib_technology