z_mirror/EditorExtensions

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

Caleb HeuerRemove or resolve TODOsf44d975

1.14
4.8 KiB179 linesraw
1local direction_util = require("__flib__/direction")
2local position = require("__flib__/position")
3
4--- @type table<defines.direction, Vector>
5local offsets = {
6  [defines.direction.north] = { 0, -1 },
7  [defines.direction.east] = { 1, 0 },
8  [defines.direction.south] = { 0, 1 },
9  [defines.direction.west] = { -1, 0 },
10}
11
12local transport_belt_connectables = {
13  "transport-belt",
14  "underground-belt",
15  "splitter",
16  "loader",
17  "loader-1x1",
18  "linked-belt",
19}
20
21--- @param entity LuaEntity
22local function snap(entity)
23  local offset_direction = entity.direction
24  if entity.loader_type == "input" then
25    offset_direction = direction_util.opposite(offset_direction)
26  end
27  local belt_position = position.add(entity.position, offsets[offset_direction])
28  local belt =
29    entity.surface.find_entities_filtered({ position = belt_position, type = transport_belt_connectables })[1]
30  if not belt then
31    belt =
32      entity.surface.find_entities_filtered({ position = belt_position, ghost_type = transport_belt_connectables })[1]
33  end
34  if not belt then
35    return
36  end
37  if belt.direction == direction_util.opposite(entity.direction) then
38    entity.loader_type = entity.loader_type == "output" and "input" or "output"
39  end
40end
41
42--- @param entity LuaEntity
43--- @param chest LuaEntity?
44local function sync_chest_filter(entity, chest)
45  if not chest then
46    chest = entity.surface.find_entity("ee-infinity-loader-chest", entity.position)
47  end
48  if not chest then
49    entity.destroy()
50    return
51  end
52  local filter = entity.get_filter(1)
53  if filter then
54    chest.set_infinity_container_filter(1, {
55      index = 1,
56      name = filter,
57      count = game.item_prototypes[filter].stack_size * 5,
58      mode = "exactly",
59    })
60  else
61    chest.set_infinity_container_filter(1, nil)
62  end
63end
64
65--- @param e BuiltEvent
66local function on_built(e)
67  local entity = e.entity or e.created_entity or e.destination
68  if not entity.valid then
69    return
70  end
71
72  if entity.name ~= "ee-infinity-loader" then
73    return
74  end
75
76  -- Create chest
77  local chest = entity.surface.create_entity({
78    name = "ee-infinity-loader-chest",
79    position = entity.position,
80    force = entity.force,
81    create_build_effect_smoke = false,
82    raise_built = true,
83  })
84
85  if not chest then
86    entity.destroy()
87    return
88  end
89
90  chest.remove_unfiltered_items = true
91  sync_chest_filter(entity, chest)
92  snap(entity)
93end
94
95--- @param e DestroyedEvent
96local function on_destroyed(e)
97  local entity = e.entity
98  if not entity.valid or entity.name ~= "ee-infinity-loader" then
99    return
100  end
101  local chest = entity.surface.find_entity("ee-infinity-loader-chest", entity.position)
102  if chest then
103    chest.destroy({ raise_destroy = true })
104  end
105end
106
107--- @param e EventData.on_player_rotated_entity
108local function on_rotated(e)
109  local entity = e.entity
110  if not entity.valid or entity.name ~= "ee-infinity-loader" then
111    return
112  end
113  sync_chest_filter(entity)
114end
115
116--- @param e EventData.on_entity_settings_pasted
117local function on_settings_pasted(e)
118  local destination = e.destination
119  if not destination.valid or destination.name ~= "ee-infinity-loader" then
120    return
121  end
122  sync_chest_filter(destination)
123end
124
125--- @param e EventData.on_gui_opened
126local function on_gui_opened(e)
127  if e.gui_type ~= defines.gui_type.entity then
128    return
129  end
130  local entity = e.entity --[[@as LuaEntity]]
131  if entity.name == "ee-infinity-loader" then
132    global.infinity_loader_open[e.player_index] = entity
133  end
134end
135
136--- @param e EventData.on_gui_closed
137local function on_gui_closed(e)
138  if e.gui_type ~= defines.gui_type.entity then
139    return
140  end
141  local loader = global.infinity_loader_open[e.player_index]
142  if loader and loader.valid then
143    sync_chest_filter(loader)
144    global.infinity_loader_open[e.player_index] = nil
145  end
146end
147
148local infinity_loader = {}
149
150function infinity_loader.on_init()
151  --- @type table<uint, LuaEntity>
152  global.infinity_loader_open = {}
153end
154
155infinity_loader.events = {
156  [defines.events.on_built_entity] = on_built,
157  [defines.events.on_entity_cloned] = on_built,
158  [defines.events.on_entity_died] = on_destroyed,
159  [defines.events.on_entity_settings_pasted] = on_settings_pasted,
160  [defines.events.on_gui_closed] = on_gui_closed,
161  [defines.events.on_gui_opened] = on_gui_opened,
162  [defines.events.on_player_mined_entity] = on_destroyed,
163  [defines.events.on_player_rotated_entity] = on_rotated,
164  [defines.events.on_robot_built_entity] = on_built,
165  [defines.events.on_robot_mined_entity] = on_destroyed,
166  [defines.events.script_raised_built] = on_built,
167  [defines.events.script_raised_destroy] = on_destroyed,
168  [defines.events.script_raised_revive] = on_built,
169}
170
171infinity_loader.on_nth_tick = {
172  [15] = function()
173    for _, loader in pairs(global.infinity_loader_open) do
174      sync_chest_filter(loader)
175    end
176  end,
177}
178
179return infinity_loader