forked from chucksellick/factorio-bad-chest
-
Notifications
You must be signed in to change notification settings - Fork 8
/
digitizer.lua
236 lines (205 loc) · 8.85 KB
/
digitizer.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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
local function readPrint(digitizer,deployer)
local inStack = deployer.get_inventory(defines.inventory.chest)[1]
if not inStack or not inStack.valid then
return false
end
global.digitizerprints[digitizer.unit_number]={
tiles=inStack.get_blueprint_tiles(),
entities=inStack.get_blueprint_entities(),
icons=inStack.blueprint_icons,
label=inStack.label,
}
--inStack.count=0
return true
end
local function writePrint(digitizer,deployer,index)
local storedPrint = global.digitizerprints[digitizer.unit_number]
local outInv = deployer.get_inventory(defines.inventory.chest)
if not outInv[1] or outInv[1].name ~= "blueprint" then
return false
end
local outStack = outInv[1]
outStack.set_blueprint_entities(storedPrint.entities)
outStack.set_blueprint_tiles(storedPrint.tiles)
outStack.blueprint_icons = storedPrint.icons
outStack.label = storedPrint.label or ""
return true
end
local commandsig = {name="signal-blue",type="virtual"}
local function onTickDigitizerDeployer(digitizer,deployer)
local printStack = deployer.get_inventory(defines.inventory.chest)[1]
if not printStack or not printStack.valid_for_read or not printStack.name == "blueprint" then
return
end
local txSignals = {}
local command = get_signal_value(deployer,commandsig)
local write = get_signal_value(deployer,{name="signal-white",type="virtual"})
if command == 0 then return end
if get_signal_value(deployer,{name="construction-robot",type="item"}) ~= 0 or
get_signal_value(deployer,{name="deconstruction-planner",type="item"}) ~= 0 then
return -- commands reserved by the deployer itself
end
if command == 2 then -- Get print BoM
txSignals[#txSignals+1]={index=#txSignals+1,count=command,signal=commandsig}
for k,v in pairs(printStack.cost_to_build) do
txSignals[#txSignals+1]={index=#txSignals+1,count=v,signal={name=k,type="item"}}
end
elseif command == 3 then -- Get print stats
--print stats: E=#entities, T=#tiles, I=#icons, L=#label
txSignals[#txSignals+1]={index=#txSignals+1,count=command,signal=commandsig}
local e = printStack.get_blueprint_entities() or {}
local t = printStack.get_blueprint_tiles() or {}
local i = printStack.blueprint_icons or {}
local l = printStack.label or ""
txSignals[#txSignals+1]={index=#txSignals+1,count=#e,signal={name="signal-E",type="virtual"}}
txSignals[#txSignals+1]={index=#txSignals+1,count=#t,signal={name="signal-T",type="virtual"}}
txSignals[#txSignals+1]={index=#txSignals+1,count=#i,signal={name="signal-I",type="virtual"}}
txSignals[#txSignals+1]={index=#txSignals+1,count=#l,signal={name="signal-L",type="virtual"}}
elseif command == 4 then -- Get print icons
--icons: I=icon number, iconsignal=1
local sigI = get_signal_value(deployer,{name="signal-I",type="virtual"})
local i = printStack.blueprint_icons
if write == 1 and sigI.count>0 and sigI.count<5 then
local deplNet=deployer.get_circuit_network(defines.wire_type.red)
or deployer.get_circuit_network(defines.wire_type.green)
local signals=deplNet.signals
if #signals == 4 then
i[sigI.count] = {index=sigI.count,signal={}}
end
else
txSignals[#txSignals+1]={index=#txSignals+1,count=command,signal=commandsig}
txSignals[#txSignals+1]={index=#txSignals+1,count=sigI,signal={name="signal-I",type="virtual"}}
if i[sigI] then txSignals[#txSignals+1]={index=#txSignals+1,count=1,signal=i[sigI].signal} end
end
elseif command == 5 then -- Get print tiles
local t = printStack.get_blueprint_tiles()
if t then
--tiles: T=tile number, X,Y=position, tilesignal=1
local sigT = get_signal_value(deployer,{name="signal-T",type="virtual"})
if sigT > 0 and sigT <= #t then
txSignals[#txSignals+1]={index=#txSignals+1,count=command,signal=commandsig}
txSignals[#txSignals+1]={index=#txSignals+1,count=sigT,signal={name="signal-T",type="virtual"}}
for k,_ in pairs(game.tile_prototypes[t[sigT].name].items_to_place_this) do
txSignals[#txSignals+1]={index=#txSignals+1,count=1,signal={name=k,type="item"}}
end
txSignals[#txSignals+1]={index=#txSignals+1,count=t[sigT].position.x,signal={name="signal-X",type="virtual"}}
txSignals[#txSignals+1]={index=#txSignals+1,count=t[sigT].position.y,signal={name="signal-Y",type="virtual"}}
end
end
elseif command == 6 then -- Get print entities
local e = printStack.get_blueprint_entities()
local sigE = get_signal_value(deployer,{name="signal-E",type="virtual"})
local bpent = e[sigE]
if write == 1 then
else
--entities: E=entity number, X,Y=position, entitysignal=1, R=recipe, C=#connections, F=#filters, modules as count, ???
if sigE > 0 and sigE <= #e then
txSignals[#txSignals+1]={index=#txSignals+1,count=1,signal={name="signal-E",type="virtual"}}
for k,_ in pairs(game.entity_prototypes[e[sigE].name].items_to_place_this) do
txSignals[#txSignals+1]={index=#txSignals+1,count=1,signal={name=k,type="item"}}
end
txSignals[#txSignals+1]={index=#txSignals+1,count=bpent.position.x,signal={name="signal-X",type="virtual"}}
txSignals[#txSignals+1]={index=#txSignals+1,count=bpent.position.y,signal={name="signal-Y",type="virtual"}}
if bpent.direction then
txSignals[#txSignals+1]={index=#txSignals+1,count=bpent.direction, signal={name="signal-D",type="virtual"}}
end
if bpent.recipe then
txSignals[#txSignals+1]={index=#txSignals+1,count=global.recipemap[bpent.recipe] or 0, signal={name="signal-R",type="virtual"}}
end
--TODO: other entity-specific? or dedicated messages?
end
end
elseif command == 7 then -- Get Print Name, binary encoded, LSB leftmost
if write == 1 then
local deplNet=deployer.get_circuit_network(defines.wire_type.red)
or deployer.get_circuit_network(defines.wire_type.green)
local signals=deplNet.signals
local str=""
for i=0,30 do
local endOfString=true
for _,sig in pairs(signals) do
local sigbit = bit32.extract(sig.count,i)
if sig.signal.type=="virtual" and sigbit==1 then
endOfString=false
str=str .. sigchar(sig.signal.name)
end
end
if endOfString then break end
end
printStack.label=str
else
local s = string.upper(printStack.label or "")
local letters = {}
local i=1
while s do
local c
if #s > 1 then
c,s=s:sub(1,1),s:sub(2)
else
c,s=s,nil
end
letters[c]=(letters[c] or 0)+i
i=i*2
end
for c,i in pairs(letters) do
txSignals[#txSignals+1]={index=#txSignals+1,count=i,signal={name=charsig(c),type="virtual"}}
end
end
end
--game.print(serpent.block(txSignals))
digitizer.get_or_create_control_behavior().parameters={enabled=true, parameters = txSignals}
end
local function onTickDigitizer(digitizer)
local pairedEnt = global.digitizertargets[digitizer.unit_number]
if not (pairedEnt and pairedEnt.valid) then
global.digitizertargets[digitizer.unit_number] = nil
digitizer.get_or_create_control_behavior().parameters=nil
return
end
if pairedEnt.name == "blueprint-deployer" then
onTickDigitizerDeployer(digitizer,pairedEnt)
--elseif pairedEnt.name == "blueprint-printer" then
--TODO: more specific blueprint page manipulation?
--elseif pairedEnt.name == "??radar??" then
--TODO: radar data?
--elseif pairedEnt.name == "???" then
--TODO: ???
end
end
local function onTickDigitizers(event)
if global.digitizers then
for id,digitizer in pairs(global.digitizers) do
if digitizer.valid and digitizer.name == "blueprint-digitizer" then
onTickDigitizer(digitizer)
else
global.digitizers[id]=nil
end
end
end
end
function getConnectedEntity(ent)
local connectedEntities = ent.surface.find_entities({{x = ent.position.x - 1, y = ent.position.y - 1}, {x = ent.position.x + 1, y = ent.position.y + 1}})
for _,entity in pairs(connectedEntities) do
if (entity.valid and (entity.name == "blueprint-deployer")) then
return entity
end
end
end
local function onBuiltDigitizer(event)
local ent = event.created_entity
if not ent or not ent.valid then return end
if ent.name == "blueprint-digitizer" then
if not global.digitizers then global.digitizers={} end
if not global.digitizerprints then global.digitizerprints={} end
if not global.digitizertargets then global.digitizertargets={} end
ent.operable = false
table.insert(global.digitizers,ent)
global.digitizertargets[ent.unit_number]=getConnectedEntity(ent)
global.digitizerprints[ent.unit_number]=nil
end
end
return {
[defines.events.on_tick]=onTickDigitizers,
[defines.events.on_built_entity]=onBuiltDigitizer,
[defines.events.on_robot_built_entity]=onBuiltDigitizer,
}