-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathtechnology.lua
121 lines (112 loc) · 3.9 KB
/
technology.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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