View difference between Paste ID: K4DU8d3n and bxM5eg3r
SHOW: | | - or go back to the newest paste.
1
-- Юзер-дефинед вариаблы :3
2
3
-- Начальное положение робота:
4
coordx = 785
5
coordy = 60
6
coordz = 3993
7
orLine = "z" -- линия движения: x или z
8
orPos = -1 -- 1 значит pos, -1 значит neg по orLine
9
10
retries = 3 -- попытки движения робота
11
12
INV_SIZE = 16 -- вместимость инвертаря
13
SLEEP_TIME = 600 -- задержка между уборками полей
14
15
-- <velosipedy_na_kostylah>
16
17
-- Подключение апи и прочее задание вариаблов
18
19
savedretr = retries
20
21
savedx = coordx
22
savedy = coordy
23
savedz = coordz
24
savedline = orLine
25
savedpos = orPos
26
27
robot = require("robot")
28
computer = require("computer")
29
io = require("io")
30
string = require("string")
31
component = require("component")
32
geolyzer = component.geolyzer
33
invcon = component.inventory_controller
34
35
-- Копипастнутый split
36
function split(str, pat)
37
   local t = {}  -- NOTE: use {n = 0} in Lua-5.0
38
   local fpat = "(.-)" .. pat
39
   local last_end = 1
40
   local s, e, cap = str:find(fpat, 1)
41
   while s do
42
      if s ~= 1 or cap ~= "" then
43
   table.insert(t,cap)
44
      end
45
      last_end = e+1
46
      s, e, cap = str:find(fpat, last_end)
47
   end
48
   if last_end <= #str then
49
      cap = str:sub(last_end)
50
      table.insert(t, cap)
51
   end
52
   return t
53
end
54
55
-- Навигатсия
56
function forward()
57
 if robot.forward() == true then
58
  if orLine == "x" then coordx = coordx + orPos end
59
  if orLine == "z" then coordz = coordz + orPos end
60
  retries = savedretr
61
 else
62
  retry("f")
63
 end
64
end
65
66
function back()
67
 if robot.back() == true then
68
  if orLine == "x" then coordx = coordx - orPos end
69
  if orLine == "z" then coordz = coordz - orPos end
70
  retries = savedretr
71
 else
72
  retry("b")
73
 end
74
end
75
76
function turnLeft() -- интересно, а поворот робот может провалить?
77
 robot.turnLeft() 
78
 if orLine == "x" then
79
  orLine = "z"
80
  orPos = orPos - 2 * orPos -- инвертируем
81
  return 0
82
 end
83
 if orLine == "z" then
84
  orLine = "x"
85
  return 0
86
 end
87
end
88
89
function turnRight()
90
 robot.turnRight()
91
 if orLine == "x" then
92
  orLine = "z"
93
  return 0
94
 end
95
 if orLine == "z" then
96
  orLine = "x"
97
  orPos = orPos - 2 * orPos 
98
  return 0
99
 end
100
end
101
102
function turnAround()
103
 robot.turnAround()
104
 orPos = orPos - 2 * orPos
105
end
106
107
function up()
108
 if robot.up() == true then
109
  coordy = coordy + 1
110
  retries = savedretr
111
 else
112
  retry("u")
113
 end
114
end
115
116
function down()
117
 if robot.down() == true then
118
  coordy = coordy - 1
119
  retries = savedretr
120
 else
121
  retry("d")
122
 end
123
end
124
125
function retry(ftocall)
126
 if retries > 0 then
127
  retries = retries - 1
128
  computer.beep()
129
  os.sleep(5) -- если энтитя мешается, ждем, вдруг отойдет
130
  if ftocall == "f" then 
131
   forward()
132
  end
133
  if ftocall == "b" then
134
   back()
135
  end
136
  if ftocall == "u" then
137
   up()
138
  end
139
  if ftocall == "d" then
140
   down()
141
  end
142
 else
143
  print("Не могу продолжать движение по причинам, от меня не зависящим.")
144
  error()
145
 end
146
end
147
148
function orientTo(destline,destpos)
149
 if destline == orLine and destpos ~= orPos then
150
  turnAround()
151
  return 0
152
 end
153
 if destline ~= orLine and destpos == orPos then
154
  if orLine == "x" then turnRight() else turnLeft() end
155
  return 0
156
 end
157
 if destline ~= orLine and destpos ~= orPos then
158
  if orLine == "x" then turnLeft() else turnRight() end
159
  return 0
160
 end
161
end
162
163
function moveTo(destx,desty,destz)
164
 while desty ~= coordy do
165
  if desty < coordy then down() end
166
  if desty > coordy then up() end
167
 end
168
 if destx ~= coordx then orientTo("x",1) end
169
 while destx ~= coordx do
170
  if destx < coordx then back() end
171
  if destx > coordx then forward() end
172
 end
173
 if destz ~= coordz then orientTo("z",1) end
174
 while destz ~= coordz do
175
  if destz < coordz then back() end
176
  if destz > coordz then forward() end
177
 end
178
end 
179
180
function findXY(spx,spz,apx,apz) -- находим длину и ширину поля
181
 if apx > spx then
182
  widthX = apx - spx + 1 
183
 else
184
  widthX = spx - apx + 1
185
 end
186
 if apz > spz then
187
  widthZ = apz - spz + 1
188
 else
