-- ArcChunkLoading PROGRAM -- This program is designed to load chunks in a defined area -- The original goal was to load the area chere turtles are mining (vertical mining program) -- It calculates checkpoints location to go through to load the all area -- It has regular runs depending on the time chunks stay loaded (see Advanced Preripherals settings) -- Length corresponds to the forward dimension and width to the right(relatively to the turtle's starting orientation) -- The first checkpoint will be at position 1,1 -- if the turtle encounters a block on its path, it will sop -- The turtle can save his position and status at each move or status update to automatically resume his loading operation at game/server restart -- It automatically saves it in case of unexpected interruption to make you able to resume the loading operation in the main menu telling you the interruption reason -- The turtle can report his position and status to a distant computer to write it on a screen or send chat message (turtle watching program) -- The report is sent when status is saved -- If a GPS is setup and in range, it is used to send minecraft coordinates location in the report instead of turtle's own referential coordinates -- The turtle can refuel from start position (down) storage, shulker (in slot 1) or inventory (with emergency refuel only) -- It will try to refuel before moving to the next mine shaft, when running out of fuel and at the mining operation end -- It will refuel in storage or shulker only if his fuel level is under the low fuel threshold -- It will refuel from inventory only if it runs out of fuel and no other refuel type works -- When using a shulker, the turtle will try to place it on all directions in the following order : up>down>forward>right>back>left -- Shulkers can be replaced by modded ender chests local ArcConst = require("ArcConstants") local ArcBlocks = require("ArcBlocks") local ArcTerm = require("ArcTerm") local ArcMoving = require("ArcMoving") local ArcUtilities = require("ArcUtilities") -- GLOBAL VARIABLES -- Operation Settings local gnMaxLength = 0 -- Length of the loading area (range from 1 up to 999) local gnMaxWidth = 0 -- Width of the loading area (range from 1 up to 999) -- Global Settings local gnRefuelType = 3 -- Refueling method type (range from 1 up to 3) local gbEmergencyRefuel = true -- Allow refueling directly from inventory local gnLowFuelThreshold = 1000 -- Fuel limit below which refueling is done (range from 0 up to turtle's fuel limit) local gnHighFuelThreshold = 5000 -- Maximum fuel level allowed when refueling (range from low fuel threashold up to turtle's fuel limit) local gnChunkLoadTime = 600 -- Time a chunk stay loaded (check Advanced Peripherals settings) local gbSavePosAndStatus = false -- Save position and status at each move to resume loading operation on map reload local gbReportPosAndStatus = false -- Report position and status at each status modification local gsReportProtocol = "ATW" -- Report protocol code to send reports -- Miscellaneous local gnCPCount = 0 -- Actual checkpoint index local gtabCPLocations = {} -- Locations of all checkpoints local gsShulkerDirection = "" -- Direction of placed shulker to take if back after local gnStatusType = 0 -- Current turtle status type local gsStatus = "" -- Current turtle status local gbRepeatReport = false -- Repeat report every few seconds local gsSettingsFileName = "Settings.acl" -- Global Settings file name local gsStatusFileName = "Status.acl" -- Saved status file name to resume interrupted mining operation local gsPositionFileName = "Position.acl" -- Saved position file name to resume interrupted mining operation local gnRefreshTime = 5 -- Status refresh countdown -- FUNCTIONS local function CalculateCheckpointsLocation() local tabPosCP = {} local nCPL = 1 local nCPW = 1 gtabCPLocations = {} if gnMaxLength > 1 then nCPL = nCPL+math.ceil((gnMaxLength-1)/16) end if gnMaxWidth > 1 then nCPW = nCPW+math.ceil((gnMaxWidth-1)/16) end for k=1,nCPW,1 do if k%2 == 1 then for j=1,nCPL,1 do tabPosCP = {16*(j-1)+1,16*(k-1)+1} if tabPosCP[1] > gnMaxLength then tabPosCP[1] = gnMaxLength end if tabPosCP[2] > gnMaxWidth then tabPosCP[2] = gnMaxWidth end table.insert(gtabCPLocations,tabPosCP) end else for j=nCPL,1,-1 do tabPosCP = {16*(j-1)+1,16*(k-1)+1} if tabPosCP[1] > gnMaxLength then tabPosCP[1] = gnMaxLength end if tabPosCP[2] > gnMaxWidth then tabPosCP[2] = gnMaxWidth end table.insert(gtabCPLocations,tabPosCP) end end end end local function ReportPositionAndStatus() local nX = nil local nY = nil local nZ = nil local nO = nil local TurtleData = nil local sTurtleData = nil local nLocationType = nil local fDelay = nil while true do TurtleData = {} nLocationType = ArcConst.TLT_MINECRAFT nX,nY,nZ = gps.locate() nO = ArcMoving.GetRealOrientation() if nX == nil then nLocationType = ArcConst.TLT_OWNREF nX = ArcMoving.GetPosL() nY = ArcMoving.GetPosW() nZ = ArcMoving.GetPosD() nO = ArcMoving.GetPosO() end table.insert(TurtleData,os.getComputerID()) table.insert(TurtleData,ArcConst.TT_CHUNKLOADING) table.insert(TurtleData,nLocationType) table.insert(TurtleData,nX) table.insert(TurtleData,nY) table.insert(TurtleData,nZ) table.insert(TurtleData,nO) table.insert(TurtleData,gnCPCount) table.insert(TurtleData,#gtabCPLocations) table.insert(TurtleData,turtle.getFuelLevel()) table.insert(TurtleData,turtle.getFuelLimit()) table.insert(TurtleData,gnStatusType) table.insert(TurtleData,gsStatus) sTurtleData = textutils.serialise(TurtleData) rednet.broadcast({sTurtleData = sTurtleData},gsReportProtocol) if not gbRepeatReport then break end fDelay = math.random(5000,6000) fDelay = fDelay/100 os.sleep(fDelay) end end local function TotalShulkerCount() local nShulkerCount = 0 if gnRefuelType == ArcConst.TRT_SHULKER then nShulkerCount = nShulkerCount+1 end return nShulkerCount end local function SaveAndReportStatus(pnStatusType,psStatus) local File = nil gnStatusType = pnStatusType if psStatus ~= "" then gsStatus = psStatus end if pnStatusType == ArcConst.TST_NEEDPLAYER or pnStatusType == ArcConst.TST_SHUTDOWN or gbSavePosAndStatus then File = fs.open(gsStatusFileName,"w+") File.writeLine(("%d;%s"):format(pnStatusType,gsStatus)) File.writeLine(("%d;%d"):format(gnMaxLength,gnMaxWidth)) File.writeLine(("%d;%s"):format(gnCPCount,gsShulkerDirection)) File.close() end if gbReportPosAndStatus then ReportPositionAndStatus() end end local function Terminate(psErrorMessage) gbError = true gbRepeatReport = true ArcMoving.SavePosition(true) SaveAndReportStatus(ArcConst.TST_NEEDPLAYER,psErrorMessage) end local function SelectEmptySlot() for i=1,ArcConst.TM_MAXSLOTS,1 do if turtle.getItemCount(i) == 0 then turtle.select(i) return i end end turtle.select(1) return nil end local function PlaceShulker(pnSlot) local bReturn = nil local sMessage = nil gsShulkerDirection = "" turtle.select(pnSlot) bReturn,sMessage = turtle.placeUp() if bReturn then gsShulkerDirection = ArcConst.TD_UP SaveAndReportStatus(ArcConst.TST_RUNNING,"") return true end bReturn,sMessage = turtle.placeDown() if bReturn then gsShulkerDirection = ArcConst.TD_DOWN SaveAndReportStatus(ArcConst.TST_RUNNING,"") return true end bReturn,sMessage = turtle.place() if bReturn then gsShulkerDirection = ArcConst.TD_FORWARD SaveAndReportStatus(ArcConst.TST_RUNNING,"") return true end return false end local function TakeShulker(pnSlot) local bReturn = nil local sMessage = nil turtle.select(pnSlot) if gsShulkerDirection == ArcConst.TD_FORWARD then bReturn,sMessage = turtle.dig() if not bReturn then Terminate("Unable to take forward shulker") end elseif gsShulkerDirection == ArcConst.TD_UP then bReturn,sMessage = turtle.digUp() if not bReturn then Terminate("Unable to take up shulker") end elseif gsShulkerDirection == ArcConst.TD_DOWN then bReturn,sMessage = turtle.digDown() if not bReturn then Terminate("Unable to take down shulker") end else Terminate("Unexpedted shulker direction") end gsShulkerDirection = "" SaveAndReportStatus(ArcConst.TST_RUNNING,"") end local function RefuelFromItem() local nFuelLevel = turtle.getFuelLevel() local nItemFuel = nil local bRefuel = nil local sMessage = nil local nItemCount = nil if nFuelLevel >= gnHighFuelThreshold then return false end bRefuel,sMessage = turtle.refuel(1) if not bRefuel then return false end nItemRefuel = turtle.getFuelLevel()-nFuelLevel nItemCount = math.ceil((gnHighFuelThreshold-turtle.getFuelLevel())/nItemRefuel) if nItemCount <= 0 then return false end if nItemCount >= turtle.getItemCount(turtle.getSelectedSlot()) then turtle.refuel() else turtle.refuel(nItemCount) end return (turtle.getFuelLevel() < gnHighFuelThreshold) end local function RefuelFromStorage(psDirection) local nSlot = nil local bRefuel = false nSlot = SelectEmptySlot() if nSlot == nil then Terminate("No slot for fuel") end repeat if psDirection == ArcConst.TD_FORWARD then turtle.suck() elseif psDirection == ArcConst.TD_UP then turtle.suckUp() elseif psDirection == ArcConst.TD_DOWN then turtle.suckDown() else Terminate("Unexpected storage direction") end bRefuel = RefuelFromItem() until not bRefuel if turtle.getItemCount() > 0 then if psDirection == ArcConst.TD_FORWARD then turtle.drop() elseif psDirection == ArcConst.TD_UP then turtle.dropUp() elseif psDirection == ArcConst.TD_DOWN then turtle.dropDown() end end turtle.select(1) end local function RefuelProtocol() local nFuelLevel = turtle.getFuelLevel() local bMoved = nil local sDirection = nil local bFirstResolution = nil if nFuelLevel > 0 and nFuelLevel > gnLowFuelThreshold then return false end SaveAndReportStatus(ArcConst.TST_RUNNING,"Refueling...") if gnRefuelType == ArcConst.TRT_STARTING then if nFuelLevel > 0 then bFirstResolution = true repeat bMoved,sDirection = ArcMoving.MoveToStart(bFirstResolution) if not bMoved then ResolveMovingError(sDirection) bFirstResolution = false end until bMoved RefuelFromStorage(ArcConst.TD_DOWN) repeat bMoved,sDirection = ArcMoving.MoveToBackup() if not bMoved then ResolveMovingError(sDirection) end until bMoved end elseif gnRefuelType == ArcConst.TRT_SHULKER then if PlaceShulker(1) then RefuelFromStorage(gsShulkerDirection) TakeShulker(1) end else -- No Refuel (=1) / Unexpected value end -- No emergency refuel if standard protocol worked no matter fuel level if turtle.getFuelLevel() > nFuelLevel then return true end -- No emergency refuel if not out of fuel if turtle.getFuelLevel() > 0 then return false end if not gbEmergencyRefuel then return false end -- If no fuel items, wait until help repeat for i=TotalShulkerCount()+1,ArcConst.TM_MAXSLOTS,1 do turtle.select(i) RefuelFromItem() end Terminate("Out of fuel") until turtle.getFuelLevel() > 0 turtle.select(1) return true end local function ResolveMovingError(psDirection) local bReturn = nil local sMessage = nil local sStatus = gsStatus -- Out of fuel if turtle.getFuelLevel() == 0 then if not RefuelProtocol() then Terminate("Out of fuel") else SaveAndReportStatus(ArcConst.TST_RUNNING,sStatus) return true end end -- Block on the way if psDirection == ArcConst.TD_FORWARD then Terminate("Block forward") end -- Unexpected error Terminate("Unexpected moving error") end local function RefreshDelay() os.sleep(gnRefreshTime) end local function ManualInterruption() if ArcTerm.ReadKey() ~= nil then while true do ArcTerm.Write(1,13,"1 | Confirm interruption - 2 | Cancel") nKey = ArcUtilities.KeyToNumber(ArcTerm.ReadKey()) if nKey == 1 then ArcMoving.SavePosition(true) SaveAndReportStatus(2,"Manual interruption") os.shutdown() elseif nKey == 2 then break end end end end local function Interruption() while true do if not gbError then ArcTerm.Write(1,13,ArcUtilities.Complete("Press any key to interrupt"," ",39,"R",false)) parallel.waitForAny(ManualInterruption,RefreshDelay) else ArcTerm.Write(1,13,ArcUtilities.Complete("Press any key to exit"," ",39,"R",false)) ArcTerm.ReadKey() gbRepeatReport = false SaveAndReportStatus(ArcConst.TST_SHUTDOWN,"") if not gbError then fs.delete(gsPositionFileName) fs.delete(gsStatusFileName) end os.shutdown() end end end local function ShowStatus() while true do ArcTerm.ResetLines({1,2,3,4,5,6,7,8,9,10,11,12}) ArcTerm.Write(1,1,"<========= LOADING OPERATION =========>") ArcTerm.Write(1,3,("Position length : %d"):format(ArcMoving.GetPosL())) ArcTerm.Write(1,4,("Position width : %d"):format(ArcMoving.GetPosW())) ArcTerm.Write(1,5,("Position depth : %d"):format(ArcMoving.GetPosD())) ArcTerm.Write(1,6,("Orientation : %d"):format(ArcMoving.GetPosO())) ArcTerm.Write(1,7,("Checkpoint : %d/%d"):format(gnCPCount,#gtabCPLocations)) ArcTerm.Write(1,8,("Fuel level : %d/%d"):format(turtle.getFuelLevel(),turtle.getFuelLimit())) ArcTerm.Write(1,10,"Current status :") ArcTerm.Write(1,11,gsStatus) RefreshDelay() end end local function Timer() local nTimerId = nil local sEvent = nil local nId = nil nTimerId = os.startTimer(math.ceil(gnChunkLoadTime*0.98)) repeat sEvent,nId = os.pullEvent("timer") until nId == nTimerId end local function Run() local bMoved = nil local sDirection = nil repeat gnCPCount = gnCPCount+1 SaveAndReportStatus(ArcConst.TST_RUNNING,"Running...") repeat bMoved,sDirection = ArcMoving.MoveTo(gtabCPLocations[gnCPCount][1],gtabCPLocations[gnCPCount][2]) if not bMoved then ResolveMovingError(sDirection) end until bMoved until gnCPCount == #gtabCPLocations gnCPCount=1 SaveAndReportStatus(ArcConst.TST_RUNNING,"Running...") repeat bMoved,sDirection = ArcMoving.MoveTo(gtabCPLocations[gnCPCount][1],gtabCPLocations[gnCPCount][2]) if not bMoved then ResolveMovingError(sDirection) end until bMoved ArcMoving.ChangeOrientation(1) SaveAndReportStatus(ArcConst.TST_RUNNING,"Waiting until next run...") end local function StartLoadingOperation() local bMoved = nil local sDirection = nil while true do parallel.waitForAll(Timer,Run) end end local function LoadStatus() local File = fs.open(gsStatusFileName,"r") local sLine = nil sLine = File.readLine() gnStatusType = tonumber(ArcUtilities.StringExtract(sLine,1,";")) gsStatus = ArcUtilities.StringExtract(sLine,2,";") sLine = File.readLine() gnMaxLength = tonumber(ArcUtilities.StringExtract(sLine,1,";")) gnMaxWidth = tonumber(ArcUtilities.StringExtract(sLine,2,";")) sLine = File.readLine() gnCPCount = tonumber(ArcUtilities.StringExtract(sLine,1,";")) gsShulkerDirection = ArcUtilities.StringExtract(sLine,2,";") File.close() end local function ResumeLoadingOperation() local bMoved = nil local sDirection = nil LoadStatus() ArcMoving.LoadPosition() CalculateCheckpointsLocation() if gnStatusType == ArcConst.TST_NEEDPLAYER then gbError = true gbRepeatReport = true parallel.waitForAll(Interruption,ShowStatus,ReportPositionAndStatus) end if gsShulkerDirection ~= "" then TakeShulker(1) end SaveAndReportStatus(ArcConst.TST_RUNNING,"Moving to starting position...") repeat bMoved,sDirection = ArcMoving.MoveToStart(false) if not bMoved then ResolveMovingError(sDirection) end until bMoved parallel.waitForAll(StartLoadingOperation,Interruption,ShowStatus) end local function LoadSettings() local File = nil local sSettings = nil local nCategory = nil local i = nil if not fs.exists(gsSettingsFileName) then return false end File = fs.open(gsSettingsFileName,"r") sSettings = File.readLine() gbSavePosAndStatus = (tonumber(ArcUtilities.StringExtract(sSettings,1,";")) == 1) gbReportPosAndStatus = (tonumber(ArcUtilities.StringExtract(sSettings,2,";")) == 1) gsReportProtocol = ArcUtilities.StringExtract(sSettings,3,";") gnChunkLoadTime = tonumber(ArcUtilities.StringExtract(sSettings,4,";")) sSettings = File.readLine() gnRefuelType = tonumber(ArcUtilities.StringExtract(sSettings,1,";")) gbEmergencyRefuel = (tonumber(ArcUtilities.StringExtract(sSettings,2,";")) == 1) gnLowFuelThreshold = tonumber(ArcUtilities.StringExtract(sSettings,3,";")) gnHighFuelThreshold = tonumber(ArcUtilities.StringExtract(sSettings,4,";")) File.close() end local function SaveSettings() local File = fs.open(gsSettingsFileName,"w+") File.writeLine(("%d;%d;%s;%d"):format(ArcUtilities.BooleanToInteger(gbSavePosAndStatus),ArcUtilities.BooleanToInteger(gbReportPosAndStatus),gsReportProtocol,gnChunkLoadTime)) File.writeLine(("%d;%d;%d;%d"):format(gnRefuelType,ArcUtilities.BooleanToInteger(gbEmergencyRefuel),gnLowFuelThreshold,gnHighFuelThreshold)) File.close() end local function CheckForSavedStatus() local File = nil local sLine = nil local nStatusType = nil local sStatus = nil if not fs.exists(gsStatusFileName) then return nil,nil end File = fs.open(gsStatusFileName,"r") sLine = File.readLine() nStatusType = tonumber(ArcUtilities.StringExtract(sLine,1,";")) sStatus = ArcUtilities.StringExtract(sLine,2,";") File.close() return nStatusType,sStatus end local function EstimatedFuelConsumption() local nFuelConsumption = nil if #gtabCPLocations == 1 then return 0 end nFuelConsumption = (#gtabCPLocations-1)*16 nFuelConsumption = nFuelConsumption+(gtabCPLocations[#gtabCPLocations][1]-1)+(gtabCPLocations[#gtabCPLocations][2]-1) nFuelConsumption = nFuelConsumption*(math.ceil(3600/gnChunkLoadTime)) return nFuelConsumption end local function OpenMenu() local nStatusType = nil local sStatus = nil local bExit = nil local nKey = nil local bSettingsOk = nil local nFuelEstimation = nil nStatusType,sStatus = CheckForSavedStatus() while true do ArcMoving.SetSavePosition(gbSavePosAndStatus) ArcMoving.SetPosFileName(gsPositionFileName) ArcMoving.SetStartPosL(1) ArcMoving.SetStartPosW(1) ArcMoving.SetStartPosD(1) ArcMoving.SetStartPosO(1) ArcTerm.Reset() ArcTerm.Write(1,1,"<========= ARC CHUNK LOADING =========>") ArcTerm.Write(1,2,"-- Loading Operation --") ArcTerm.Write(1,3,"- 1 | Start new") if nStatusType == 3 then ArcTerm.Write(1,4,"- 2 | Resume") ArcTerm.Write(1,5,"Last status :") ArcTerm.Write(1,6,sStatus) end ArcTerm.Write(1,8,"- 3 | Settings") ArcTerm.Write(1,9,"- 4 | Exit") bSettingsOk = false bExit = false nKey = ArcUtilities.KeyToNumber(ArcTerm.ReadKey()) if nKey == 1 then gnMaxLength = nil gnMaxWidth = nil repeat ArcTerm.Reset() while true do ArcTerm.Write(1,1,"<==== LOADING OPERATION SETTINGS =====>") ArcTerm.Write(1,3,"Loading area length : ") ArcTerm.Write(1,4,"Loading area width : ") ArcTerm.Write(1,6,"Total chekpoints count : ") ArcTerm.Write(1,8,"Estimated fuel consumption (/h) : ") ArcTerm.Write(1,9,"Fuel level : ") if gnMaxLength == nil or gnMaxLength < 0 or gnMaxLength > 999 then gnMaxLength = tonumber(ArcTerm.Read(23,3));break else ArcTerm.Write(23,3,gnMaxLength) end if gnMaxWidth == nil or gnMaxWidth < 0 or gnMaxWidth > 999 then gnMaxWidth = tonumber(ArcTerm.Read(23,4));break else ArcTerm.Write(23,4,gnMaxWidth) end CalculateCheckpointsLocation() ArcTerm.Write(26,6,#gtabCPLocations) nFuelEstimation = EstimatedFuelConsumption() ArcTerm.Write(35,8,nFuelEstimation) ArcTerm.Write(14,9,("%d/%d"):format(turtle.getFuelLevel(),turtle.getFuelLimit())) ArcTerm.Write(1,13,"1 | Confirm - 2 | Cancel") nKey = ArcUtilities.KeyToNumber(ArcTerm.ReadKey()) if nKey == 1 then bSettingsOk = true elseif nKey == 2 then bExit = true end break end until bSettingsOk or bExit if bSettingsOk then gnCPCount = 1 ArcMoving.TestOrientation() parallel.waitForAll(StartLoadingOperation,Interruption,ShowStatus) break end elseif nKey == 2 and nStatusType == ArcConst.TST_SHUTDOWN then ResumeLoadingOperation() elseif nKey == 3 then repeat ArcTerm.Reset() while true do ArcTerm.Write(1,1,"<========= GENERAL SETTINGS ==========>") ArcTerm.Write(1,2,"Refuel type : ") ArcTerm.Write(1,3,"- 1 | No refuel") ArcTerm.Write(1,4,"- 2 | Refuel at starting position") ArcTerm.Write(1,5,"- 3 | Refuel from shulker") ArcTerm.Write(1,6,"Emergency refuel : ") ArcTerm.Write(1,7,"Low fuel Threshold : ") ArcTerm.Write(1,8,"High fuel Threshold : ") ArcTerm.Write(1,9,"Chunk load time : ") ArcTerm.Write(1,10,"Save position and status : ") ArcTerm.Write(1,11,"Report position and status : ") if gbReportPosAndStatus == true then ArcTerm.Write(1,12,"Report protocol : ") end if gnRefuelType <= 0 or gnRefuelType > 3 then gnRefuelType = ArcUtilities.KeyToNumber(ArcTerm.ReadKey());break else ArcTerm.Write(1,2+gnRefuelType,"X") end if gbEmergencyRefuel == nil then gbEmergencyRefuel = ArcTerm.ReadYesNo(20,6);break else ArcTerm.WriteYesNo(20,6,gbEmergencyRefuel) end if gnLowFuelThreshold == nil or gnLowFuelThreshold < 0 or gnLowFuelThreshold > turtle.getFuelLimit() then gnLowFuelThreshold = tonumber(ArcTerm.Read(22,7));break else ArcTerm.Write(22,7,gnLowFuelThreshold) end if gnHighFuelThreshold == nil or gnHighFuelThreshold < 0 or gnHighFuelThreshold > turtle.getFuelLimit() or gnHighFuelThreshold < gnLowFuelThreshold then gnHighFuelThreshold = tonumber(ArcTerm.Read(23,8));break else ArcTerm.Write(23,8,gnHighFuelThreshold) end if gnChunkLoadTime == nil or gnChunkLoadTime <= 0 then gnChunkLoadTime = tonumber(ArcTerm.Read(19,9));break else ArcTerm.Write(19,9,gnChunkLoadTime) end if gbSavePosAndStatus == nil then gbSavePosAndStatus = ArcTerm.ReadYesNo(28,10);break else ArcTerm.WriteYesNo(28,10,gbSavePosAndStatus) end if gbReportPosAndStatus == nil then gbReportPosAndStatus = ArcTerm.ReadYesNo(30,11);break else ArcTerm.WriteYesNo(30,11,gbReportPosAndStatus) end if gbReportPosAndStatus == true then if gsReportProtocol == nil or gsReportProtocol == " " then gsReportProtocol = ArcTerm.Read(19,12);break else ArcTerm.Write(19,12,gsReportProtocol) end else gsReportProtocol = " " end SaveSettings() ArcTerm.Write(1,13,"1 | Edit - 2 | Exit") nKey = ArcUtilities.KeyToNumber(ArcTerm.ReadKey()) if nKey == 1 then gnRefuelType = 0 gbEmergencyRefuel = nil gnLowFuelThreshold = nil gnHighFuelThreshold = nil gnChunkLoadTime = nil gbSavePosAndStatus = nil gbReportPosAndStatus = nil gsReportProtocol = nil elseif nKey == 2 then bExit = true end break end until bExit elseif nKey == 4 then ArcTerm.Reset() break end end end local function Main() local nStatusType = nil local sStatus = nil local sBlockName = nil sBlockName = ArcBlocks.BlockName(turtle.getEquippedLeft()) if sBlockName == "computercraft:wireless_modem_normal" or sBlockName == "computercraft:wireless_modem_advanced" then rednet.open("left") end sBlockName = ArcBlocks.BlockName(turtle.getEquippedRight()) if sBlockName == "computercraft:wireless_modem_normal" or sBlockName == "computercraft:wireless_modem_advanced" then rednet.open("right") end LoadSettings() nStatusType,sStatus = CheckForSavedStatus() if nStatusType == ArcConst.TST_RUNNING or nStatusType == ArcConst.TST_NEEDPLAYER then ArcMoving.SetSavePosition(gbSavePosAndStatus) ArcMoving.SetPosFileName(gsPositionFileName) ArcMoving.SetStartPosL(1) ArcMoving.SetStartPosW(1) ArcMoving.SetStartPosD(1) ArcMoving.SetStartPosO(1) ResumeLoadingOperation() else OpenMenu() end end Main() os.shutdown()