From 60ff78619aa66e440b674de7f78ffb2e9468dfd1 Mon Sep 17 00:00:00 2001 From: Igor Timofeev Date: Thu, 17 Nov 2016 03:01:18 +0300 Subject: [PATCH] afaef --- .DS_Store | Bin 18436 -> 18436 bytes Applications/.DS_Store | Bin 69636 -> 69636 bytes Applications/Robot/Diamonds.lua | 140 ++++++----- Applications/Robot/GeoMiner.lua | 413 ++++++++++++++++++++++++++++++++ Applications/Robot/robotAPI.lua | 361 +++++++++++++++++++++++++--- 5 files changed, 825 insertions(+), 89 deletions(-) create mode 100644 Applications/Robot/GeoMiner.lua diff --git a/.DS_Store b/.DS_Store index cdb54b516b044bb1cc8e4a07ca6e23252099c0dc..e33283b269b96a3473c2cbb5c054ff411e5b6202 100644 GIT binary patch delta 1209 zcmcJOS!_&E7{~8_6z6cIXJ)9*bVNEl{7gOz&PBpbuEwxn8 ziDQkO5Fsd|u|D9*gG3|~58}a-2MLjg^@VfqZ6b|&bRTYVzVDuM?*EtH*BL=)1U=Ik z5_leq^0M(0I%3op@;556cxE)o7Hbk^y<}Oy-=fTG3ItaLm4McIM@`@ zt5fAHVuXiQ)-^RYDxsFJUe2}V5%!GKsF%<6hg%k`Q$l}!tB{Z?wNn@fC;^gEuqK%= zbdKf*lcVmn^j3N=eUZLOKct`1FAz`+hYSnsNPz=s$VLvPBM(I=#aztC0{E~THK>Ij ztFaF25k?EPU>A0y3;V!v3a4=v=WrAEa32qNm#K27ZPx5L@v@iav-7;mT+g3dogIk+ zrEHfS)QA{mQcPXjTsAimc$q<4${t&)3XcuayBd@LWrOvuprL|fae6mb78FV;8=@}@ zY(***M)Z$eHZLU%T7F49+~+j&Ya^#rr(r4z;6(}Mh>Y`4jtVSAwMe;2Bn+Y+4cLHI zv|%GQqf;c^gS}eP!#Ij#IDreeh)cMPE4YQ*xPxBY#bZ3d(`e49tFk#e)03Q@k>2h} z-kg<|=1HEGIgP)Vn9Ch5OSII!+%U-Om3d)YF&}Hr;?D7t_$QXy@qyBqi5cSu7EbL9 zAe^?LpKw~GpK#jN{=#XcKfjC_)BA=p*te%Dyn-Wy^-EYAEnR2 zt#8tI00zWiFic2-4P)TOWMm*yu+PN|%oOxz^|7xK^lSULHwyAw(SaSmDg$TA1bx;sOlNg<5F*@xc;5Ka60v3VV${7y*XGW`Y8ku%lGpeIoTE-M@sao11jHkZ=Sci58ZvZJBPu_ z=duW2JvF_n-(>2KVP;FbO;xHif2&^Bqy=k(y2c*JgPkchRjm}A1uZ)LHCZ+eBso;Y z7Y=UMnSW@b)1@fB`d~<7;h{^@+={xo!M{OoV47+0SZ0=@u4&U-!oj8xD={q_tme*C z)QUh;W1}8w4V&Q}+U(6!)oSr{sXyGhyjc&?SkH&v&!@50ie90niJ|1=g7yo1g>y2G zvZMswNN=S9>9h1z`X+ssen3VnCLkxpBT5Lo! zwqiRvumk(hi=#LOj9X5d6nQEe%QUxLVWSM^M3+plvuML3u_QMXHrjAeEWLTu9Ybafp3N_y zt7O9m(JgY(Rgg`Feu+Nrb6WY0Nja72$RUlzSWF5_QHF9G zP}+_CIEWq`BBdvA5~pw)mv9+Za23~Z4-q`TLp;J0p*`Y_y{=e2Iqt-4PgbWpvBQ&@ z?M}?e&E+rB@_35N7AbM8iy9SItnk9o3%K3t;m)ZU`~#cbHDL0E{Ed3Qg_&b${$ZdK zonfF8<-eg5mA|1Am4BcUr9Yta267#Yz(g>ZVL<|1n1)njV-^wSMIMT<i38;LVH_dPe|vo& z5&qd(2YaN(H4X+;2{tueaVRM!GX_jd`p-~}C#Vdhj_(pkNy)t2>EVk~<5syagQVqC zaEh>y;95@M5z#3pVSb8_Mga;@d|C{Fo#?`D?7?0V*o!_RNM~>k=WziSaUC~BoFaEq Ox3ZC7inMuqC;S9aR3VW7 diff --git a/Applications/.DS_Store b/Applications/.DS_Store index da83ef6b8c10e07b8d29ce6171ae06cf88efdb06..a9a03d4dd94bd4dc4e74ede8bc4cd7e060f3a0ef 100644 GIT binary patch delta 39 vcmZo!z|yjSWy6LSA|{rmItqryhP65h)fNT@Itu2d=93pPTW|jVf>j*=3dRjH delta 27 jcmZo!z|yjSWy6LS9A;*gIts?7Mw6#9yKnygf>j*=lBEh{ diff --git a/Applications/Robot/Diamonds.lua b/Applications/Robot/Diamonds.lua index dd67218c..23d0cd71 100644 --- a/Applications/Robot/Diamonds.lua +++ b/Applications/Robot/Diamonds.lua @@ -1,77 +1,107 @@ -local robot = require("robot") -local component = require("component") + +_G.robotAPI, package.loaded.robotAPI = nil, nil + local robotAPI = require("robotAPI") -local inventory = component.inventory_controller +local sides = require("sides") +local component = require("component") +local inventoryController = component.inventory_controller +local robotComponent = component.robot -local args = { ... } -if #args < 3 then print(" "); print("Использование: diamonds <длина> <высота> <ширина>"); print(" "); return end +----------------------------------------------------------------- -local length = args[1] -local height = args[2] -local width = args[3] +local args = {...} +if not (args[1] and args[2] and args[3]) then + print("Usage: diamonds ") + return +end -local moves = { - -} +local length, height, width, torchFrequency = tonumber(args[1]), tonumber(args[2]), tonumber(args[3]), tonumber(args[4] or 7) +local torchCount, torchSlot -local function swingForLength() - for i = 1, length do - robotAPI.move("forward") - robot.swingDown() - robot.swingUp() +----------------------------------------------------------------- + +local function getItemSlotAndCount(item) + for slot = 1, robotComponent.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack and stack.name == item then + return slot, stack.size + end end end -local function swingForUp() - for i = 1, 3 do - robotAPI.move("up") + +local function doLength() + for l = 1, length do + robotAPI.moveForward() + robotAPI.swingUp() + robotAPI.swingDown() + if l % torchFrequency == 0 and torchSlot and torchCount > 0 and robotAPI.robotPosition.y == 0 then + robotComponent.select(torchSlot) + robotComponent.place(sides.down) + torchCount = torchCount - 1 + end + end + + robotAPI.tryToDropShittyResources() + robotAPI.checkGeneratorStatus() + robotAPI.checkEnergyStatus() + robotAPI.checkToolStatus() +end + +local function doHeight() + for h = 1, height do + doLength() + for i = 1, 3 do robotAPI.moveUp() end + robotAPI.turnAround() + doLength() + robotAPI.turnAround() + if h < height then for i = 1, 3 do robotAPI.moveUp() end end end end -local function swingForDown() - for i = 1, 3 do - robotAPI.move("down") +local function doWidth() + for w = 1, width do + doHeight() + for i = 1, height * 3 * 2 - 3 do robotAPI.moveDown() end + + if w < width then + robotAPI.turnRight() + for i = 1, 3 do robotAPI.moveForward() end + robotAPI.turnLeft() + end end end ---Перебираем все ширины -for i = 1, width do - --Перебираем все высоты для конкретной ширины - for i = 1, height do - swingForLength() - robot.turnAround() - swingForUp() - swingForLength() - robot.turnAround() - swingForUp() - --Выбрасываем говно - robotAPI.dropShmot() - end +----------------------------------------------------------------- - --Возвращаемся по высоте на конкретной ширине - for i = 1, (height * 2) do - swingForDown() - end - - --Двигаемся к следующей ширине - robot.turnRight() - - for i = 1, 3 do - robotAPI.move("forward") - end - - robot.turnLeft() +-- Ставим стартовый сундук +local chestSlot = getItemSlotAndCount("minecraft:chest") +if chestSlot then + robotAPI.turnAround() + robotComponent.select(chestSlot) + robotComponent.place(sides.front) + robotAPI.turnAround() end ---Возвращаемся домой из последней ширины -robot.turnLeft() +-- Получаем слот факела +torchSlot, torchCount = getItemSlotAndCount("minecraft:torch") -for i = 1, width do - for j = 1, 3 do - robotAPI.move("forward") - end +-- Ебошим +doWidth() + +-- Пиздуем назад +robotAPI.returnToStartPoint() + +-- Скидываем говно в сундук, если он ваще был +if chestSlot then + robotAPI.turnAround() + robotAPI.dropAllResources(sides.front) + robotAPI.turnAround() end -robot.turnRight() + + + + diff --git a/Applications/Robot/GeoMiner.lua b/Applications/Robot/GeoMiner.lua new file mode 100644 index 00000000..dd46f432 --- /dev/null +++ b/Applications/Robot/GeoMiner.lua @@ -0,0 +1,413 @@ + +local computer = require("computer") +local component = require("component") +local robot = require("robot") +local event = require("event") +local sides = require("sides") +local geo = component.geolyzer +local inventoryController = component.inventory_controller + +------------------------------------------------------------------------------------------------------------------- + +local fuels = { + "minecraft:coal", + "minecraft:lava_bucket", + "minecraft:coal_block", +} + +local shittyResources = { + "minecraft:cobblestone", + "minecraft:grass", + "minecraft:dirt", + "minecraft:gravel", + "minecraft:sand", + "minecraft:sandstone", + "minecraft:torch", + "minecraft:planks", + "minecraft:fence", + "minecraft:chest", + "minecraft:monster_egg", + "minecraft:stonebrick", +} + +local oreSearchRadius = 24 +local searchPassesCount = 5 +local minimumOreHardness = 2.5 +local maximumOreHardness = 9 +local replaceToolDurabilityTrigger = 0.05 +local replaceToolRegex = "(minecraft:).+(_pickaxe)" +local rechargeTrigger = 0.1 +local dropShittyResourcesOnEmptySlots = 5 + +------------------------------------------------------------------------------------------------------------------- + +local program = {} +local robotPosition = {x = 0, y = 0, z = 0, rotation = 0} +local energyStatusCheckEnabled = true +local toolStatusCheckEnabled = true +local generatorIsAvailable = component.isAvailable("generator") + +function program.scan(radius, passes, minHardness, maxHardness) + local ores = {} + + -- Заносим все руды в массивыч руд + for pass = 1, passes do + print("Scan pass " .. pass .. " started...") + for x = -radius, radius do + for z = -radius, radius do + local stack = geo.scan(x, z, true) + for y = 1, #stack do + if stack[y] >= minHardness and stack[y] <= maxHardness then + -- Заполняем координатную сетку, если массивов еще не существует + ores[x] = ores[x] or {} + ores[x][y] = ores[x][y] or {} + + -- Если мы уже сканировали этот блок, то получаем среднюю плотность из двух значений + -- Если нет, то банально ставим полученное значение + if ores[x][y][z] then + ores[x][y][z] = (ores[x][y][z] + stack[y]) / 2 + else + ores[x][y][z] = stack[y] + end + + -- print("x=" .. x .. ", y=" .. y .. ", z=" .. z .. ", hardness=" .. stack[y]) + end + end + end + + -- Проверяем энергосостояние, а то уже один раз вылетело с ошибкой нот еаугх ЕНЕРГИ, БЛЯДЬ!!11 + program.checkEnergyStatus() + end + end + + -- Переебошиваем массив руд для более удобной работы с ним в линейном формате + -- Не забываем подчищать говнище за собой, а то роботы не резиновые + local newOres = {} + for x in pairs(ores) do + for y in pairs(ores[x]) do + for z in pairs(ores[x][y]) do + table.insert(newOres, {x = robotPosition.x + x, y = robotPosition.y + y - 33, z = robotPosition.z + z}) + ores[x][y][z] = nil + end + ores[x][y] = nil + end + ores[x]= nil + end + + return newOres +end + +local function getHardness(x, z) + local stack = geo.scan(x, z) + for i = 1, #stack do + print("i=" .. i .. ", val=" .. stack[i]) + event.pull("key_down") + end +end + +function program.move(direction) + while true do + local swingSuccess, swingReason = component.robot.swing(direction) + if swingSuccess or swingReason == "air" then + local moveSuccess, moveReason = component.robot.move(direction) + if moveSuccess then + break + end + else + if swingReason == "block" then + print("Unbreakable block detected, going to base") + program.returnToBase() + os.exit() + end + end + end + + if direction == sides.front or direction == sides.back then + local directionOffset = direction == sides.front and 1 or -1 + + if robotPosition.rotation == 0 then + robotPosition.x = robotPosition.x + directionOffset + elseif robotPosition.rotation == 1 then + robotPosition.z = robotPosition.z + directionOffset + elseif robotPosition.rotation == 2 then + robotPosition.x = robotPosition.x - directionOffset + elseif robotPosition.rotation == 3 then + robotPosition.z = robotPosition.z - directionOffset + end + elseif direction == sides.up or direction == sides.down then + local directionOffset = direction == sides.up and 1 or -1 + robotPosition.y = robotPosition.y + directionOffset + end +end + + +function program.returnToBase() + program.gotoPoint(0, robotPosition.y, 0) + program.turnToRequiredRotation(0) + program.gotoPoint(0, -2, 0) + program.tryToDropShittyResources() + program.gotoPoint(0, 0, 0) + program.dropAllResoucesIntoBaseChest() +end + +function program.getSlotWithFuel() + for slot = 1, component.robot.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + for fuel = 1, #fuels do + if stack.name == fuels[fuel] then + return slot + end + end + end + end +end + +function program.tryToRechargeByGenerator() + if generatorIsAvailable then + if component.generator.count() == 0 then + print("Generator is empty, trying to find some fuel in inventory") + local slot = program.getSlotWithFuel() + if slot then + print("Found slot with fuel: " .. slot) + local oldSlot = robot.select(slot) + component.generator.insert() + robot.select(oldSlot) + return + else + print("Slot with fuel not found") + end + end + end +end + +function program.checkEnergyStatus() + if computer.energy() / computer.maxEnergy() < rechargeTrigger then + print("Low energy level detected") + energyStatusCheckEnabled = false + -- Запоминаем старую позицию, шобы суда вернуться + local oldPosition = {x = robotPosition.x, y = robotPosition.y, z = robotPosition.z, rotation = robotPosition.rotation} + -- Пиздуем на базу за зарядкой + program.returnToBase() + -- Заряжаемся, пока энергия не достигнет более-менее максимума + while computer.energy() / computer.maxEnergy() < 0.99 do + print("Charging up: " .. math.floor(computer.energy() / computer.maxEnergy() * 100) .. "%") + os.sleep(1) + end + -- Пиздуем обратно + program.gotoPoint(oldPosition.x, oldPosition.y, oldPosition.z) + program.turnToRequiredRotation(oldPosition.rotation) + energyStatusCheckEnabled = true + end +end + +function program.turn(clockwise) + component.robot.turn(clockwise) + robotPosition.rotation = robotPosition.rotation + (clockwise and 1 or -1) + if robotPosition.rotation > 3 then + robotPosition.rotation = 0 + elseif robotPosition.rotation < 0 then + robotPosition.rotation = 3 + end +end + +function program.turnToRequiredRotation(requiredRotation) + local difference = robotPosition.rotation - requiredRotation + + if difference ~= 0 then + local fastestWay + if difference > 0 then + if difference > 2 then fastestWay = true else fastestWay = false end + else + if -difference > 2 then fastestWay = false else fastestWay = true end + end + + while robotPosition.rotation ~= requiredRotation do + program.turn(fastestWay) + end + end +end + +function program.gotoPoint(xTarget, yTarget, zTarget) + local xDistance = xTarget - robotPosition.x + local yDistance = yTarget - robotPosition.y + local zDistance = zTarget - robotPosition.z + + if yDistance ~= 0 then + local direction = yDistance > 0 and sides.up or sides.down + for i = 1, math.abs(yDistance) do program.move(direction) end + end + + if xDistance ~= 0 then + program.turnToRequiredRotation(xDistance > 0 and 0 or 2) + for i = 1, math.abs(xDistance) do program.move(sides.front) end + end + + if zDistance ~= 0 then + program.turnToRequiredRotation(zDistance > 0 and 1 or 3) + for i = 1, math.abs(zDistance) do program.move(sides.front) end + end + + -- Если количество пустых слотов меньше, чем лимит пустых слотов, + -- то выбрасываем весь дерьмовый шмот, указанный в массиве дерьмового шмота + program.tryToDropShittyResources() + + -- Если включена проверка энергосостояния, то делаем ее и возвращаемся на базу + -- для подзарядки, если требуется + if energyStatusCheckEnabled then program.checkEnergyStatus() end + + -- Проверяем также состояние инструментов + if toolStatusCheckEnabled then program.checkToolStatus() end + + -- А еще заправляем генератор + program.tryToRechargeByGenerator() +end + +function program.findNearestOre(ores) + local nearest + for i = 1, #ores do + local distance = math.sqrt((ores[i].x - robotPosition.x) ^ 2 + (ores[i].y - robotPosition.y) ^ 2 + (ores[i].z - robotPosition.z) ^ 2) + if not nearest or distance < nearest.distance then + nearest = {x = ores[i].x, y = ores[i].y, z = ores[i].z, distance = distance, oreIndex = i} + end + end + return nearest +end + +function program.scanAndDig(radius, passes, minHardness, maxHardness, bedrockLocation) + local ores = program.scan(radius, passes, minHardness, maxHardness) + print("Scanning finished, count of resources to mine: " .. #ores) + while #ores > 0 do + local nearest = program.findNearestOre(ores) + if nearest.y >= bedrockLocation and nearest.y < 0 then + -- print("Found next nearest ore: (" .. nearest.x .. "; " .. nearest.y .. "; " .. nearest.z .. ")") + program.gotoPoint(nearest.x, nearest.y, nearest.z) + end + table.remove(ores, nearest.oreIndex) + end +end + +function program.getBedrockLocation() + while true do + local success, reason = component.robot.swing(sides.down) + if success or reason == "air" then + program.move(sides.down) + else + if reason == "block" then + print("Bedrock location is: " .. robotPosition.y) + return robotPosition.y + end + end + end +end + +function program.getEmptySlotsCount() + local count = 0 + for slot = 1, robot.inventorySize() do + count = count + (robot.count(slot) == 0 and 1 or 0) + end + return count +end + +function program.tryToDropShittyResources() + if program.getEmptySlotsCount() < dropShittyResourcesOnEmptySlots then + print("Trying to drop all shitty resources to free some slots for mining") + for slot = 1, robot.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + for i = 1, #shittyResources do + if stack.name == shittyResources[i] then + robot.select(slot) + robot.drop() + end + end + end + end + + if program.getEmptySlotsCount() < dropShittyResourcesOnEmptySlots - 2 then + local oldPosition = {x = robotPosition.x, y = robotPosition.y, z = robotPosition.z, rotation = robotPosition.rotation} + program.returnToBase() + program.gotoPoint(oldPosition.x, oldPosition.y, oldPosition.z) + program.turnToRequiredRotation(oldPosition.rotation) + end + + robot.select(1) + end +end + +function program.dropAllResoucesIntoBaseChest() + print("Dropping all mined resources to chest on base") + for slot = 1, robot.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + if not string.match(stack.name, replaceToolRegex) then + robot.select(slot) + robot.drop() + end + end + end + robot.select(1) +end + +function program.checkToolStatus() + if robot.durability() < replaceToolDurabilityTrigger then + print("Equipped tool durability lesser then " .. replaceToolDurabilityTrigger) + local success = false + + for slot = 1, robot.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + if string.match(stack.name, replaceToolRegex) and stack.damage / stack.maxDamage < replaceToolDurabilityTrigger then + local oldSlot = robot.select(slot) + inventoryController.equip() + robot.select(oldSlot) + success = true + break + end + end + end + + if not success and toolStatusCheckEnabled then + toolStatusCheckEnabled = false + returnToBase() + print("No one useable tool are found in inventory, going back to base") + os.exit() + else + print("Successfullty switched tool to another from inventory") + end + end +end + +------------------------------------------------------------------------------------------------------------------- + +-- getHardness(1, 0) +-- program.checkToolStatus() +-- program.move(sides.front) + +-- Выбираем сразу первый слотик по умолчанию +robot.select(1) +-- Определяем позицию говна +print("Going deeper to determine bedrock location...") +local bedrockLocation = program.getBedrockLocation() + 4 +-- Ебошим стартовую точку после определения позиции говна, и если она слишком высоко, то робот начнет как раз от нее же +local startPoint = bedrockLocation + 32 +if startPoint > 0 then startPoint = 0 end + +-- Пиздуем на старт и вкалываем до посинения +program.gotoPoint(0, startPoint, 0) +program.scanAndDig(oreSearchRadius, searchPassesCount, minimumOreHardness, maximumOreHardness, bedrockLocation) + +-- В конце возвращаемся на начало и ожидаем, че уж там +program.returnToBase() + + + + + + + + + + + + diff --git a/Applications/Robot/robotAPI.lua b/Applications/Robot/robotAPI.lua index 9796ac2f..c8bf1606 100644 --- a/Applications/Robot/robotAPI.lua +++ b/Applications/Robot/robotAPI.lua @@ -1,61 +1,354 @@ -local robot = require("robot") + +local computer = require("computer") +local event = require("event") +local sides = require("sides") local component = require("component") -local inventory = component.inventory_controller + +local robotComponent = component.robot +local inventoryController = component.inventory_controller local robotAPI = {} ---------------------------------------------------------------------------------------------------------------------------------------- +-------------------------------------------------- Some variables that user can change for himself -------------------------------------------------- -local countOfTries = 20 -local sleepDelay = 0.06 +robotAPI.fuels = { + "minecraft:coal", + "minecraft:lava_bucket", + "minecraft:coal_block", +} -local itemsToDrop = { +robotAPI.shittyResources = { "minecraft:cobblestone", + "minecraft:grass", "minecraft:dirt", "minecraft:gravel", "minecraft:sand", + "minecraft:sandstone", + "minecraft:torch", + "minecraft:planks", + "minecraft:fence", + "minecraft:chest", + "minecraft:monster_egg", + "minecraft:stonebrick", } -local directions = { - up = { move = robot.up, swing = robot.swingUp}, - down = { move = robot.down, swing = robot.swingDown}, - forward = { move = robot.forward, swing = robot.swing}, +robotAPI.tools = { + "minecraft:diamond_pickaxe", + "minecraft:iron_pickaxe", } -function robotAPI.move(direction) - local tries = 0 - while tries <= countOfTries do - directions[direction].swing() - local success, reason = directions[direction].move() - os.sleep(sleepDelay) - if success then - return - else - print("Не могу двигаться " .. direction .. ": " .. reason) - end - tries = tries + 1 - end - error("Количество попыток перемещения " .. direction .. " исчерпано, программа завершена") +robotAPI.replaceToolOnDurabilityLesserThen = 0.05 +robotAPI.returnToHomeOnEneryLowerThen = 0.1 +robotAPI.dropShittyResourcesOnCountOfEmptySlotsLesserThen = 4 + +-------------------------------------------------- API-related stuff -------------------------------------------------- + +robotAPI.robotPosition = {x = 0, y = 0, z = 0, rotation = 0} + +function robotAPI.getRobotPosition() + return { + x = robotAPI.robotPosition.x, + y = robotAPI.robotPosition.y, + z = robotAPI.robotPosition.z, + rotation =robotAPI.robotPosition.rotation + } end -function robotAPI.dropShmot() - for slot = 1, robot.inventorySize() do - local item = inventory.getStackInInternalSlot(slot) - if item then - for i = 1, #itemsToDrop do - if item.name == itemsToDrop[i] then - robot.select(slot) - robot.drop() +-------------------------------------------------- Move-related functions -------------------------------------------------- + +function robotAPI.returnToStartPoint() + robotAPI.moveToRequiredPoint(0, robotAPI.robotPosition.y, 0) + robotAPI.turnToRequiredRotation(0) + robotAPI.tryToDropShittyResources() + robotAPI.moveToRequiredPoint(0, 0, 0) +end + +function robotAPI.move(direction) + while true do + local swingSuccess, swingReason = robotComponent.swing(direction) + if swingSuccess or swingReason == "air" then + local moveSuccess, moveReason = robotComponent.move(direction) + if moveSuccess then + break + end + else + if swingReason == "block" then + robotAPI.returnToStartPoint() + error("Unbreakable block detected, going to base") + end + end + end + + if direction == sides.front or direction == sides.back then + local directionOffset = direction == sides.front and 1 or -1 + + if robotAPI.robotPosition.rotation == 0 then + robotAPI.robotPosition.x = robotAPI.robotPosition.x + directionOffset + elseif robotAPI.robotPosition.rotation == 1 then + robotAPI.robotPosition.z = robotAPI.robotPosition.z + directionOffset + elseif robotAPI.robotPosition.rotation == 2 then + robotAPI.robotPosition.x = robotAPI.robotPosition.x - directionOffset + elseif robotAPI.robotPosition.rotation == 3 then + robotAPI.robotPosition.z = robotAPI.robotPosition.z - directionOffset + end + elseif direction == sides.up or direction == sides.down then + local directionOffset = direction == sides.up and 1 or -1 + robotAPI.robotPosition.y = robotAPI.robotPosition.y + directionOffset + end +end + +function robotAPI.turn(clockwise) + robotComponent.turn(clockwise) + robotAPI.robotPosition.rotation = robotAPI.robotPosition.rotation + (clockwise and 1 or -1) + if robotAPI.robotPosition.rotation > 3 then + robotAPI.robotPosition.rotation = 0 + elseif robotAPI.robotPosition.rotation < 0 then + robotAPI.robotPosition.rotation = 3 + end +end + +function robotAPI.turnToRequiredRotation(requiredRotation) + local difference = robotAPI.robotPosition.rotation - requiredRotation + + if difference ~= 0 then + local fastestWay + if difference > 0 then + if difference > 2 then fastestWay = true else fastestWay = false end + else + if -difference > 2 then fastestWay = false else fastestWay = true end + end + + while robotAPI.robotPosition.rotation ~= requiredRotation do + robotAPI.turn(fastestWay) + end + end +end + +function robotAPI.moveToRequiredPoint(xTarget, yTarget, zTarget) + local xDistance = xTarget - robotAPI.robotPosition.x + local yDistance = yTarget - robotAPI.robotPosition.y + local zDistance = zTarget - robotAPI.robotPosition.z + + if yDistance ~= 0 then + local direction = yDistance > 0 and sides.up or sides.down + for i = 1, math.abs(yDistance) do robotAPI.move(direction) end + end + + if xDistance ~= 0 then + robotAPI.turnToRequiredRotation(xDistance > 0 and 0 or 2) + for i = 1, math.abs(xDistance) do robotAPI.move(sides.front) end + end + + if zDistance ~= 0 then + robotAPI.turnToRequiredRotation(zDistance > 0 and 1 or 3) + for i = 1, math.abs(zDistance) do robotAPI.move(sides.front) end + end +end + +-------------------------------------------------- Inventory-related functions -------------------------------------------------- + +function robotAPI.getEmptySlotsCount() + local count = 0 + for slot = 1, robotComponent.inventorySize() do + count = count + (robotComponent.count(slot) == 0 and 1 or 0) + end + return count +end + +function robotAPI.tryToDropShittyResources(side) + if robotAPI.getEmptySlotsCount() < robotAPI.dropShittyResourcesOnCountOfEmptySlotsLesserThen then + print("Trying to drop all shitty resources to free some slots for mining") + for slot = 1, robotComponent.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + for i = 1, #robotAPI.shittyResources do + if stack.name == robotAPI.shittyResources[i] then + robotComponent.select(slot) + robotComponent.drop(side or sides.down) + end + end + end + end + + robotComponent.select(1) + end +end + +function robotAPI.dropAllResources(side, exceptArray) + side = side or sides.front + exceptArray = exceptArray or robotAPI.tools + print("Dropping all mined resources...") + + for slot = 1, robotComponent.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + local thisIsAShittyItem = true + + for exceptItem = 1, #exceptArray do + if stack.name == exceptArray[exceptItem] then + thisIsAShittyItem = false + break + end + end + + if thisIsAShittyItem then + robotComponent.select(slot) + robotComponent.drop(side) + end + end + end + robotComponent.select(1) +end + +function robotAPI.checkToolStatus() + if robotComponent.durability() < robotAPI.replaceToolOnDurabilityLesserThen then + print("Equipped tool durability lesser then " .. robotAPI.replaceToolOnDurabilityLesserThen) + local success = false + + for slot = 1, robotComponent.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + for tool = 1, #robotAPI.tools do + if stack.name == robotAPI.tools[tool] and stack.damage / stack.maxDamage < robotAPI.replaceToolOnDurabilityLesserThen then + local oldSlot = robotComponent.select() + robotComponent.select(slot) + inventoryController.equip() + robotComponent.select(oldSlot) + success = true + break + end + end + end + end + + if not success then + robotAPI.returnToStartPoint() + error("No one useable tool are found in inventory, going back to base") + else + print("Successfullty switched tool to another from inventory") + end + end +end + +-------------------------------------------------- Energy-related functions -------------------------------------------------- + +function robotAPI.checkEnergyStatus() + if computer.energy() / computer.maxEnergy() < robotAPI.returnToHomeOnEneryLowerThen then + print("Low energy level detected") + -- Запоминаем старую позицию, шобы суда вернуться + local oldPosition = robotAPI.getRobotPosition() + -- Пиздуем на базу за зарядкой + robotAPI.returnToStartPoint() + -- Заряжаемся, пока энергия не достигнет более-менее максимума + while computer.energy() / computer.maxEnergy() < 0.99 do + print("Charging up: " .. math.floor(computer.energy() / computer.maxEnergy() * 100) .. "%") + os.sleep(1) + end + -- Пиздуем обратно + robotAPI.moveToRequiredPoint(oldPosition.x, oldPosition.y, oldPosition.z) + robotAPI.turnToRequiredRotation(oldPosition.rotation) + end +end + +function robotAPI.getSlotWithFuel() + for slot = 1, robotComponent.inventorySize() do + local stack = inventoryController.getStackInInternalSlot(slot) + if stack then + for fuel = 1, #robotAPI.fuels do + if stack.name == robotAPI.fuels[fuel] then + return slot end end end end - robot.select(1) end --------------------------------------------------------------------------------------------------------------------------------------------- +function robotAPI.checkGeneratorStatus() + if component.isAvailable("generator") then + if component.generator.count() == 0 then + print("Generator is empty, trying to find some fuel in inventory") + local slot = robotAPI.getSlotWithFuel() + if slot then + print("Found slot with fuel: " .. slot) + local oldSlot = robotComponent.select() + robotComponent.select(slot) + component.generator.insert() + robotComponent.select(oldSlot) + return + else + print("Slot with fuel not found") + end + end + end +end + +-------------------------------------------------- Shortcut functions -------------------------------------------------- + +-- Swing +function robotAPI.swingForward() + return robotComponent.swing(sides.front) +end + +function robotAPI.swingUp() + return robotComponent.swing(sides.up) +end + +function robotAPI.swingDown() + return robotComponent.swing(sides.down) +end + +--Use +function robotAPI.useForward() + return robotComponent.use(sides.front) +end + +function robotAPI.useUp() + return robotComponent.use(sides.up) +end + +function robotAPI.useDown() + return robotComponent.use(sides.down) +end + +-- Move +function robotAPI.moveForward() + robotAPI.move(sides.front) +end + +function robotAPI.moveBack() + robotAPI.move(sides.back) +end + +function robotAPI.moveUp() + robotAPI.move(sides.up) +end + +function robotAPI.moveDown() + robotAPI.move(sides.down) +end + +-- Turn +function robotAPI.turnLeft() + robotAPI.turn(false) +end + +function robotAPI.turnRight() + robotAPI.turn(true) +end + +function robotAPI.turnAround() + robotAPI.turn(true) + robotAPI.turn(true) +end + +-------------------------------------------------- End of shit -------------------------------------------------- return robotAPI + + + + +