z_mirror/RecipeBook

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

Caleb HeuerAlso auto-scale crafting timef677f42

trunk
8.5 KiB303 linesraw
1local flib_format = require("__flib__.format")
2local flib_math = require("__flib__.math")
3local core_util = require("__core__.lualib.util")
4local util = require("scripts.util")
5
6--- @class GuiUtil
7local gui_util = {}
8
9--- @param crafting_time double?
10--- @return LocalisedString?
11function gui_util.format_crafting_time(crafting_time)
12  if not crafting_time then
13    return nil
14  end
15  return {
16    "",
17    "[img=quantity-time]",
18    gui_util.format_time(crafting_time),
19    " ",
20    { "description.crafting-time" },
21  }
22end
23
24--- @param count uint?
25--- @param time double?
26--- @return LocalisedString
27function gui_util.format_technology_count_and_time(count, time)
28  if not count or not time then
29    return
30  end
31
32  --- @type LocalisedString
33  return {
34    "",
35    "[img=quantity-time]",
36    { "time-symbol-seconds", flib_math.floored(time, 0.01) },
37    " × ",
38    flib_format.number(count, true),
39  }
40end
41
42local temperature_edge = (2 - 2 ^ -23) * 2 ^ 127
43
44--- @param id DatabaseID
45--- @return LocalisedString
46function gui_util.format_caption(id)
47  --- @type LocalisedString
48  local caption = { "" }
49  if id.probability and id.probability < 1 then
50    caption[#caption + 1] = {
51      "",
52      "[font=default-semibold]",
53      { "format-percent", flib_math.round(id.probability * 100, 0.01) },
54      "[/font] ",
55    }
56  end
57  if id.amount then
58    if id.extra_count_fraction then
59      caption[#caption + 1] = {
60        "",
61        "[font=default-semibold]",
62        core_util.format_number(flib_math.round(id.amount, 0.01), true),
63        "-",
64        core_util.format_number(flib_math.round(id.amount + 1, 0.01), true),
65        " ×[/font] ",
66      }
67    else
68      caption[#caption + 1] = {
69        "",
70        "[font=default-semibold]",
71        core_util.format_number(flib_math.round(id.amount, 0.01), true),
72        " ×[/font] ",
73      }
74    end
75  elseif id.amount_min and id.amount_max then
76    caption[#caption + 1] = {
77      "",
78      "[font=default-semibold]",
79      core_util.format_number(flib_math.round(id.amount_min, 0.01), true),
80      "-",
81      core_util.format_number(flib_math.round(id.amount_max, 0.01), true),
82      " ×[/font] ",
83    }
84  end
85  if id.time then
86    caption[#caption + 1] = {
87      "",
88      "[font=default-semibold](",
89      gui_util.format_time(id.time),
90      ")[/font] ",
91    }
92  end
93
94  caption[#caption + 1] = util.get_prototype(id).localised_name --- @diagnostic disable-line:assign-type-mismatch
95
96  if id.temperature then
97    caption[#caption + 1] = { "", "  (", flib_math.round(id.temperature, 0.01), { "si-unit-degree-celsius" }, ")" }
98  elseif id.minimum_temperature and id.maximum_temperature then
99    local temperature_min = id.minimum_temperature --[[@as number]]
100    local temperature_max = id.maximum_temperature --[[@as number]]
101    local temperature_string
102    if temperature_min == -temperature_edge then
103      temperature_string = "≤ " .. flib_math.round(temperature_max, 0.01)
104    elseif temperature_max == temperature_edge then
105      temperature_string = "≥ " .. flib_math.round(temperature_min, 0.01)
106    else
107      temperature_string = ""
108        .. flib_math.round(temperature_min, 0.01)
109        .. " - "
110        .. flib_math.round(temperature_max, 0.01)
111    end
112    caption[#caption + 1] = { "", "  (", temperature_string, { "si-unit-degree-celsius" }, ")" }
113  end
114
115  if id.extra_count_fraction then
116    caption[#caption + 1] = " [img=info]"
117  end
118
119  return caption
120end
121
122--- @param id DatabaseID
123function gui_util.format_tooltip(id)
124  --- @type LocalisedString
125  local output = { "" }
126  if id.extra_count_fraction then
127    output[#output + 1] = {
128      "",
129      {
130        "description.extra-count-factor",
131        core_util.format_number(flib_math.round(id.extra_count_fraction * 100, 0.01)),
132      },
133      "\n",
134    }
135  end
136  output[#output + 1] = { "", { "gui.rb-control-hint" }, "\n", { "gui.rb-pipette-control-hint" } }
137  return output
138end
139
140--- @param input number?
141--- @return LocalisedString?
142function gui_util.format_short_number(input)
143  if not input then
144    return
145  end
146  local divisor = 0.1
147  if input >= 100 then
148    divisor = 1
149  elseif input < 1 then
150    divisor = 0.01
151  end
152
153  return core_util.format_number(flib_math.floored(input, divisor), true)
154end
155
156--- @param input number Time in seconds.
157--- @return LocalisedString
158function gui_util.format_time(input)
159  local output = input
160  local format = "time-symbol-seconds"
161  if input >= 60 * 60 then
162    output = input / 60 / 60
163    format = "time-symbol-hours"
164  elseif input >= 60 then
165    output = input / 60
166    format = "time-symbol-minutes"
167  end
168
169  return { format, gui_util.format_short_number(output) }
170end
171
172--- @param id DatabaseID
173--- @return LocalisedString? bottom
174--- @return LocalisedString? top
175function gui_util.format_slot_button_remarks(id)
176  local amount = id.amount
177  local amount_min = id.amount_min
178  local amount_max = id.amount_max
179  if amount then
180    return gui_util.format_short_number(amount)
181  elseif amount_min and amount_max and amount_min ~= amount_max then
182    return gui_util.format_short_number(amount_min), gui_util.format_short_number(amount_max)
183  elseif amount_min then
184    return gui_util.format_short_number(amount_min)
185  elseif amount_max then
186    return gui_util.format_short_number(amount_max)
187  end
188  if id.time then
189    return gui_util.format_time(id.time)
190  end
191  local temperature = id.temperature
192  local temperature_min = id.minimum_temperature
193  local temperature_max = id.maximum_temperature
194  --- @type LocalisedString?
195  local bottom
196  --- @type LocalisedString?
197  local top
198  if temperature then
199    bottom = { "", gui_util.format_short_number(temperature), { "si-unit-degree-celsius" } }
200  elseif temperature_min and temperature_max then
201    if temperature_min == -temperature_edge then
202      bottom = { "", "≤", gui_util.format_short_number(temperature_max), { "si-unit-degree-celsius" } }
203    elseif temperature_max == temperature_edge then
204      bottom = { "", "≥", gui_util.format_short_number(temperature_min), { "si-unit-degree-celsius" } }
205    else
206      bottom = { "", gui_util.format_short_number(temperature_min), { "si-unit-degree-celsius" } }
207      top = { "", gui_util.format_short_number(temperature_max), { "si-unit-degree-celsius" } }
208    end
209  end
210
211  return bottom, top
212end
213
214--- @alias FabState
215--- | "default"
216--- | "selected"
217--- | "disabled"
218
219--- @param button LuaGuiElement
220--- @param state FabState
221function gui_util.update_frame_action_button(button, state)
222  if state == "default" then
223    button.enabled = true
224    button.toggled = false
225  elseif state == "selected" then
226    button.enabled = true
227    button.toggled = true
228  elseif state == "disabled" then
229    button.enabled = false
230    button.toggled = false
231  end
232end
233
234--- @type table<string, LocalisedString>
235gui_util.type_locale = {
236  LuaEntityPrototype = { "factoriopedia.entity" },
237  LuaEquipmentPrototype = { "gui-map-editor.character-equipment" },
238  LuaFluidPrototype = { "factoriopedia.fluid" },
239  LuaItemPrototype = { "factoriopedia.item" },
240  LuaRecipePrototype = { "description.recipe" },
241  LuaTechnologyPrototype = { "gui-map-generator.technology-difficulty-group-tile" },
242  LuaTilePrototype = { "factoriopedia.tile" },
243}
244
245--- @type table<string, boolean>
246gui_util.vehicles = {
247  ["car"] = true,
248  ["artillery-wagon"] = true,
249  ["cargo-wagon"] = true,
250  ["fluid-wagon"] = true,
251  ["locomotive"] = true,
252  ["spider-vehicle"] = true,
253}
254
255--- @return LocalisedString
256function gui_util.format_power(input)
257  local formatted = flib_format.number(input, true)
258  if input < 1000 then
259    return { "", formatted, " ", { "si-unit-symbol-watt" } }
260  end
261  return { "", formatted, { "si-unit-symbol-watt" } }
262end
263
264--- @param id DatabaseID
265--- @param fallback string
266function gui_util.get_tooltip_category_sprite(id, fallback)
267  local by_name = "tooltip-category-" .. id.name
268  if helpers.is_valid_sprite_path(by_name) then
269    return by_name
270  end
271  return "tooltip-category-" .. fallback
272end
273
274--- @param elem LuaGuiElement
275--- @param key string
276--- @param value AnyBasic
277function gui_util.add_tag(elem, key, value)
278  local tags = elem.tags
279  tags[key] = value
280  elem.tags = tags
281end
282
283--- @param tick uint
284--- @return string
285function gui_util.format_spoil_time(tick)
286  local total_seconds = math.floor(tick / 60)
287  local seconds = total_seconds % 60
288  local minutes = math.floor(total_seconds / 60 % 60)
289  local hours = math.floor(total_seconds / 60 / 60)
290  local output = ""
291  if hours > 0 then
292    output = output .. hours .. "h"
293  end
294  if minutes > 0 then
295    output = output .. minutes .. "m"
296  end
297  if seconds > 0 then
298    output = output .. seconds .. "s"
299  end
300  return output
301end
302
303return gui_util