z_mirror/EditorExtensions

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

Caleb HeuerRefactor super pump864e346

1.14
7.0 KiB267 linesraw
1local gui = require("__flib__/gui-lite")
2local math = require("__flib__/math")
3local table = require("__flib__/table")
4
5local util = require("__EditorExtensions__/scripts/util")
6
7--- @param entity LuaEntity
8--- @param speed double
9local function set_speed(entity, speed)
10  entity.fluidbox[2] = {
11    name = "ee-super-pump-speed-fluid",
12    amount = 100000000000,
13    temperature = speed + 0.01, -- avoid floating point imprecision
14  }
15end
16
17--- @param entity LuaEntity
18local function get_speed(entity)
19  return math.floor(entity.fluidbox[2].temperature)
20end
21
22local slider_to_temperature = {
23  [0] = 0,
24  [1] = 100,
25  [2] = 200,
26  [3] = 300,
27  [4] = 400,
28  [5] = 500,
29  [6] = 600,
30  [7] = 700,
31  [8] = 800,
32  [9] = 900,
33  [10] = 1000,
34  [11] = 2000,
35  [12] = 3000,
36  [13] = 4000,
37  [14] = 5000,
38  [15] = 6000,
39  [16] = 7000,
40  [17] = 8000,
41  [18] = 9000,
42  [19] = 10000,
43  [20] = 15000,
44  [21] = 20000,
45  [22] = 25000,
46  [23] = 30000,
47}
48local temperature_to_slider = table.invert(slider_to_temperature)
49
50--- @param speed double
51--- @return double
52local function to_slider_value(speed)
53  local index
54  if speed == 0 then
55    index = 0
56  elseif speed < 1000 then
57    index = math.floor(speed / 100) * 100
58  elseif speed < 10000 then
59    index = math.floor(speed / 1000) * 1000
60  elseif speed < 30000 then
61    index = math.floor(speed / 5000) * 5000
62  else
63    index = 30000
64  end
65  return temperature_to_slider[index]
66end
67
68--- @param value double
69--- @return double
70local function from_slider_value(value)
71  return slider_to_temperature[value]
72end
73
74--- @param entity LuaEntity
75--- @param flow LuaGuiElement
76local function update_gui(entity, flow)
77  local speed = get_speed(entity)
78
79  local textfield = flow.speed_textfield --[[@as LuaGuiElement]]
80  textfield.style = "ee_slider_textfield"
81  textfield.text = tostring(speed)
82
83  local slider = flow.speed_slider --[[@as LuaGuiElement]]
84  slider.slider_value = to_slider_value(speed)
85end
86
87local handlers = {
88  --- @param entity LuaEntity
89  --- @param e EventData.on_gui_value_changed
90  on_pump_speed_slider_value_changed = function(entity, e)
91    local new_speed = from_slider_value(e.element.slider_value)
92    set_speed(entity, new_speed)
93    update_gui(entity, e.element.parent)
94  end,
95
96  --- @param entity LuaEntity
97  --- @param e EventData.on_gui_text_changed
98  on_pump_speed_textfield_changed = function(entity, e)
99    local textfield = e.element
100    local text = textfield.text
101    local speed = tonumber(text)
102
103    if not speed or speed > 600000 then
104      textfield.style = "ee_invalid_slider_textfield"
105      return
106    end
107
108    set_speed(entity, speed)
109    update_gui(entity, e.element.parent)
110  end,
111}
112
113gui.add_handlers(handlers, function(e, handler)
114  local player = game.get_player(e.player_index)
115  if not player or player.opened_gui_type ~= defines.gui_type.entity then
116    return
117  end
118  local entity = player.opened --[[@as LuaEntity]]
119  if entity.name ~= "ee-super-pump" then
120    return
121  end
122  handler(entity, e)
123end)
124
125--- @param player LuaPlayer
126local function create_gui(player)
127  local existing = player.gui.relative.ee_super_pump_window
128  if existing then
129    existing.destroy()
130  end
131
132  gui.add(player.gui.relative, {
133    type = "frame",
134    name = "ee_super_pump_window",
135    style = "frame_with_even_paddings",
136    style_mods = { width = 448 },
137    anchor = {
138      gui = defines.relative_gui_type.entity_with_energy_source_gui,
139      position = defines.relative_gui_position.bottom,
140      name = "ee-super-pump",
141    },
142    {
143      type = "frame",
144      name = "inner_frame",
145      style = "inside_shallow_frame_with_padding",
146      {
147        type = "flow",
148        name = "inner_flow",
149        style = "centering_horizontal_flow",
150        { type = "label", caption = { "gui.ee-speed" }, tooltip = { "gui.ee-speed-tooltip" } },
151        {
152          type = "slider",
153          name = "speed_slider",
154          style_mods = { horizontally_stretchable = true, margin = { 0, 8, 0, 8 } },
155          minimum_value = 0,
156          maximum_value = 23,
157          value = 0,
158          handler = { [defines.events.on_gui_value_changed] = handlers.on_pump_speed_slider_value_changed },
159        },
160        {
161          type = "textfield",
162          name = "speed_textfield",
163          style = "ee_slider_textfield",
164          numeric = true,
165          clear_and_focus_on_right_click = true,
166          handler = { [defines.events.on_gui_text_changed] = handlers.on_pump_speed_textfield_changed },
167        },
168      },
169    },
170  })
171end
172
173--- @param e BuiltEvent
174local function on_entity_built(e)
175  local entity = e.created_entity or e.entity or e.destination
176  if not entity or not entity.valid or entity.name ~= "ee-super-pump" then
177    return
178  end
179  local speed = 12000
180  local tags = e.tags
181  if tags and tags.EditorExtensions then
182    speed = tags.EditorExtensions.speed --[[@as double]]
183  end
184  set_speed(entity, speed)
185end
186
187--- @param e EventData.on_player_setup_blueprint
188local function on_player_setup_blueprint(e)
189  local blueprint = util.get_blueprint(e)
190  if not blueprint then
191    return
192  end
193
194  local entities = blueprint.get_blueprint_entities()
195  if not entities then
196    return
197  end
198  for i, entity in pairs(entities) do
199    --- @cast i uint
200    if entity.name ~= "ee-super-pump" then
201      goto continue
202    end
203    local real_entity = e.surface.find_entity(entity.name, entity.position)
204    if not real_entity then
205      goto continue
206    end
207    blueprint.set_blueprint_entity_tag(i, "EditorExtensions", { speed = get_speed(real_entity) })
208    ::continue::
209  end
210end
211
212local function on_entity_settings_pasted(e)
213  local source, destination = e.source, e.destination
214  if not source.valid or not destination.valid then
215    return
216  end
217  if source.name ~= "ee-super-pump" or destination.name ~= "ee-super-pump" then
218    return
219  end
220  set_speed(destination, get_speed(source))
221end
222
223--- @param e EventData.on_gui_opened
224local function on_gui_opened(e)
225  local player = game.get_player(e.player_index)
226  if not player or player.opened_gui_type ~= defines.gui_type.entity then
227    return
228  end
229  local entity = player.opened --[[@as LuaEntity]]
230  if entity.name ~= "ee-super-pump" then
231    return
232  end
233
234  update_gui(entity, player.gui.relative.ee_super_pump_window.inner_frame.inner_flow)
235end
236
237--- @param e EventData.on_player_created
238local function on_player_created(e)
239  local player = game.get_player(e.player_index)
240  if not player then
241    return
242  end
243
244  create_gui(player)
245end
246
247local super_pump = {}
248
249super_pump.on_configuration_changed = function()
250  for _, player in pairs(game.players) do
251    create_gui(player)
252  end
253end
254
255super_pump.events = {
256  [defines.events.on_built_entity] = on_entity_built,
257  [defines.events.on_entity_cloned] = on_entity_built,
258  [defines.events.on_entity_settings_pasted] = on_entity_settings_pasted,
259  [defines.events.on_gui_opened] = on_gui_opened,
260  [defines.events.on_player_created] = on_player_created,
261  [defines.events.on_player_setup_blueprint] = on_player_setup_blueprint,
262  [defines.events.on_robot_built_entity] = on_entity_built,
263  [defines.events.script_raised_built] = on_entity_built,
264  [defines.events.script_raised_revive] = on_entity_built,
265}
266
267return super_pump