189
  widthZ = spz - apz + 1
190
 end
191
 return widthX, widthZ
192
end
193
194
-- Фермофункстии
195
196
function takeBlock(blockName,metadata,itemName,isUse)
197
 block = geolyzer.analyze(0)
198
 if block.metadata == metadata or metadata == -1 then
199
  metaChecked = true
200
 else
201
  metaChecked = false
202
 end -- так проще, чем писать еще or в if ниже
203
 if block.name == blockName and metaChecked == true then
204
  if isUse == "true" then
205
   robot.useDown()
206
  else
207
   robot.swingDown()
208
  end
209
  if itemName ~= "nil" then
210
   placeItem(itemName)
211
  end
212
 end
213
end
214
215
function placeItem(itemtp)
216
 asgCounter = INV_SIZE
217
 item = invcon.getStackInInternalSlot(robot.select())
218
 if item ~= nil and item.name == itemtp then
219
  robot.placeDown()
220
 else
221
  while asgCounter > 0 do
222
   item = invcon.getStackInInternalSlot(asgCounter)
223
   if item ~= nil and item.name == itemtp then
224
    robot.select(asgCounter)
225
    robot.placeDown()
226
    break
227
   else
228
    asgCounter = asgCounter - 1
229
   end
230
  end
231
 end
232
end
233
234
function harvestField(num)
235
 moveTo(startPointX[num],fieldY[num]+1,startPointZ[num])
236
 wx, wz = findXY(startPointX[num],startPointZ[num],anotherPointX[num],anotherPointZ[num])
237
 if wx > wz then -- костыли-костылики
238
  anotherPointX[num] = anotherPointX[num] - 1
239
  wx = wx - 1
240
  kostylFlag = false
241
 else
242
  if wx == wz then -- Костыль для костыля :O
243
   kostylFlag = true
244
  else
245
   kostylFlag = false
246
  end
247
  anotherPointZ[num] = anotherPointZ[num] - 1
248
  wz = wz - 1
249
 end
250
 counter = wx * wz -- площадь поля
251
 if wx > wz and kostylFlag == false then
252
  if anotherPointX[num] > startPointX[num] then
253
   orPosTmp = 1
254
  else
255
   orPosTmp = -1
256
  end
257
  while counter > 0 do
258
   orientTo("x",orPosTmp)
259
   length = wx
260
   while length > 0 do
261
    takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
262
    forward()
263
    if coordx == startPointX[num] or coordx == anotherPointX[num] + 1 then
264
     takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
265
    end
266
    length = length - 1
267
    counter = counter - 1
268
   end
269
   if counter > 0 then
270
    if startPointZ[num] < anotherPointZ[num] then
271
     moveTo(coordx,coordy,coordz+1)
272
    else
273
     moveTo(coordx,coordy,coordz-1)
274
    end
275
    orPosTmp = orPosTmp - 2 * orPosTmp
276
   end
277
  end
278
 else
279
  if anotherPointZ[num] > startPointZ[num] then
280
   orPosTmp = 1
281
  else
282
   orPosTmp = -1
283
  end
284
  while counter > 0 do   
285
   orientTo("z",orPosTmp)
286
   length = wz
287
   while length > 0 do
288
    takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
289
    forward()
290
    if coordz == startPointZ[num] or coordz == anotherPointZ[num] + 1 then
291
     takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
292
    end    
293
    length = length - 1
294
    counter = counter - 1
295
   end
296
   if counter > 0 then
297
    if startPointX[num] < anotherPointX[num] then
298
     moveTo(coordx+1,coordy,coordz)
299
    else
300
     moveTo(coordx-1,coordy,coordz)
301
    end
302
    orPosTmp = orPosTmp - 2 * orPosTmp
303
   end
304
  end
305
 end
306
end
307
 
308
-- Читаем конфиг
309
310
startPointX = {}
311
startPointZ = {}
312
anotherPointX = {}
313
anotherPointZ = {}
314
fieldY = {}
315
blockToTake = {}
316
itemToPlant = {}
317
fullGrownState = {}
318
isRight = {}
319
320
function getFields()
321
 counter = 1 
322
 for line in io.lines("/fields.txt") do
323
  lineTable = split(line,",")
324
  startPointX[counter] = tonumber(lineTable[1])
325
  startPointZ[counter] = tonumber(lineTable[2])
326
  anotherPointX[counter] = tonumber(lineTable[3])
327
  anotherPointZ[counter] = tonumber(lineTable[4])
328
  fieldY[counter] = tonumber(lineTable[5])
329
  blockToTake[counter] = lineTable[6]
330
  itemToPlant[counter] = lineTable[7]
331
  fullGrownState[counter] = tonumber(lineTable[8])
332-
  isRight[counter] = lineTable[9]
332+
  if lineTable[9] == nil then
333
   isRight[counter] = "false"
334
  else
335
   isRight[counter] = lineTable[9]
336
  end
337
  counter = counter + 1
338
 end
339
end
340
341
while true do
342
 getFields()
343
 for foobar=1, #startPointX do
344
  harvestField(foobar)
345
 end
346
 moveTo(savedx,coordy,savedz)
347
 moveTo(coordx,savedy,coordz)
348
 orientTo(savedline,savedpos)
349
 os.sleep(SLEEP_TIME)
350
end
351
352
-- </velosipedy_na_kostylah>