z_mirror/EditorExtensions

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

Caleb HeuerFix crash when placing an infinity fluid wagon5caf159

trunk
6.3 KiB218 linesraw
1--- @class InfinityFluidWagonData
2--- @field flip integer
3--- @field proxy LuaEntity
4--- @field wagon LuaEntity
5--- @field wagon_last_position MapPosition
6--- @field wagon_name string
7
8--- @param player LuaPlayer
9--- @param entity LuaEntity
10local function open_gui(player, entity)
11  player.opened = storage.wagons[entity.unit_number].proxy
12end
13
14--- @param e BuiltEvent
15local function on_entity_built(e)
16  local entity = e.entity or e.destination
17  if not entity or not entity.valid or entity.name ~= "ee-infinity-fluid-wagon" then
18    return
19  end
20
21  local proxy = entity.surface.create_entity({
22    name = "ee-infinity-wagon-pipe",
23    position = entity.position,
24    force = entity.force,
25  })
26  if not proxy then
27    return
28  end
29
30  -- Create all api lookups here to save time in on_tick()
31  local data = {
32    flip = 0,
33    proxy = proxy,
34    wagon = entity,
35    wagon_last_position = entity.position,
36    wagon_name = entity.name,
37  }
38  storage.wagons[entity.unit_number] = data
39
40  local tags = e.tags
41  if not tags or not tags.EditorExtensions then
42    return
43  end
44  proxy.set_infinity_pipe_filter(tags.EditorExtensions --[[@as InfinityPipeFilter]])
45end
46
47--- @param e DestroyedEvent
48local function on_entity_destroyed(e)
49  local entity = e.entity
50  if not entity or not entity.valid or entity.name ~= "ee-infinity-fluid-wagon" then
51    return
52  end
53
54  local proxy = storage.wagons[entity.unit_number].proxy
55  if proxy and proxy.valid then
56    proxy.destroy({})
57  end
58  storage.wagons[entity.unit_number] = nil
59end
60
61--- @param e EventData.on_marked_for_deconstruction
62local function on_marked_for_deconstruction(e)
63  local entity = e.entity
64  if not entity.valid or entity.name ~= "ee-infinity-fluid-wagon" then
65    return
66  end
67  storage.wagons[entity.unit_number].flip = 3
68end
69
70--- @param e EventData.on_cancelled_deconstruction
71local function on_cancelled_deconstruction(e)
72  local entity = e.entity
73  if not entity.valid or entity.name ~= "ee-infinity-fluid-wagon" then
74    return
75  end
76  -- Resume syncing
77  storage.wagons[entity.unit_number].flip = 0
78end
79
80--- @param data InfinityFluidWagonData
81local function sync_fluid(data)
82  if data.flip == 0 then
83    local fluid = data.proxy.get_fluid(1)
84    if fluid then
85      fluid.amount = math.max(fluid.amount * 250, 0)
86      data.wagon.set_fluid(1, fluid)
87    else
88      data.wagon.clear_fluid(1)
89    end
90    data.flip = 1
91  elseif data.flip == 1 then
92    local fluid = data.wagon.get_fluid(1)
93    if fluid then
94      fluid.amount = math.max(fluid.amount / 250, 0)
95      data.proxy.set_fluid(1, fluid)
96    else
97      data.proxy.clear_fluid(1)
98    end
99    data.flip = 0
100  end
101end
102
103local function on_tick()
104  for unit_number, data in pairs(storage.wagons) do
105    if not data.wagon.valid or not data.proxy.valid then
106      if data.wagon.valid then
107        data.wagon.destroy({ raise_destroy = true })
108      end
109      if data.proxy.valid then
110        data.proxy.destroy({ raise_destroy = true })
111      end
112      storage.wagons[unit_number] = nil
113      goto continue
114    end
115    sync_fluid(data)
116    local position = data.wagon.position
117    local last_position = data.wagon_last_position
118    if not last_position or last_position.x ~= position.x or last_position.y ~= position.y then
119      data.proxy.teleport(data.wagon.position)
120      data.wagon_last_position = data.wagon.position
121    end
122    ::continue::
123  end
124end
125
126--- @param e EventData.CustomInputEvent
127local function on_linked_open_gui(e)
128  local player = game.get_player(e.player_index)
129  if not player then
130    return
131  end
132  local entity = player.selected
133  if not entity or entity.name ~= "ee-infinity-fluid-wagon" then
134    return
135  end
136  if not player.can_reach_entity(entity) then
137    return
138  end
139  open_gui(player, entity)
140end
141
142--- @param e EventData.on_entity_settings_pasted
143local function on_entity_settings_pasted(e)
144  local source, destination = e.source, e.destination
145  if not source.valid or not destination.valid then
146    return
147  end
148  if source.name ~= "ee-infinity-fluid-wagon" or destination.name ~= "ee-infinity-fluid-wagon" then
149    return
150  end
151  if source.name ~= destination.name then
152    return
153  end
154
155  storage.wagons[destination.unit_number].proxy.copy_settings(storage.wagons[source.unit_number].proxy)
156end
157
158--- @param e EventData.on_player_setup_blueprint
159local function on_player_setup_blueprint(e)
160  local blueprint = e.stack or e.record
161  if not blueprint then
162    return
163  end
164
165  local entities = blueprint.get_blueprint_entities()
166  if not entities then
167    return
168  end
169  for i, entity in pairs(entities) do
170    --- @cast i uint
171    if entity.name ~= "ee-infinity-fluid-wagon" then
172      goto continue
173    end
174    local real_entity = e.surface.find_entity(entity.name, entity.position)
175    if not real_entity then
176      goto continue
177    end
178    local proxy = storage.wagons[real_entity.unit_number].proxy
179    local tags = {}
180    if entity.name == "ee-infinity-cargo-wagon" then
181      tags.filters = proxy.infinity_container_filters
182      tags.remove_unfiltered_items = proxy.remove_unfiltered_items
183    else
184      tags = proxy.get_infinity_pipe_filter()
185    end
186    blueprint.set_blueprint_entity_tag(i, "EditorExtensions", tags --[[@as AnyBasic]])
187    ::continue::
188  end
189end
190
191local infinity_wagon = {}
192
193infinity_wagon.on_init = function()
194  --- @type table<uint, InfinityFluidWagonData>
195  storage.wagons = {}
196end
197
198infinity_wagon.events = {
199  [defines.events.on_built_entity] = on_entity_built,
200  [defines.events.on_cancelled_deconstruction] = on_cancelled_deconstruction,
201  [defines.events.on_entity_cloned] = on_entity_built,
202  [defines.events.on_entity_died] = on_entity_destroyed,
203  [defines.events.on_entity_settings_pasted] = on_entity_settings_pasted,
204  [defines.events.on_marked_for_deconstruction] = on_marked_for_deconstruction,
205  [defines.events.on_player_mined_entity] = on_entity_destroyed,
206  [defines.events.on_player_setup_blueprint] = on_player_setup_blueprint,
207  [defines.events.on_robot_built_entity] = on_entity_built,
208  [defines.events.on_robot_mined_entity] = on_entity_destroyed,
209  [defines.events.on_tick] = on_tick,
210  [defines.events.script_raised_built] = on_entity_built,
211  [defines.events.script_raised_destroy] = on_entity_destroyed,
212  [defines.events.script_raised_revive] = on_entity_built,
213  [defines.events.on_space_platform_built_entity] = on_entity_built,
214  [defines.events.on_space_platform_mined_entity] = on_entity_destroyed,
215  ["ee-linked-open-gui"] = on_linked_open_gui,
216}
217
218return infinity_wagon