Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Юзер-дефинед вариаблы :3
- -- Начальное положение робота:
- coordx = 785
- coordy = 60
- coordz = 3993
- orLine = "z" -- линия движения: x или z
- orPos = -1 -- 1 значит pos, -1 значит neg по orLine
- retries = 3 -- попытки движения робота
- INV_SIZE = 16 -- вместимость инвертаря
- SLEEP_TIME = 600 -- задержка между уборками полей
- -- <velosipedy_na_kostylah>
- -- Подключение апи и прочее задание вариаблов
- savedretr = retries
- savedx = coordx
- savedy = coordy
- savedz = coordz
- savedline = orLine
- savedpos = orPos
- robot = require("robot")
- computer = require("computer")
- io = require("io")
- string = require("string")
- component = require("component")
- geolyzer = component.geolyzer
- invcon = component.inventory_controller
- -- Копипастнутый split
- function split(str, pat)
- local t = {} -- NOTE: use {n = 0} in Lua-5.0
- local fpat = "(.-)" .. pat
- local last_end = 1
- local s, e, cap = str:find(fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(t,cap)
- end
- last_end = e+1
- s, e, cap = str:find(fpat, last_end)
- end
- if last_end <= #str then
- cap = str:sub(last_end)
- table.insert(t, cap)
- end
- return t
- end
- -- Навигатсия
- function forward()
- if robot.forward() == true then
- if orLine == "x" then coordx = coordx + orPos end
- if orLine == "z" then coordz = coordz + orPos end
- retries = savedretr
- else
- retry("f")
- end
- end
- function back()
- if robot.back() == true then
- if orLine == "x" then coordx = coordx - orPos end
- if orLine == "z" then coordz = coordz - orPos end
- retries = savedretr
- else
- retry("b")
- end
- end
- function turnLeft() -- интересно, а поворот робот может провалить?
- robot.turnLeft()
- if orLine == "x" then
- orLine = "z"
- orPos = orPos - 2 * orPos -- инвертируем
- return 0
- end
- if orLine == "z" then
- orLine = "x"
- return 0
- end
- end
- function turnRight()
- robot.turnRight()
- if orLine == "x" then
- orLine = "z"
- return 0
- end
- if orLine == "z" then
- orLine = "x"
- orPos = orPos - 2 * orPos
- return 0
- end
- end
- function turnAround()
- robot.turnAround()
- orPos = orPos - 2 * orPos
- end
- function up()
- if robot.up() == true then
- coordy = coordy + 1
- retries = savedretr
- else
- retry("u")
- end
- end
- function down()
- if robot.down() == true then
- coordy = coordy - 1
- retries = savedretr
- else
- retry("d")
- end
- end
- function retry(ftocall)
- if retries > 0 then
- retries = retries - 1
- computer.beep()
- os.sleep(5) -- если энтитя мешается, ждем, вдруг отойдет
- if ftocall == "f" then
- forward()
- end
- if ftocall == "b" then
- back()
- end
- if ftocall == "u" then
- up()
- end
- if ftocall == "d" then
- down()
- end
- else
- print("Не могу продолжать движение по причинам, от меня не зависящим.")
- error()
- end
- end
- function orientTo(destline,destpos)
- if destline == orLine and destpos ~= orPos then
- turnAround()
- return 0
- end
- if destline ~= orLine and destpos == orPos then
- if orLine == "x" then turnRight() else turnLeft() end
- return 0
- end
- if destline ~= orLine and destpos ~= orPos then
- if orLine == "x" then turnLeft() else turnRight() end
- return 0
- end
- end
- function moveTo(destx,desty,destz)
- while desty ~= coordy do
- if desty < coordy then down() end
- if desty > coordy then up() end
- end
- if destx ~= coordx then orientTo("x",1) end
- while destx ~= coordx do
- if destx < coordx then back() end
- if destx > coordx then forward() end
- end
- if destz ~= coordz then orientTo("z",1) end
- while destz ~= coordz do
- if destz < coordz then back() end
- if destz > coordz then forward() end
- end
- end
- function findXY(spx,spz,apx,apz) -- находим длину и ширину поля
- if apx > spx then
- widthX = apx - spx + 1
- else
- widthX = spx - apx + 1
- end
- if apz > spz then
- widthZ = apz - spz + 1
- else
- widthZ = spz - apz + 1
- end
- return widthX, widthZ
- end
- -- Фермофункстии
- function takeBlock(blockName,metadata,itemName,isUse)
- block = geolyzer.analyze(0)
- if block.metadata == metadata or metadata == -1 then
- metaChecked = true
- else
- metaChecked = false
- end -- так проще, чем писать еще or в if ниже
- if block.name == blockName and metaChecked == true then
- if isUse == "true" then
- robot.useDown()
- else
- robot.swingDown()
- end
- if itemName ~= "nil" then
- placeItem(itemName)
- end
- end
- end
- function placeItem(itemtp)
- asgCounter = INV_SIZE
- item = invcon.getStackInInternalSlot(robot.select())
- if item ~= nil and item.name == itemtp then
- robot.placeDown()
- else
- while asgCounter > 0 do
- item = invcon.getStackInInternalSlot(asgCounter)
- if item ~= nil and item.name == itemtp then
- robot.select(asgCounter)
- robot.placeDown()
- break
- else
- asgCounter = asgCounter - 1
- end
- end
- end
- end
- function harvestField(num)
- moveTo(startPointX[num],fieldY[num]+1,startPointZ[num])
- wx, wz = findXY(startPointX[num],startPointZ[num],anotherPointX[num],anotherPointZ[num])
- if wx > wz then -- костыли-костылики
- anotherPointX[num] = anotherPointX[num] - 1
- wx = wx - 1
- kostylFlag = false
- else
- if wx == wz then -- Костыль для костыля :O
- kostylFlag = true
- else
- kostylFlag = false
- end
- anotherPointZ[num] = anotherPointZ[num] - 1
- wz = wz - 1
- end
- counter = wx * wz -- площадь поля
- if wx > wz and kostylFlag == false then
- if anotherPointX[num] > startPointX[num] then
- orPosTmp = 1
- else
- orPosTmp = -1
- end
- while counter > 0 do
- orientTo("x",orPosTmp)
- length = wx
- while length > 0 do
- takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
- forward()
- if coordx == startPointX[num] or coordx == anotherPointX[num] + 1 then
- takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
- end
- length = length - 1
- counter = counter - 1
- end
- if counter > 0 then
- if startPointZ[num] < anotherPointZ[num] then
- moveTo(coordx,coordy,coordz+1)
- else
- moveTo(coordx,coordy,coordz-1)
- end
- orPosTmp = orPosTmp - 2 * orPosTmp
- end
- end
- else
- if anotherPointZ[num] > startPointZ[num] then
- orPosTmp = 1
- else
- orPosTmp = -1
- end
- while counter > 0 do
- orientTo("z",orPosTmp)
- length = wz
- while length > 0 do
- takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
- forward()
- if coordz == startPointZ[num] or coordz == anotherPointZ[num] + 1 then
- takeBlock(blockToTake[num],fullGrownState[num],itemToPlant[num],isRight[num])
- end
- length = length - 1
- counter = counter - 1
- end
- if counter > 0 then
- if startPointX[num] < anotherPointX[num] then
- moveTo(coordx+1,coordy,coordz)
- else
- moveTo(coordx-1,coordy,coordz)
- end
- orPosTmp = orPosTmp - 2 * orPosTmp
- end
- end
- end
- end
- -- Читаем конфиг
- startPointX = {}
- startPointZ = {}
- anotherPointX = {}
- anotherPointZ = {}
- fieldY = {}
- blockToTake = {}
- itemToPlant = {}
- fullGrownState = {}
- isRight = {}
- function getFields()
- counter = 1
- for line in io.lines("/fields.txt") do
- lineTable = split(line,",")
- startPointX[counter] = tonumber(lineTable[1])
- startPointZ[counter] = tonumber(lineTable[2])
- anotherPointX[counter] = tonumber(lineTable[3])
- anotherPointZ[counter] = tonumber(lineTable[4])
- fieldY[counter] = tonumber(lineTable[5])
- blockToTake[counter] = lineTable[6]
- itemToPlant[counter] = lineTable[7]
- fullGrownState[counter] = tonumber(lineTable[8])
- if lineTable[9] == nil then
- isRight[counter] = "false"
- else
- isRight[counter] = lineTable[9]
- end
- counter = counter + 1
- end
- end
- while true do
- getFields()
- for foobar=1, #startPointX do
- harvestField(foobar)
- end
- moveTo(savedx,coordy,savedz)
- moveTo(coordx,savedy,coordz)
- orientTo(savedline,savedpos)
- os.sleep(SLEEP_TIME)
- end
- -- </velosipedy_na_kostylah>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement