Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- VillageBot v1.4
- --#region STRICT TOP-LEVEL CONFIGURATION AND LOGGER GLOBALS
- local LOG_LEVELS = { DEBUG = 1, INFO = 2, WARN = 3, ERROR = 4, FATAL = 5 }
- local DEBUG_LOGGING_ENABLED = true
- local LOG_FILE_NAME_CONST = "villagebot.log"
- local current_log_level_val
- if DEBUG_LOGGING_ENABLED then
- current_log_level_val = (LOG_LEVELS and LOG_LEVELS.DEBUG) or 1
- else
- current_log_level_val = (LOG_LEVELS and LOG_LEVELS.INFO) or 2
- end
- local BOT_DATA_FILE = "villagebot_data.json"
- local ME_BRIDGE_NAME = "advancedperipherals:me_bridge"
- local REDSTONE_BLOCK_NAME = "minecraft:redstone_block"
- local AUTOMATA_PERIPHERAL_NAME = "endAutomata"
- local ME_BRIDGE_PERIPHERAL_NAME = "meBridge"
- local COLONY_INTEGRATOR_PERIPHERAL_NAME = "colonyIntegrator"
- local FUEL_SLOT = 16
- local COAL_BLOCK_NAME = "minecraft:coal_block"
- local REFUEL_BELOW_PERCENTAGE = 0.90
- local MAX_REDSTONE_BLOCK_RETRIES = 10
- local REDSTONE_BLOCK_RETRY_WAIT = 5
- local REFUEL_BARREL_ACCESS_POS = { x = -111, y = 65, z = 219, dir = 3 }
- --#endregion
- --#region Global State
- local current_pos = { x = nil, y = nil, z = nil }; local current_dir = nil
- local roboSlot = nil; local home_pos = { x = nil, y = nil, z = nil, dir = nil }
- local pAutomata = nil; local pMeBridge = nil; local pColonyIntegrator = nil
- local DIR_VECTORS = { [0]={x=0,z=1},[1]={x=1,z=0},[2]={x=0,z=-1},[3]={x=-1,z=0} }
- local DIR_NAMES = {[0]="North",[1]="East",[2]="South",[3]="West"}
- local mounted_peripherals = {}; local undeliveredItemsBuffer = {}
- --#endregion
- --#region Logger Function
- local function botLog(level, message)
- local message_str = message
- if type(message) ~= "string" and type(message) ~= "number" then
- message_str = textutils.serialize(message, {compact=true})
- if message == nil then message_str = "nil_message_passed_to_botLog" end
- else message_str = tostring(message) end
- local level_display_name = "LVL?"
- if LOG_LEVELS and type(LOG_LEVELS) == "table" then
- for name_key, lVal_val in pairs(LOG_LEVELS) do if lVal_val == level then level_display_name = name_key; break end end
- else print("Console: botLog - LOG_LEVELS is nil or not a table! Cannot determine level name.") end
- print(string.format("[%s] [%s] %s", os.date("%Y-%m-%d %H:%M:%S"), level_display_name, message_str))
- local can_write_to_file = false
- if LOG_LEVELS and type(LOG_LEVELS) == "table" and current_log_level_val and LOG_FILE_NAME_CONST and type(LOG_FILE_NAME_CONST) == "string" then
- if DEBUG_LOGGING_ENABLED or level >= (LOG_LEVELS.WARN or 3) then
- if level >= current_log_level_val then
- can_write_to_file = true
- end
- end
- end
- if can_write_to_file then
- local levelNameInFile = "UNK_LVL"
- if LOG_LEVELS then for name, lVal in pairs(LOG_LEVELS) do if lVal == level then levelNameInFile = name; break end end end
- local logMessageToFile = string.format("[%s] [%s] %s", os.date("%Y-%m-%d %H:%M:%S"), levelNameInFile, message_str)
- local f, err = fs.open(LOG_FILE_NAME_CONST, "a")
- if f then
- f.write(logMessageToFile .. "\n"); f.close()
- else
- print("CONSOLE: LOG FILE OPEN ERROR for '"..LOG_FILE_NAME_CONST.."' (in botLog): " .. tostring(err))
- end
- elseif DEBUG_LOGGING_ENABLED then
- if not LOG_LEVELS or type(LOG_LEVELS) ~= "table" then print("Console: botLog - Cannot write to file, LOG_LEVELS invalid.") end
- if not current_log_level_val then print("Console: botLog - Cannot write to file, current_log_level_val invalid.") end
- if not LOG_FILE_NAME_CONST or type(LOG_FILE_NAME_CONST) ~= "string" then print("Console: botLog - Cannot write to file, LOG_FILE_NAME_CONST invalid.") end
- end
- end
- --#endregion
- --#region Peripheral Management
- function findPeripheral(name,type_arg,required)
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"findPeripheral: Find "..name.." type '"..tostring(type_arg).."'")end
- if type(type_arg) ~= "string" then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "findPeripheral: Invalid type argument passed. Expected string, got " .. type(type_arg)) end
- return nil
- end
- local p=peripheral.find(type_arg)
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"findPeripheral: peripheral.find Result for type '"..type_arg.."': "..tostring(p))end
- if p then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"Found peripheral: "..name) end
- mounted_peripherals[name]=p
- return p
- else
- local m="Peripheral NOT FOUND: "..name.." (type: " .. type_arg .. ")"
- if required then
- if LOG_LEVELS then botLog(LOG_LEVELS.FATAL,m.." - REQUIRED!") end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,m) end
- end
- return nil
- end
- end
- function initCorePeripherals()
- print("Console: CHKPT - Enter initCorePeripherals")
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initCorePeripherals: Start") end
- pAutomata=findPeripheral("Automata",AUTOMATA_PERIPHERAL_NAME,true)
- if not pAutomata then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"initCorePeripherals: Automata peripheral missing. Cannot proceed.") end
- print("Console: CHKPT - initCorePeripherals FAIL (Automata missing)")
- return false
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initCorePeripherals: Core peripherals OK.") end
- print("Console: CHKPT - initCorePeripherals OK")
- return true
- end
- function findHomeLocationPeripherals()
- print("Console: CHKPT - Enter findHomeLocationPeripherals")
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"findHomeLocationPeripherals: Start (should be at home and oriented)") end
- if not (home_pos and home_pos.x and current_pos and current_pos.x == home_pos.x and current_pos.y == home_pos.y and current_pos.z == home_pos.z) then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"findHomeLocationPeripherals: Called when not at stored home coordinates. This might fail.") end
- end
- if not (home_pos and home_pos.dir ~= nil and current_dir == home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"findHomeLocationPeripherals: Not facing home direction (".. (home_pos and DIR_NAMES[home_pos.dir] or "N/A").."). ME Bridge might not be in front.") end
- if home_pos and home_pos.dir ~= nil then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "findHomeLocationPeripherals: Attempting re-orientation to home direction: " .. DIR_NAMES[home_pos.dir]) end
- if not ml.turnToDir(home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, "findHomeLocationPeripherals: Re-orientation failed.") end
- end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, "findHomeLocationPeripherals: home_pos.dir is nil, cannot re-orient.") end
- end
- end
- if not pMeBridge then
- pMeBridge=findPeripheral("ME Bridge",ME_BRIDGE_PERIPHERAL_NAME,true)
- elseif LOG_LEVELS then
- botLog(LOG_LEVELS.DEBUG, "findHomeLocationPeripherals: pMeBridge already attached.")
- end
- if not pColonyIntegrator then
- pColonyIntegrator=findPeripheral("Colony Integrator",COLONY_INTEGRATOR_PERIPHERAL_NAME,true)
- elseif LOG_LEVELS then
- botLog(LOG_LEVELS.DEBUG, "findHomeLocationPeripherals: pColonyIntegrator already attached.")
- end
- if not (pMeBridge and pColonyIntegrator)then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"findHomeLocationPeripherals: ME Bridge or Colony Integrator missing after checks.") end
- print("Console: CHKPT - findHomeLocationPeripherals FAIL")
- return false
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"findHomeLocationPeripherals: Home location peripherals OK.") end
- print("Console: CHKPT - findHomeLocationPeripherals OK")
- return true
- end
- --#endregion
- --#region JSON Data Handling
- function saveData() if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"saveData: Attempt")end; if roboSlot==nil or not home_pos or home_pos.x==nil or not current_pos or current_pos.x==nil or current_dir==nil then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"saveData: Skip, incomplete data (roboSlot, home_pos, current_pos, or current_dir is nil/incomplete).")end; return false end; local d={roboSlot=roboSlot,home_pos=home_pos,current_pos=current_pos,current_dir=current_dir}; if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"saveData: Data: "..textutils.serialize(d))end; local s,e=textutils.serialiseJSON(d); if not s then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"saveData: Serialize fail: "..tostring(e))end; return false end; local f,fe=fs.open(BOT_DATA_FILE,"w"); if not f then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"saveData: Open file fail: "..tostring(fe))end; return false end; f.write(s);f.close(); if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"Bot data saved.")end; return true end
- function loadData() print("Console: CHKPT - Enter loadData"); if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"loadData: Attempt from '"..BOT_DATA_FILE.."'")end; if not fs.exists(BOT_DATA_FILE)then if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"loadData: File not found.")end; print("Console: CHKPT - loadData: No file"); return false end; local f,fe=fs.open(BOT_DATA_FILE,"r"); if not f then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"loadData: Open file fail: "..tostring(fe))end; print("Console: CHKPT - loadData: Open fail"); return false end; local s=f.readAll();f.close(); if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"loadData: File content: "..s)end; local sc,d=pcall(textutils.unserialiseJSON,s); if not sc or type(d)~="table"then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"loadData: Parse fail. Success:"..tostring(sc)..", Err/Data:"..tostring(d))end; print("Console: CHKPT - loadData: Parse JSON fail"); return false end; if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"loadData: Parsed: "..textutils.serialize(d))end; if d.roboSlot and d.home_pos and d.home_pos.x~=nil and d.home_pos.y~=nil and d.home_pos.z~=nil and d.home_pos.dir~=nil and d.current_pos and d.current_pos.x~=nil and d.current_pos.y~=nil and d.current_pos.z~=nil and d.current_dir~=nil then roboSlot=d.roboSlot;home_pos=d.home_pos;current_pos=d.current_pos;current_dir=d.current_dir; if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"Bot data loaded.")end; print("Console: CHKPT - loadData: OK"); return true else if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"loadData: Incomplete/malformed data in JSON file.")end; print("Console: CHKPT - loadData: Malformed data"); return false end end
- --#endregion
- --#region Movement Library (ml)
- ml = {}
- function ml.setPos(x,y,z,dirNum) current_pos={x=x,y=y,z=z}; current_dir=dirNum; if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, string.format("ml.setPos: X:%s Y:%s Z:%s Dir:%s (%s)",x,y,z,dirNum,DIR_NAMES[dirNum])) end; saveData() end
- function ml.inspect() if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "ml.inspect: Called") end; local s,d=turtle.inspect(); if s and d then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.inspect: Success, Block: "..d.name .. (d.state and " " .. textutils.serialize(d.state) or "")) end; return d elseif s and not d then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.inspect: Success, Empty space.")end; return nil else if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.inspect: Failed: " .. tostring(d))end; return nil end end
- function ml.inspectUp() if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "ml.inspectUp: Called") end; local s,d=turtle.inspectUp(); if s and d then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.inspectUp: Success, Block: "..d.name)end; return d else if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.inspectUp: Success, Empty/failed.")end; return nil end end
- function ml.inspectDown() if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "ml.inspectDown: Called") end; local s,d=turtle.inspectDown(); if s and d then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.inspectDown: Success, Block: "..d.name)end; return d else if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.inspectDown: Success, Empty/failed.")end; return nil end end
- local function genericMove(moveFunc,actionName,updatesPos,updatesDir) if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"genericMove: Action: '"..actionName.."' FuelStart:"..turtle.getFuelLevel())end; local s,e=pcall(moveFunc); if s then if LOG_LEVELS then botLog(LOG_LEVELS.INFO,actionName.." successful. FuelEnd:"..turtle.getFuelLevel())end; if updatesPos and current_pos and current_pos.x~=nil and current_dir~=nil then local oX,oY,oZ=current_pos.x,current_pos.y,current_pos.z; if actionName=="forward"then current_pos.x=current_pos.x+DIR_VECTORS[current_dir].x;current_pos.z=current_pos.z+DIR_VECTORS[current_dir].z elseif actionName=="back"then current_pos.x=current_pos.x-DIR_VECTORS[current_dir].x;current_pos.z=current_pos.z-DIR_VECTORS[current_dir].z elseif actionName=="up"then current_pos.y=current_pos.y+1 elseif actionName=="down"then current_pos.y=current_pos.y-1 end; if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"genericMove: Pos "..oX..","..oY..","..oZ.." -> "..current_pos.x..","..current_pos.y..","..current_pos.z)end; end; if updatesDir and current_dir~=nil then local oD=current_dir; if actionName=="turnLeft"then current_dir=(current_dir-1+4)%4 elseif actionName=="turnRight"then current_dir=(current_dir+1)%4 end; if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"genericMove: Dir "..(oD and DIR_NAMES[oD] or "nil").." -> "..(current_dir and DIR_NAMES[current_dir] or "nil"))end; end; if updatesPos or updatesDir then saveData() end; return true else if LOG_LEVELS then botLog(LOG_LEVELS.WARN,actionName.." failed: "..tostring(e))end; return false end end
- function ml.forward() return genericMove(turtle.forward,"forward",true,false) end
- function ml.back() return genericMove(turtle.back,"back",true,false) end
- function ml.up() return genericMove(turtle.up,"up",true,false) end
- function ml.down() return genericMove(turtle.down,"down",true,false) end
- function ml.turnLeft() return genericMove(turtle.turnLeft,"turnLeft",false,true) end
- function ml.turnRight() return genericMove(turtle.turnRight,"turnRight",false,true) end
- function ml.select(slot) if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.select: Slot "..slot) end; turtle.select(slot); return true end
- function ml.getItemCount(slot) local c=turtle.getItemCount(slot); if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.getItemCount: Slot "..slot.." has "..c)end; return c end
- function ml.getItemDetail(slot) local d=turtle.getItemDetail(slot); if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.getItemDetail: Slot "..slot.." detail: "..(d and textutils.serialize(d, {compact=true}) or "nil"))end; return d end
- function ml.getFuelLevel() local l=turtle.getFuelLevel(); if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.getFuelLevel: "..l)end; return l end
- function ml.getFuelLimit() local l=turtle.getFuelLimit(); if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.getFuelLimit: "..l)end; return l end
- function ml.drop(count) local sl=turtle.getSelectedSlot();local dt=ml.getItemDetail(sl);local iN=(dt and dt.name or "unk item");local aC=count or ml.getItemCount(sl);if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.drop: Attempt drop "..aC.." of "..iN.." from slot "..sl)end;if aC==0 then return true end;local sc;if count then sc=turtle.drop(count)else sc=turtle.drop()end;if sc then if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"ml.drop: Dropped from slot "..sl)end else if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.drop: Fail drop from slot "..sl)end end;return sc end
- function ml.suck(count) local sl=turtle.getSelectedSlot();local aC=count or 1;if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.suck: Attempt suck "..aC.." into slot "..sl)end;local sc;if count then sc=turtle.suck(count)else sc=turtle.suck()end;if sc then if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"ml.suck: Sucked items into slot "..sl .. " (requested: "..aC..")")end else if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.suck: Fail suck into slot "..sl)end end;return sc end
- function ml.refuel() ml.select(FUEL_SLOT);local it=ml.getItemDetail(FUEL_SLOT);if not it or it.name ~= COAL_BLOCK_NAME then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.refuel: Fail: No/wrong fuel. Expected '"..COAL_BLOCK_NAME.."', Item: "..(it and it.name or "nil"))end;return false end;if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.refuel: Attempt from slot "..FUEL_SLOT.." with "..it.name)end;local iF=ml.getFuelLevel();local s=turtle.refuel();if s then if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"ml.refuel: OK. Fuel: "..ml.getFuelLevel().." (was "..iF..")")end else if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.refuel: turtle.refuel() fail.")end end;return s end
- function ml.turnToDir(targetDirNum) if current_dir==nil then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"ml.turnToDir: current_dir is nil.")end; return false end;if targetDirNum<0 or targetDirNum>3 then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"ml.turnToDir: Invalid targetDir: "..targetDirNum)end; return false end;if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.turnToDir: From "..(current_dir and DIR_NAMES[current_dir] or "nil").." ("..current_dir..") to "..DIR_NAMES[targetDirNum].." ("..targetDirNum..")")end;if current_dir==targetDirNum then return true end;local df=(targetDirNum-current_dir+4)%4;if df==1 then return ml.turnRight()elseif df==2 then return ml.turnRight() and ml.turnRight()elseif df==3 then return ml.turnLeft()end;return false end
- function ml.moveTo(tx,ty,tz,tdir_opt) print(string.format("Console: ml.moveTo Start - Target X:%s Y:%s Z:%s Dir:%s", tx, ty, tz, (tdir_opt and DIR_NAMES[tdir_opt] or "any"))); if LOG_LEVELS then botLog(LOG_LEVELS.INFO, string.format("ml.moveTo: Attempt: Target X%sY%sZ%sD%s | Current X%sY%sZ%sD%s (%s)",tx,ty,tz,(tdir_opt and DIR_NAMES[tdir_opt] or "any"), current_pos.x,current_pos.y,current_pos.z,current_dir,(current_dir and DIR_NAMES[current_dir] or "nil")))end; local function att(aF,cnt,axisName)for i=1,cnt do if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo.att: "..axisName.." Step "..i.."/"..cnt)end;if not aF()then return false end;if ml.getFuelLevel()<5 and ml.getFuelLimit()>0 then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.moveTo: Low fuel ("..ml.getFuelLevel()..")!")end end;sleep(0.05)end;return true end; if current_pos.y~=ty then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo: Adjust Y "..current_pos.y.."->"..ty)end; while current_pos.y<ty do if not ml.up()then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.moveTo: Blocked UP at Y="..current_pos.y.." to Y="..ty)end;return false end end;while current_pos.y>ty do if not ml.down()then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.moveTo: Blocked DOWN at Y="..current_pos.y.." to Y="..ty)end;return false end end;if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo: Y OK at "..current_pos.y)end end; if current_pos.x~=tx then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo: Adjust X "..current_pos.x.."->"..tx)end; if current_pos.x<tx then if not ml.turnToDir(1)then return false end;if not att(ml.forward,tx-current_pos.x,"East")then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.moveTo: Blocked EAST at X="..current_pos.x.." to X="..tx)end;return false end elseif current_pos.x>tx then if not ml.turnToDir(3)then return false end;if not att(ml.forward,current_pos.x-tx,"West")then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.moveTo: Blocked WEST at X="..current_pos.x.." to X="..tx)end;return false end end;if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo: X OK at "..current_pos.x)end end; if current_pos.z~=tz then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo: Adjust Z "..current_pos.z.."->"..tz)end; if current_pos.z<tz then if not ml.turnToDir(0)then return false end;if not att(ml.forward,tz-current_pos.z,"North")then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.moveTo: Blocked NORTH at Z="..current_pos.z.." to Z="..tz)end;return false end elseif current_pos.z>tz then if not ml.turnToDir(2)then return false end;if not att(ml.forward,current_pos.z-tz,"South")then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"ml.moveTo: Blocked SOUTH at Z="..current_pos.z.." to Z="..tz)end;return false end end;if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo: Z OK at "..current_pos.z)end end; if tdir_opt~=nil and current_dir~=tdir_opt then if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"ml.moveTo: Adjust final dir to "..DIR_NAMES[tdir_opt].." ("..tdir_opt..")")end; if not ml.turnToDir(tdir_opt)then return false end end; if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"ml.moveTo: Target vicinity. Final Pos: X:"..current_pos.x.." Y:"..current_pos.y.." Z:"..current_pos.z.." Dir:"..current_dir.." ("..(current_dir and DIR_NAMES[current_dir] or "nil")..")")end; print(string.format("Console: ml.moveTo End - Current X:%s Y:%s Z:%s Dir:%s", current_pos.x, current_pos.y, current_pos.z, (current_dir and DIR_NAMES[current_dir] or "nil"))); return current_pos.x==tx and current_pos.y==ty and current_pos.z==tz and (tdir_opt == nil or current_dir == tdir_opt) end
- --#endregion
- --#region Core Logic Functions
- function initializeBot()
- print("Console: CHKPT - Enter initializeBot");
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initializeBot: Start")end;
- if not pAutomata then if LOG_LEVELS then botLog(LOG_LEVELS.FATAL,"initializeBot: pAutomata nil!")end; print("Console: initializeBot - pAutomata nil, FAIL"); return false end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"initializeBot: Warp 'home'")end;
- local ws,we=pcall(function()return pAutomata.warpToPoint("home")end);
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"initializeBot: Warp pcall: Success="..tostring(ws)..", Result="..tostring(we))end;
- if not ws or not we then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"initializeBot: Warp fail: Success="..tostring(ws)..", Result="..tostring(we))end; print("Console: initializeBot - Warp FAIL"); return false end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initializeBot: Warp OK. Now at physical home.")end;
- current_pos={x=nil,y=nil,z=nil};current_dir=nil;
- local me_bridge_peripheral_found = false
- for i=1,4 do
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "initializeBot: Attempt " .. i .. "/4 to find ME Bridge peripheral ("..ME_BRIDGE_PERIPHERAL_NAME..").") end
- pMeBridge = peripheral.find(ME_BRIDGE_PERIPHERAL_NAME)
- if pMeBridge then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "initializeBot: ME Bridge peripheral (type '"..ME_BRIDGE_PERIPHERAL_NAME.."') found on attempt " .. i .. ".") end
- mounted_peripherals["ME Bridge"] = pMeBridge
- me_bridge_peripheral_found = true
- break
- end
- if i < 4 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "initializeBot: ME Bridge peripheral not found in current direction. Turning right.") end
- if not turtle.turnRight() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "initializeBot: turtle.turnRight() failed during ME Bridge peripheral search.") end
- return false
- end
- sleep(0.2)
- end
- end
- if not me_bridge_peripheral_found then
- if LOG_LEVELS then botLog(LOG_LEVELS.FATAL, "initializeBot: ME Bridge peripheral (type '"..ME_BRIDGE_PERIPHERAL_NAME.."') NOT found after 4 attempts. This is required.") end
- return false
- end
- pColonyIntegrator = findPeripheral("Colony Integrator", COLONY_INTEGRATOR_PERIPHERAL_NAME, true)
- if not pColonyIntegrator then
- if LOG_LEVELS then botLog(LOG_LEVELS.FATAL, "initializeBot: Colony Integrator peripheral NOT found (it is required).") end
- return false
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initializeBot: Home location peripherals (ME Bridge, Colony Integrator) found and attached.") end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "initializeBot: Confirming visual orientation to ME Bridge block ('"..ME_BRIDGE_NAME.."')...") end
- local visually_oriented_to_me_block = false
- for visual_orient_attempt = 1, 4 do
- local success_inspect, block_in_front = turtle.inspect()
- if success_inspect and block_in_front and block_in_front.name == ME_BRIDGE_NAME then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "initializeBot: Visually confirmed: ME_BRIDGE_NAME block is in front (attempt " .. visual_orient_attempt .. ").") end
- visually_oriented_to_me_block = true
- break
- end
- if visual_orient_attempt < 4 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "initializeBot: Not visually facing ME_BRIDGE_NAME block. Turning right for visual confirmation.") end
- if not turtle.turnRight() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "initializeBot: turtle.turnRight() failed during visual ME Bridge confirmation.") end
- return false
- end
- sleep(0.2)
- end
- end
- if not visually_oriented_to_me_block then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "initializeBot: Could not visually confirm ME_BRIDGE_NAME block in front after 4 attempts. This is needed for coordinate setup.") end
- return false
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"initializeBot: Backing up from ME Bridge.")end;
- if not turtle.back()then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"initializeBot: Raw turtle.back() failed after orienting to ME Bridge.")end; print("Console: initializeBot - Back ME FAIL"); return false end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"initializeBot: Turning right to face Redstone path.")end;
- if not turtle.turnRight()then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"initializeBot: Raw turtle.turnRight() failed (to face Redstone path).")end; print("Console: initializeBot - TR after back FAIL"); return false end;
- local forward_count_to_redstone=0;
- local redstone_retries=0;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"initializeBot: Searching for Redstone Block ("..REDSTONE_BLOCK_NAME..") along path...")end;
- while true do
- -- CORRECTED THE RETURN VALUE HANDLING FOR PCALL(TURTLE.INSPECT)
- local pcall_success, inspect_success_val, block_data_val_or_errmsg = pcall(turtle.inspect);
- if pcall_success and inspect_success_val and block_data_val_or_errmsg and type(block_data_val_or_errmsg) == "table" and block_data_val_or_errmsg.name==REDSTONE_BLOCK_NAME then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initializeBot: Redstone Block found after " .. forward_count_to_redstone .. " forward moves.")end;
- break
- end;
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then
- local block_ahead_log_str = "pcall_fail"
- if pcall_success then
- if inspect_success_val then
- if block_data_val_or_errmsg and type(block_data_val_or_errmsg) == "table" then
- block_ahead_log_str = block_data_val_or_errmsg.name
- else
- block_ahead_log_str = "empty" -- inspect success, but no block table (air)
- end
- else
- block_ahead_log_str = "inspect_fail:" .. tostring(block_data_val_or_errmsg) -- inspect failed, block_data_val_or_errmsg is error
- end
- else
- block_ahead_log_str = "pcall_fail:" .. tostring(inspect_success_val) -- pcall failed, inspect_success_val is pcall error
- end
- botLog(LOG_LEVELS.DEBUG,"initializeBot: Redstone not found in front, moving forward. Count:"..forward_count_to_redstone.." BlockAhead: " .. block_ahead_log_str)
- end;
- if turtle.forward()then
- forward_count_to_redstone=forward_count_to_redstone+1;
- redstone_retries=0
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"initializeBot: Path to Redstone obstructed. Retry "..(redstone_retries+1).."/"..MAX_REDSTONE_BLOCK_RETRIES)end;
- redstone_retries=redstone_retries+1;
- if redstone_retries>=MAX_REDSTONE_BLOCK_RETRIES then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"initializeBot: Failed to reach Redstone Block after multiple retries.")end; print("Console: initializeBot - Redstone search FAIL (obstructed)"); return false
- end;
- sleep(REDSTONE_BLOCK_RETRY_WAIT)
- end
- end;
- roboSlot = forward_count_to_redstone + 1;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initializeBot: Determined roboSlot: "..roboSlot)end;
- local redstone_block_abs_x = -110
- local redstone_block_abs_y = 65
- local redstone_block_abs_z = 220
- local redstone_block_abs_dir = 1
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, string.format("initializeBot: Setting current pos at Redstone (Slot %d's marker): X%d Y%d Z%d Dir%s(1)", roboSlot, redstone_block_abs_x, redstone_block_abs_y, redstone_block_abs_z, DIR_NAMES[redstone_block_abs_dir]))end;
- ml.setPos(redstone_block_abs_x, redstone_block_abs_y, redstone_block_abs_z, redstone_block_abs_dir);
- home_pos.x = redstone_block_abs_x - (roboSlot - 1);
- home_pos.y = redstone_block_abs_y;
- home_pos.z = redstone_block_abs_z + 1;
- home_pos.dir = 0;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,string.format("initializeBot: Calculated home_pos: X%s Y%s Z%s Dir%s (%s)",home_pos.x,home_pos.y,home_pos.z,home_pos.dir, DIR_NAMES[home_pos.dir]))end;
- if not saveData()then if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"initializeBot: Save data failed post-initialization.")end end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"initializeBot: Initialization complete.")end;
- print("Console: CHKPT - initializeBot OK");
- return true
- end
- function maneuverToBarrelsFromHome()
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"maneuverToBarrelsFromHome: Start")end;
- if not(current_pos.x==home_pos.x and current_pos.y==home_pos.y and current_pos.z==home_pos.z and current_dir==home_pos.dir)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"maneuverToBarrelsFromHome: Not at home! Current: X"..current_pos.x.." Y"..current_pos.y.." Z"..current_pos.z.." D"..current_dir..". Home: X"..home_pos.x.." Y"..home_pos.y.." Z"..home_pos.z.." D"..home_pos.dir..". Aborting.")end;
- return false
- end;
- if not ml.moveTo(REFUEL_BARREL_ACCESS_POS.x,REFUEL_BARREL_ACCESS_POS.y,REFUEL_BARREL_ACCESS_POS.z,REFUEL_BARREL_ACCESS_POS.dir)then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"maneuverToBarrelsFromHome: Failed ml.moveTo barrel access point.")end;
- return false
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"maneuverToBarrelsFromHome: OK, at barrel access point.")end;
- return true
- end
- function maneuverHomeFromBarrels()
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"maneuverHomeFromBarrels: Start")end
- if not(current_pos.x==REFUEL_BARREL_ACCESS_POS.x and current_pos.y==REFUEL_BARREL_ACCESS_POS.y and current_pos.z==REFUEL_BARREL_ACCESS_POS.z and current_dir==REFUEL_BARREL_ACCESS_POS.dir)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"maneuverHomeFromBarrels: Not at barrel access point! Abort.")end; return false
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"maneuverHomeFromBarrels: Current pos at barrel access: X"..current_pos.x.." Y"..current_pos.y.." Z"..current_pos.z.." D"..DIR_NAMES[current_dir])end
- if not ml.turnRight() then return false end
- if not ml.forward() then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"maneuverHomeFromBarrels: Failed forward (North) after turning from barrel access.")end; return false end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"maneuverHomeFromBarrels: Intermediate pos: X"..current_pos.x.." Y"..current_pos.y.." Z"..current_pos.z.." D"..DIR_NAMES[current_dir])end
- local deltaX = home_pos.x - current_pos.x
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"maneuverHomeFromBarrels: Calculated deltaX to home: " .. deltaX .. " (home_pos.x: "..home_pos.x..", current_pos.x: "..current_pos.x..")") end
- if deltaX > 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"maneuverHomeFromBarrels: Moving East by "..deltaX)end
- if not ml.turnToDir(1) then return false end
- for _=1, deltaX do
- if not ml.forward() then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"maneuverHomeFromBarrels: Failed move East step.")end; return false end
- end
- elseif deltaX < 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"maneuverHomeFromBarrels: Moving West by "..math.abs(deltaX))end
- if not ml.turnToDir(3) then return false end
- for _=1, math.abs(deltaX) do
- if not ml.forward() then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"maneuverHomeFromBarrels: Failed move West step.")end; return false end
- end
- end
- if not ml.turnToDir(home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"maneuverHomeFromBarrels: Failed to turn North for final approach.")end; return false
- end
- if current_pos.z ~= home_pos.z then
- local deltaZ = home_pos.z - current_pos.z
- if deltaZ == 1 and current_dir == 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"maneuverHomeFromBarrels: Moving final step North to Z:"..home_pos.z)end
- if not ml.forward() then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"maneuverHomeFromBarrels: Failed final Northward move to home Z.")end; return false end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"maneuverHomeFromBarrels: Unexpected Z difference or direction for final move. deltaZ: "..deltaZ..", current_dir: "..current_dir)end; return false
- end
- end
- if current_pos.x==home_pos.x and current_pos.y==home_pos.y and current_pos.z==home_pos.z and current_dir==home_pos.dir then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"maneuverHomeFromBarrels: OK, successfully at home.")end; return true
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,string.format("maneuverHomeFromBarrels: Homing FAILED. Position Mismatch. Expected X%sY%sZ%sD%s, Got X%sY%sZ%sD%s", home_pos.x,home_pos.y,home_pos.z,DIR_NAMES[home_pos.dir], current_pos.x,current_pos.y,current_pos.z,DIR_NAMES[current_dir]))end;
- return false
- end
- end
- function goHomeProcedure()
- print("Console: CHKPT - Enter goHomeProcedure");
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"goHomeProcedure: Start")end;
- if current_pos.x==home_pos.x and current_pos.y==home_pos.y and current_pos.z==home_pos.z and current_dir==home_pos.dir then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"goHomeProcedure: Already at home.")end; print("Console: goHomeProcedure - Already home");
- return true
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"goHomeProcedure: Navigating to nest entry point x-113 y100 z221...")end;
- if not ml.moveTo(-113,100,221,nil)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"goHomeProcedure: Failed to navigate to nest entry point.")end; print("Console: goHomeProcedure - moveTo nest entry FAIL");
- return false
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"goHomeProcedure: At nest entry. Descending to Y65.")end;
- while current_pos.y > 65 do
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"goHomeProcedure: Descending. Current Y:"..current_pos.y)end;
- if not ml.down()then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"goHomeProcedure: Descend failed at Y:"..current_pos.y)end; print("Console: goHomeProcedure - descend FAIL");
- return false
- end
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"goHomeProcedure: Descended to Y65.")end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"goHomeProcedure: Moving to barrel access position defined by REFUEL_BARREL_ACCESS_POS")end;
- if not ml.moveTo(REFUEL_BARREL_ACCESS_POS.x,REFUEL_BARREL_ACCESS_POS.y,REFUEL_BARREL_ACCESS_POS.z,REFUEL_BARREL_ACCESS_POS.dir)then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"goHomeProcedure: Failed to move to defined barrel access position.")end;
- return false
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"goHomeProcedure: Positioned at refuel barrel access point.")end;
- if not maneuverHomeFromBarrels()then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"goHomeProcedure: maneuverHomeFromBarrels (called from goHomeProcedure) failed.")end;
- return false
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"goHomeProcedure: Successfully returned home.")end;
- print("Console: CHKPT - goHomeProcedure OK");
- return true
- end
- function handleFuel()
- print("Console: CHKPT - Enter handleFuel");
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleFuel: Start")end;
- if not(current_pos.x==REFUEL_BARREL_ACCESS_POS.x and current_pos.y==REFUEL_BARREL_ACCESS_POS.y and current_pos.z==REFUEL_BARREL_ACCESS_POS.z and current_dir==REFUEL_BARREL_ACCESS_POS.dir)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"handleFuel: Not at barrel access point. Skipping fuel handling.")end;
- return true
- end;
- local fuel_level, fuel_limit = ml.getFuelLevel(), ml.getFuelLimit();
- if fuel_limit == 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleFuel: Infinite fuel detected.")end;
- return true
- end;
- local fuel_percentage = (fuel_level / fuel_limit);
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,string.format("handleFuel: Fuel: %d/%d (%.2f%%)",fuel_level,fuel_limit,fuel_percentage*100))end;
- local needs_refuel = fuel_percentage < REFUEL_BELOW_PERCENTAGE;
- local coal_detail = ml.getItemDetail(FUEL_SLOT);
- local coal_count = ml.getItemCount(FUEL_SLOT);
- local needs_restock = not coal_detail or coal_detail.name ~= COAL_BLOCK_NAME or coal_count < (coal_detail and coal_detail.maxCount or 64);
- if needs_refuel or needs_restock then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleFuel: Action required. Needs Refuel="..tostring(needs_refuel)..", Needs Restock="..tostring(needs_restock))end;
- if needs_restock then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleFuel: Restocking fuel slot "..FUEL_SLOT.." with "..COAL_BLOCK_NAME)end;
- ml.select(FUEL_SLOT);
- if coal_detail and coal_detail.name ~= COAL_BLOCK_NAME and coal_count > 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"handleFuel: Non-"..COAL_BLOCK_NAME.." item found in fuel slot! Cannot restock unless slot is cleared or contains correct item type.")end
- else
- local amount_to_suck = (coal_detail and coal_detail.maxCount or 64) - coal_count;
- if amount_to_suck > 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"handleFuel: Attempting to suck "..amount_to_suck.." "..COAL_BLOCK_NAME..".")end;
- if ml.suck(amount_to_suck)then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleFuel: Sucked "..COAL_BLOCK_NAME.." into fuel slot. New count: "..ml.getItemCount(FUEL_SLOT))end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"handleFuel: Failed to suck "..COAL_BLOCK_NAME.." into fuel slot.")end
- end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"handleFuel: Fuel slot already full of "..COAL_BLOCK_NAME.." or needs 0 items.")end
- end
- end
- end;
- coal_detail = ml.getItemDetail(FUEL_SLOT)
- if fuel_percentage < REFUEL_BELOW_PERCENTAGE and coal_detail and coal_detail.name == COAL_BLOCK_NAME then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleFuel: Refueling...")end;
- if not ml.refuel()then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"handleFuel: ml.refuel() attempt failed.")end
- end
- elseif fuel_percentage < REFUEL_BELOW_PERCENTAGE then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"handleFuel: Needs refuel, but fuel slot does not contain "..COAL_BLOCK_NAME)end
- end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleFuel: Fuel level and stock OK.")end
- end;
- print("Console: CHKPT - Exit handleFuel");
- return true
- end
- function handleItemReturn()
- print("Console: CHKPT - Enter handleItemReturn");
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleItemReturn: Start")end;
- if not(current_pos.x==REFUEL_BARREL_ACCESS_POS.x and current_pos.y==REFUEL_BARREL_ACCESS_POS.y and current_pos.z==REFUEL_BARREL_ACCESS_POS.z and current_dir==REFUEL_BARREL_ACCESS_POS.dir)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"handleItemReturn: Not at barrel access point. Skipping item return.")end;
- return true
- end;
- local items_found_to_return=false;
- for slot_idx=1,15 do
- if ml.getItemCount(slot_idx)>0 then
- items_found_to_return=true;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"handleItemReturn: Found items in slot "..slot_idx.." to return.")end;
- break
- end
- end;
- if not items_found_to_return then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleItemReturn: No items in cargo slots 1-15 to return.")end; print("Console: handleItemReturn - No items");
- return true
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleItemReturn: Items found for return. Moving up to Return Barrel.")end;
- if not ml.up()then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"handleItemReturn: Failed to move up to Return Barrel level.")end; print("Console: handleItemReturn - up FAIL");
- return false
- end;
- for slot_idx=1,15 do
- ml.select(slot_idx);
- local item_count_in_slot=ml.getItemCount(slot_idx);
- if item_count_in_slot > 0 then
- local item_detail=ml.getItemDetail(slot_idx);
- local item_name = item_detail and item_detail.name or "Unknown Item";
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"handleItemReturn: Attempting to return "..item_count_in_slot.."x "..item_name.." from slot "..slot_idx)end;
- if not ml.drop()then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"handleItemReturn: Failed to drop items from slot "..slot_idx)end
- end
- end
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"handleItemReturn: Finished attempting returns. Moving down from Return Barrel level.")end;
- if not ml.down()then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"handleItemReturn: Failed to move down from Return Barrel level.")end; print("Console: handleItemReturn - down FAIL");
- return false
- end;
- undeliveredItemsBuffer = {}
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"handleItemReturn: Item return process complete.")end;
- print("Console: CHKPT - Exit handleItemReturn");
- return true
- end
- function getItemsFromME(itemsToGetTable)
- print("Console: CHKPT - Enter getItemsFromME")
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "getItemsFromME: Start processing item requests.") end
- if not (current_pos.x == home_pos.x and current_pos.y == home_pos.y and current_pos.z == home_pos.z and current_dir == home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, "getItemsFromME: Not at home position. Aborting.") end
- return {}
- end
- if not pMeBridge then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "getItemsFromME: pMeBridge (ME Bridge peripheral) is nil. Aborting.") end
- return {}
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "getItemsFromME: Moving up to access ME transfer chest.") end
- if not ml.up() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "getItemsFromME: Failed to move up to ME transfer chest level.") end
- return {}
- end
- local fetched_item_details = {}
- for _, requested_item_spec in ipairs(itemsToGetTable) do
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "getItemsFromME: Requesting " .. requested_item_spec.count .. "x " .. requested_item_spec.name .. " from ME system.") end
- local export_success, export_result = pcall(function() return pMeBridge.exportItem({ name = requested_item_spec.name, count = requested_item_spec.count }, "up") end)
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "getItemsFromME: exportItem pcall Success=" .. tostring(export_success) .. ", Result=" .. textutils.serialize(export_result)) end
- if not export_success or type(export_result) ~= "number" or export_result == 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, "getItemsFromME: ME export failed or exported 0 for " .. requested_item_spec.name .. ". Error/Msg: " .. tostring(export_result)) end
- goto continue_me_item_request
- end
- local actual_exported_count = export_result
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "getItemsFromME: ME Bridge exported " .. actual_exported_count .. "x " .. requested_item_spec.name .. " to chest.") end
- local amount_remaining_to_suck_from_chest = actual_exported_count
- while amount_remaining_to_suck_from_chest > 0 do
- local target_slot = -1
- for s = 1, 15 do
- local item_in_slot = ml.getItemDetail(s)
- if item_in_slot and item_in_slot.name == requested_item_spec.name and item_in_slot.count < item_in_slot.maxCount then
- target_slot = s
- break
- end
- end
- if target_slot == -1 then
- for s = 1, 15 do
- if not ml.getItemDetail(s) then
- target_slot = s
- break
- end
- end
- end
- if target_slot == -1 then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, "getItemsFromME: No inventory space for more '" .. requested_item_spec.name .. "' (needed " .. amount_remaining_to_suck_from_chest .. "). Items may remain in chest.") end
- break
- end
- ml.select(target_slot)
- local space_in_this_slot = turtle.getItemSpace(target_slot)
- local attempt_suck_amount = math.min(amount_remaining_to_suck_from_chest, space_in_this_slot)
- if attempt_suck_amount == 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "getItemsFromME: Slot " .. target_slot .. " is full or no more items needed for " .. requested_item_spec.name .. ". Skipping suck.") end
- break
- end
- local count_in_slot_before_suck = ml.getItemCount(target_slot)
- if ml.suck(attempt_suck_amount) then
- local count_in_slot_after_suck = ml.getItemCount(target_slot)
- local num_actually_sucked_this_op = count_in_slot_after_suck - count_in_slot_before_suck
- if num_actually_sucked_this_op > 0 then
- amount_remaining_to_suck_from_chest = amount_remaining_to_suck_from_chest - num_actually_sucked_this_op
- local existing_entry_idx = -1
- for i, entry in ipairs(fetched_item_details) do
- if entry.slot == target_slot then
- existing_entry_idx = i; break
- end
- end
- if existing_entry_idx ~= -1 then
- fetched_item_details[existing_entry_idx].count = count_in_slot_after_suck
- else
- table.insert(fetched_item_details, { name = requested_item_spec.name, slot = target_slot, count = count_in_slot_after_suck })
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "getItemsFromME: Sucked " .. num_actually_sucked_this_op .. "x " .. requested_item_spec.name .. " into slot " .. target_slot .. ". Total in slot: " .. count_in_slot_after_suck .. ". Remaining from chest: " .. amount_remaining_to_suck_from_chest) end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "getItemsFromME: ml.suck() transferred 0 items for " .. requested_item_spec.name .. " into slot " .. target_slot .. ". Chest might be empty for this item now.") end
- break
- end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, "getItemsFromME: ml.suck() failed for " .. requested_item_spec.name .. " into slot " .. target_slot .. ". Chest might be obstructed or empty.") end
- break
- end
- end
- ::continue_me_item_request::
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "getItemsFromME: Finished processing all item requests. Moving down from ME chest level.") end
- if not ml.down() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "getItemsFromME: Failed to move down from ME transfer chest level.") end
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "getItemsFromME: Process complete. Fetched " .. #fetched_item_details .. " item stacks/details.") end
- print("Console: CHKPT - Exit getItemsFromME")
- return fetched_item_details
- end
- function leaveNest()
- print("Console: CHKPT - Enter leaveNest");
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"leaveNest: Start")end;
- local start_exit_pos_x = home_pos.x
- local start_exit_pos_y = home_pos.y
- local start_exit_pos_z = home_pos.z - 1
- local start_exit_dir = 1
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, string.format("leaveNest: Moving to its redstone block position (X%s Y%s Z%s Dir%s) to begin exit sequence.", start_exit_pos_x, start_exit_pos_y, start_exit_pos_z, DIR_NAMES[start_exit_dir]))end;
- if not ml.moveTo(start_exit_pos_x, start_exit_pos_y, start_exit_pos_z, start_exit_dir)then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"leaveNest: Failed to move to its redstone block to start exit sequence.")end;
- return false
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"leaveNest: Turning South (TR from East).")end;
- if not ml.turnRight()then return false end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"leaveNest: Moving Forward (South).")end;
- if not ml.forward()then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"leaveNest: Obstructed moving South during exit.")end;return false end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"leaveNest: Turning West (TR from South).")end;
- if not ml.turnRight()then return false end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"leaveNest: Moving Forward (West).")end;
- if not ml.forward()then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"leaveNest: Obstructed moving West during exit.")end;return false end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"leaveNest: Ascending to Y=100...")end;
- while current_pos.y < 100 do
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"leaveNest: Ascending. Current Y:"..current_pos.y)end;
- if not ml.up()then if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"leaveNest: Obstructed during ascent at Y:"..current_pos.y)end;return false end
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"leaveNest: Reached Y=100.")end;
- local target_exit_x = -111
- local target_exit_y = 100
- local target_exit_z = 221
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, string.format("leaveNest: Moving to final exit point (X%s Y%s Z%s).",target_exit_x, target_exit_y, target_exit_z))end;
- if not ml.moveTo(target_exit_x, target_exit_y, target_exit_z, nil)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, string.format("leaveNest: Could not reach precise final exit point. Current Y:%s. Target was X%s Y%s Z%s.", current_pos.y, target_exit_x, target_exit_y, target_exit_z))end;
- if current_pos.y ~= target_exit_y then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"leaveNest: Critical - Y coordinate incorrect after ascent and moveTo. Expected Y"..target_exit_y)end;
- return false
- end
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,string.format("leaveNest: Successfully exited nest. Current Position: X:%s Y:%s Z:%s Dir:%s (%s)",current_pos.x,current_pos.y,current_pos.z,current_dir, DIR_NAMES[current_dir]))end;
- print("Console: CHKPT - Exit leaveNest");
- return true
- end
- function deliverItems(target_pos,items_in_slots_details)
- print("Console: CHKPT - Enter deliverItems");
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,string.format("deliverItems: Target X:%s Y:%s Z:%s",target_pos.x,target_pos.y,target_pos.z))end;
- if not ml.moveTo(target_pos.x,target_pos.y,target_pos.z,nil)then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"deliverItems: Failed to move to delivery location.")end;
- for _,item_detail_entry in ipairs(items_in_slots_details)do
- table.insert(undeliveredItemsBuffer,{name=item_detail_entry.name,count=item_detail_entry.count,original_slot=item_detail_entry.slot})
- end;
- if DEBUG_LOGGING_ENABLED and LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"deliverItems: All items for this delivery moved to undeliveredItemsBuffer. Buffer size:"..#undeliveredItemsBuffer)end;
- return false
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"deliverItems: Arrived at delivery location. Attempting to drop items.")end;
- for _,item_detail_entry in ipairs(items_in_slots_details)do
- ml.select(item_detail_entry.slot);
- local count_to_drop = ml.getItemCount(item_detail_entry.slot);
- if count_to_drop > 0 then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"deliverItems: Attempting to drop "..count_to_drop.."x "..item_detail_entry.name.." from slot "..item_detail_entry.slot)end;
- if not ml.drop(count_to_drop)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"deliverItems: Failed to drop all items ("..item_detail_entry.name..") from slot "..item_detail_entry.slot)end;
- local remaining_count = ml.getItemCount(item_detail_entry.slot);
- if remaining_count > 0 then
- table.insert(undeliveredItemsBuffer,{name=item_detail_entry.name,count=remaining_count,original_slot=item_detail_entry.slot});
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"deliverItems: "..remaining_count.."x "..item_detail_entry.name.." from slot "..item_detail_entry.slot.." added to undeliveredItemsBuffer.")end
- end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"deliverItems: Successfully dropped "..count_to_drop.."x "..item_detail_entry.name.." from slot "..item_detail_entry.slot)end
- end
- end
- end;
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"deliverItems: Delivery attempt complete.")end;
- print("Console: CHKPT - Exit deliverItems");
- return true
- end
- --#endregion
- --#region Main Loop
- local function run()
- print("Console: CHKPT - run() CALLED")
- do
- local fileNameToOpen = LOG_FILE_NAME_CONST
- if type(fileNameToOpen) ~= "string" then
- print("Console: CRITICAL - LOG_FILE_NAME_CONST is nil AT THE POINT OF OPENING. Forcing default for safety.")
- fileNameToOpen = "villagebot_forced_CRITICAL.log"
- end
- local f,ferr=fs.open(fileNameToOpen,"w")
- if f then
- f.write(string.format("[%s] VillageBot Log Initialized.\n",os.date("%Y-%m-%d %H:%M:%S")))
- f.close()
- print("Console: Log file reset and initialized using: " .. fileNameToOpen)
- else
- print("Console: CRITICAL - Log init FAIL for '" .. tostring(fileNameToOpen) .. "': "..tostring(ferr))
- if LOG_LEVELS and pcall then
- pcall(botLog,LOG_LEVELS.FATAL,"CRITICAL - Log init FAIL: "..tostring(ferr))
- end
- return
- end
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"VillageBot v1.4 Starting...") else print("Console: VillageBot v1.4 Starting... (LOG_LEVELS nil)") end
- sleep(0.1)
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"RUN: Attempt init core peripherals...") end; sleep(0.1)
- local corePOK=initCorePeripherals();
- if not corePOK then if LOG_LEVELS then botLog(LOG_LEVELS.FATAL,"RUN: initCorePeripherals FAILED. Terminating script.")end; print("Console: Error - Core Peripheral init FAILED. Terminate from run()."); return end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"RUN: Core Peripherals OK.")end; sleep(0.1)
- local data_setup_successful=false
- if loadData() and roboSlot~=nil and home_pos and home_pos.x~=nil and current_pos and current_pos.x~=nil and current_dir~=nil then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"RUN: Bot data loaded successfully. RoboSlot:"..roboSlot)end
- data_setup_successful=true
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"RUN: No valid data file found or data incomplete. Performing full initialization.")end
- if fs.exists(BOT_DATA_FILE) then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"RUN: Existing data file was present but invalid. Deleting it.")end
- pcall(fs.delete, BOT_DATA_FILE)
- end
- if initializeBot()then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"RUN: Bot full initialization successful.")end
- data_setup_successful=true
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.FATAL,"RUN: Bot full initialization FAILED. Terminating script.")end;print("Console: Error - Bot core initialization FAILED. Terminate.");return
- end
- end
- if not data_setup_successful then if LOG_LEVELS then botLog(LOG_LEVELS.FATAL,"RUN: Failed to load or initialize bot data. Terminating script.")end;print("Console: FATAL - Data setup FAILED. Terminate.");return end
- if not pMeBridge or not pColonyIntegrator then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "RUN: Home location peripherals (ME Bridge, Colony Integrator) not yet confirmed/attached. Ensuring bot is home and then finding/attaching them.") end
- if not (current_pos.x == home_pos.x and current_pos.y == home_pos.y and current_pos.z == home_pos.z and current_dir == home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "RUN: Bot is not at home. Running goHomeProcedure to reach home first.") end
- if not goHomeProcedure() then
- if LOG_LEVELS then botLog(LOG_LEVELS.FATAL, "RUN: goHomeProcedure failed during setup phase. Cannot find home peripherals. Terminating.") end
- return
- end
- end
- if not findHomeLocationPeripherals() then
- if LOG_LEVELS then botLog(LOG_LEVELS.FATAL, "RUN: Failed to find/attach home location peripherals even after ensuring bot is at home. Terminating.") end
- return
- end
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"RUN: Data load/initialization phase complete. All required peripherals should now be found."); end; sleep(0.1)
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"RUN: Entering main operational loop...")end;
- while true do
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "===== Starting New Cycle =====")end; sleep(0.1)
- local dummy_work_order, items_to_fetch, fetched_items_summary = nil,nil,nil
- local needs_dedicated_barrel_trip_flag = false
- local fuel_check_still_needed_flag = true
- local item_return_check_still_needed_flag = true
- local was_at_barrels_this_cycle_leg = false
- if not (current_pos.x == home_pos.x and current_pos.y == home_pos.y and current_pos.z == home_pos.z and current_dir == home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "LOOP: Not at home. Current: X"..current_pos.x.." Y"..current_pos.y.." Z"..current_pos.z.." D"..(current_dir and DIR_NAMES[current_dir] or "nil")..". Executing goHomeProcedure.")end
- if not goHomeProcedure() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"LOOP: goHomeProcedure failed. Retrying cycle after a delay.")end
- sleep(60); goto continue_main_loop_cycle
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: goHomeProcedure completed. Bot should now be at home (and passed barrels).")end
- was_at_barrels_this_cycle_leg = true
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Started cycle already at home position.")end
- end
- if was_at_barrels_this_cycle_leg then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Bot was at barrels during goHomeProcedure transit. Performing necessary checks now.")end
- else
- local current_fuel_level = ml.getFuelLevel(); local current_fuel_limit = ml.getFuelLimit()
- if current_fuel_limit == 0 or (current_fuel_limit > 0 and (current_fuel_level / current_fuel_limit >= REFUEL_BELOW_PERCENTAGE)) then
- fuel_check_still_needed_flag = false
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Fuel OK or infinite type, no dedicated trip needed *just* for low fuel percentage.")end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Fuel is low. Dedicated trip for fuel may be needed.")end
- end
- local items_in_cargo_slots = false
- for slot_idx=1,15 do if ml.getItemCount(slot_idx) > 0 then items_in_cargo_slots = true; break; end end
- if not items_in_cargo_slots then
- item_return_check_still_needed_flag = false
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: No items in cargo slots, no dedicated trip needed *just* for item return.")end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Items found in cargo slots. Dedicated trip for item return may be needed.")end
- end
- local coal_detail_check = ml.getItemDetail(FUEL_SLOT)
- local needs_fuel_slot_restock = not coal_detail_check or coal_detail_check.name ~= COAL_BLOCK_NAME or ml.getItemCount(FUEL_SLOT) < (coal_detail_check and coal_detail_check.maxCount or 64)
- if needs_fuel_slot_restock then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Fuel slot needs restocking. Dedicated trip for fuel may be needed.")end
- fuel_check_still_needed_flag = true
- end
- needs_dedicated_barrel_trip_flag = fuel_check_still_needed_flag or item_return_check_still_needed_flag
- if needs_dedicated_barrel_trip_flag then
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO, "LOOP: Bot is at home, but needs fuel/item return. Maneuvering to barrels. FuelNeeded="..tostring(fuel_check_still_needed_flag).." ItemReturnNeeded="..tostring(item_return_check_still_needed_flag))end
- if not maneuverToBarrelsFromHome() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "LOOP: Failed to maneuver to barrels from home. Retrying cycle after a delay.")end
- sleep(60); goto continue_main_loop_cycle
- end
- was_at_barrels_this_cycle_leg = true
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Bot is at home, and no dedicated fuel/return operations are immediately required from here.")end
- end
- end
- if was_at_barrels_this_cycle_leg then
- if item_return_check_still_needed_flag then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Performing item return at barrels.")end
- if not handleItemReturn() then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN, "LOOP: An issue occurred during item return at barrels. Continuing.")end
- end
- end
- if fuel_check_still_needed_flag then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Performing fuel handling at barrels.")end
- if not handleFuel() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "LOOP: Failed fuel handling at barrels. Retrying cycle after a delay.")end;
- sleep(60); goto continue_main_loop_cycle
- end
- end
- if not (current_pos.x == home_pos.x and current_pos.y == home_pos.y and current_pos.z == home_pos.z and current_dir == home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG, "LOOP: Not at home after barrel operations. Maneuvering home from barrels.")end
- if not maneuverHomeFromBarrels() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR, "LOOP: Failed to maneuver home from barrels after operations. Retrying cycle after a delay.")end
- sleep(60); goto continue_main_loop_cycle
- end
- end
- end
- if not(current_pos.x==home_pos.x and current_pos.y==home_pos.y and current_pos.z==home_pos.z and current_dir==home_pos.dir) then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"LOOP: CRITICAL - NOT AT HOME before attempting to get work! Pos: X"..current_pos.x.." Y"..current_pos.y.." Z"..current_pos.z.." D"..(current_dir and DIR_NAMES[current_dir] or "nil")..". Forcing goHomeProcedure.")end
- if not goHomeProcedure() then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"LOOP: Critical Failure on forced goHomeProcedure. Retrying cycle after a delay.")end
- sleep(60); goto continue_main_loop_cycle
- end
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"LOOP: Position confirmed at home before starting work tasks.")end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"LOOP: Fetching work order (V1.4 Placeholder)...")end
- dummy_work_order={id="dummyWorkOrder123", resources={{name="minecraft:cobblestone",count=65},{name="minecraft:dirt",count=33}}, target_location={x=home_pos.x+10,y=home_pos.y,z=home_pos.z+5}}
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,string.format("LOOP: Dummy Work Order: Deliver items to X:%s Y:%s Z:%s", dummy_work_order.target_location.x, dummy_work_order.target_location.y, dummy_work_order.target_location.z ))end
- if dummy_work_order and dummy_work_order.resources then
- items_to_fetch = dummy_work_order.resources
- fetched_items_summary = getItemsFromME(items_to_fetch)
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"LOOP: getItemsFromME returned "..#fetched_items_summary.." item slot details.")end
- local has_items_to_deliver = false
- if fetched_items_summary and #fetched_items_summary > 0 then
- for _, item_entry in ipairs(fetched_items_summary) do
- if item_entry.count > 0 then has_items_to_deliver = true; break; end
- end
- end
- if has_items_to_deliver then
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"LOOP: Items fetched. Attempting to leave nest.")end
- if not leaveNest()then
- if LOG_LEVELS then botLog(LOG_LEVELS.ERROR,"LOOP: Failed to leave nest. Items will be returned next cycle if still in inventory. Retrying cycle after delay.")end
- sleep(30);goto continue_main_loop_cycle
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"LOOP: leaveNest successful.")end
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"LOOP: Attempting to deliver items.")end
- if not deliverItems(dummy_work_order.target_location, fetched_items_summary)then
- if LOG_LEVELS then botLog(LOG_LEVELS.WARN,"LOOP: Delivery issues encountered. Any undelivered items were buffered (and will be handled by handleItemReturn next cycle).")end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"LOOP: deliverItems process completed (check logs for specifics).")end
- end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"LOOP: No items were actually fetched from ME system for the current work order, or fetched items had 0 count.")end
- end
- else
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"LOOP: No work orders found or work order invalid.")end
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.INFO,"===== Cycle Ended Successfully =====")end
- ::continue_main_loop_cycle::
- if LOG_LEVELS then botLog(LOG_LEVELS.DEBUG,"LOOP: Sleeping for 30 seconds before next cycle.")end
- print("Console: LOOP - Cycle End. Sleeping 30s.")
- sleep(30)
- end
- if LOG_LEVELS then botLog(LOG_LEVELS.FATAL,"RUN: Main operational loop EXITED UNEXPECTEDLY!")end; print("Console: FATAL - Main loop EXITED!")
- end
- --#endregion
- -- Start the bot
- print("Console: DEBUG - Script execution starting. About to call run().")
- run()
- print("Console: DEBUG - Script execution finished. run() function has completed/exited.")
- if LOG_LEVELS and LOG_FILE_NAME_CONST and type(LOG_FILE_NAME_CONST) == "string" then
- pcall(botLog,LOG_LEVELS.FATAL, "SCRIPT ENDED ABNORMALLY: Reached end of file after run() call, indicating run() exited.")
- else
- print("Console: SCRIPT ENDED ABNORMALLY (LOG_LEVELS or LOG_FILE_NAME_CONST was nil/invalid, cannot use botLog for final message).")
- end
Add Comment
Please, Sign In to add comment