forked from mspielberg/factorio-railloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
inserterconfig.lua
208 lines (182 loc) · 5.79 KB
/
inserterconfig.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
local bulk = require "bulk"
local EntityQueue = require "EntityQueue"
local util = require "util"
local M = {}
local INTERVAL = 60
local allowed_items_setting = settings.global["railloader-allowed-items"].value
local show_configuration_messages_setting = settings.global["railloader-show-configuration-messages"].value
local function display_configuration_message(loader, items)
if not next(items) then
return
end
local type = "railloader"
if loader.name == "railunloader-chest" then
type = "railunloader"
end
local msg = {"railloader." .. type .. "-configured-" .. #items}
for i, item in ipairs(items) do
msg[i+1] = {"item-name." .. item}
end
loader.surface.create_entity{
name = "flying-text",
position = loader.position,
text = msg,
}
end
local function inserter_configuration_changes(inserter, items)
local item_set = {}
for _, v in ipairs(items) do
item_set[v] = true
end
for i=1,inserter.prototype.filter_count do
local filter = inserter.get_filter(i)
if filter then
if not item_set[filter] then
-- existing filter will be removed
return true
end
item_set[filter] = nil
end
end
-- check if new filter(s) will be added
return next(item_set) ~= nil
end
local function configure_loader_from_inventories(loader, inventories)
local items = bulk.acceptable_items(inventories, 5)
if not next(items) then
return false
end
local inserters = util.railloader_filter_inserters(loader)
if not next(inserters) then
return true
end
if show_configuration_messages_setting and inserter_configuration_changes(inserters[1], items) then
display_configuration_message(loader, items)
end
for _, inserter in ipairs(inserters) do
for i=1,inserter.prototype.filter_count do
inserter.set_filter(i, items[i])
end
end
return true
end
local function configure_loader(loader)
local inventories = { loader.get_inventory(defines.inventory.chest) }
if loader.name == "railunloader-chest" then
local wagons = loader.surface.find_entities_filtered{
type = "cargo-wagon",
area = util.box_centered_at(loader.position, 0.6),
force = loader.force,
}
for i=1,#wagons do
inventories[i] = wagons[i].get_inventory(defines.inventory.cargo_wagon)
end
end
if next(inventories) then
return configure_loader_from_inventories(loader, inventories)
end
return false
end
local queue = EntityQueue.new("unconfigured_loaders", INTERVAL, configure_loader)
function M.on_train_changed_state(event)
if allowed_items_setting == "any" then
return
end
local train = event.train
if train.state ~= defines.train_state.wait_station and
event.old_state ~= defines.train_state.wait_station then
return
end
for _, wagon in ipairs(train.cargo_wagons) do
local loader = wagon.surface.find_entities_filtered{
type = "container",
area = util.box_centered_at(wagon.position, 0.6),
}[1]
if loader then
if train.state == defines.train_state.wait_station then
M.configure_or_register_loader(loader)
else
queue:unregister(loader)
end
end
end
end
function M.on_init()
queue:on_init()
end
function M.on_load()
queue:on_load()
end
function M.configure_or_register_loader(loader)
if allowed_items_setting == "any" then
return
end
local success = configure_loader(loader)
if not success then
queue:register(loader)
end
end
local function configure_inserter_control_behavior(inserter)
local behavior = inserter.get_or_create_control_behavior()
behavior.circuit_condition = {
condition = {
comparator = "=",
first_signal = {type = "virtual", name = "railloader-disable"},
}
}
end
function M.connect_and_configure_inserter_control_behavior(inserter, chest)
for _, wire_type in ipairs{"red", "green"} do
inserter.connect_neighbour{
target_entity = chest,
wire = defines.wire_type[wire_type],
}
end
configure_inserter_control_behavior(inserter)
end
local function replace_all_inserters(universal)
local from_qualifier = universal and "" or "-universal"
local to_qualifier = universal and "-universal" or ""
for _, s in pairs(game.surfaces) do
for _, type in ipairs{"railloader", "railunloader"} do
local to_match = type .. from_qualifier .. "-inserter"
local replace_with = type .. to_qualifier .. "-inserter"
for _, e in ipairs(s.find_entities_filtered{name=to_match}) do
local replacement = s.create_entity{
name = replace_with,
position = e.position,
direction = e.direction,
force = e.force,
}
replacement.destructible = false
replacement.held_stack.swap_stack(e.held_stack)
for _, ccd in ipairs(e.circuit_connection_definitions) do
replacement.connect_neighbour(ccd)
end
configure_inserter_control_behavior(replacement)
if not universal then
local loader = replacement.surface.find_entity(type .. "-chest", e.position)
if not loader then error("no loader found") end
queue:register(loader)
end
e.destroy()
end
end
end
end
function M.on_setting_changed(event)
if event.setting == "railloader-allowed-items" then
local new_value = settings.global["railloader-allowed-items"].value
if new_value == "any" and allowed_items_setting ~= "any" then
allowed_items_setting = new_value
replace_all_inserters(true)
elseif new_value ~= "any" and allowed_items_setting == "any" then
allowed_items_setting = new_value
replace_all_inserters(false)
end
bulk.on_setting_changed()
elseif event.setting == "railloader-show-configuration-messages" then
show_configuration_messages_setting = settings.global["railloader-show-configuration-messages"].value
end
end
return M