Myros27

mineBot V2

May 22nd, 2025 (edited)
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 43.26 KB | None | 0 0
  1. -- Advanced Mining Turtle for CC: Tweaked
  2.  
  3. -- Configuration
  4. local DEBUG_MODE = false
  5. -- No LOG_FILE, LOG_CYCLE_LIMIT, or old global main_loop_cycle_count_for_log needed
  6.  
  7. -- Delete old log file if it exists (one-time operation)
  8. local OLD_LOG_FILE_NAME = "miner_log.txt"
  9. if fs.exists(OLD_LOG_FILE_NAME) then
  10.     fs.delete(OLD_LOG_FILE_NAME)
  11.     print(os.date("%Y-%m-%d %H:%M:%S") .. " - Deleted old log file: " .. OLD_LOG_FILE_NAME)
  12. end
  13.  
  14. local FUEL_ENDER_CHEST_NBT = nil
  15. local ITEM_DUMP_ENDER_CHEST_NBT = "12dc70dc0c75dbe36569479175a42608"
  16.  
  17. local FUEL_ALERT_PERCENTAGE = 40
  18. local MIN_FREE_SLOTS_FOR_OPERATION = 2
  19. local WORLD_BOTTOM_Y_CALIBRATION_DEPTH = 317
  20.  
  21. local ENDER_CHEST_ITEM_NAME = "enderstorage:ender_chest"
  22. local COAL_BLOCK_ITEM_NAME = "minecraft:coal_block"
  23. local CHUNK_CONTROLLER_ITEM_NAME = "advancedperipherals:chunk_controller"
  24. local BEDROCK_ITEM_NAME = "minecraft:bedrock"
  25. local AIR_ITEM_NAME = "minecraft:air"
  26.  
  27. local is_y_calibrated = false
  28. local dig_and_move_actions_before_check = 0
  29. local current_y_relative = 0
  30.  
  31. --------------------------------------------------------------------------------
  32. -- Logging, Error Handling, and Table Serialization
  33. --------------------------------------------------------------------------------
  34. -- serialize_table remains unchanged as it's a general utility
  35. local function serialize_table(tbl,indent_level)indent_level=indent_level or 0;local i_s=string.rep("  ",indent_level);local p={};if type(tbl)~="table"then return tostring(tbl)end;table.insert(p,"{");local f=true;for k,v in pairs(tbl)do if not f then table.insert(p,",")end;f=false;table.insert(p,"\n"..string.rep("  ",indent_level+1));if type(k)=="string"then table.insert(p,k.." = ")else table.insert(p,"["..tostring(k).."] = ")end;if type(v)=="table"then table.insert(p,serialize_table(v,indent_level+1))elseif type(v)=="string"then table.insert(p,"\""..tostring(v):gsub("\"","\\\"").."\"")else table.insert(p,tostring(v))end end;table.insert(p,"\n"..i_s.."}");return table.concat(p)end
  36.  
  37. local function log_message(msg, data_tbl)
  38.     local is_important_msg = msg:find("FATAL ERROR") or
  39.                              msg:find("--- Initializing") or
  40.                              msg:find("--- Sys Check") or -- Covers "--- Sys Check ---" and "--- Sys Check Done ---"
  41.                              msg:find("Start Scenario") or -- Covers startup scenario messages
  42.                              msg:find("Starting Main Mining Loop") or
  43.                              msg:find("Cycle #") or
  44.                              msg:find("Y-cal:") or -- Covers Y-calibration messages
  45.                              msg:find("Refuel") or -- Covers "Refueling...", "Refueled", "Refueling complete."
  46.                              msg:find("Deposit") or -- Covers "Depositing...", "Deposit done."
  47.                              msg:find("WARN:") or msg:find("CRIT:") or -- Covers warnings and critical non-fatal messages
  48.                              msg:find("SP1 complete") or msg:find("SP2 confirmed") or -- Important startup milestones
  49.                              msg:find("Equipped items check summary") or msg:find("Initial inventory scan summary")
  50.  
  51.  
  52.     if DEBUG_MODE or is_important_msg then
  53.         print(os.date("%Y-%m-%d %H:%M:%S") .. " - " .. msg)
  54.         if DEBUG_MODE and data_tbl then
  55.             print("Data (Debug):\n" .. serialize_table(data_tbl))
  56.         end
  57.     end
  58. end
  59.  
  60. local function error_stop(msg, data_tbl)
  61.     local full_msg = "FATAL ERROR: " .. msg
  62.     -- log_message will print the error message (as it contains "FATAL ERROR")
  63.     log_message(full_msg, data_tbl)
  64.     print(os.date("%Y-%m-%d %H:%M:%S") .. " - Stopping due to fatal error.") -- Explicit stop message
  65.     error(full_msg, 0) -- Halt script execution
  66. end
  67.  
  68. --------------------------------------------------------------------------------
  69. -- Helper Functions (Logging calls updated)
  70. --------------------------------------------------------------------------------
  71. local function find_item_in_inventory(f, dbg_ctx)
  72.     if DEBUG_MODE and dbg_ctx then log_message("Debug: find_item_in_inventory for: " .. dbg_ctx) end
  73.     for i = 1, 16 do
  74.         local d = turtle.getItemDetail(i)
  75.         if d and d.name ~= AIR_ITEM_NAME then
  76.             if DEBUG_MODE and dbg_ctx then log_message("  Debug: Chk slot " .. i .. " for '" .. dbg_ctx .. "':", d) end
  77.             if f(d, i) then
  78.                 if DEBUG_MODE and dbg_ctx then log_message("    Debug: Found match slot " .. i .. " for '" .. dbg_ctx .. "'") end
  79.                 return i, d
  80.             end
  81.         end
  82.     end
  83.     if DEBUG_MODE and dbg_ctx then log_message("  Debug: No match for '" .. dbg_ctx .. "'") end
  84.     return nil, nil
  85. end
  86.  
  87. local function count_free_slots()local c=0;for i=1,16 do if turtle.getItemCount(i)==0 then c=c+1 end end;return c end
  88. local function turn_around()turtle.turnLeft();turtle.turnLeft()end
  89.  
  90. local function get_item_from_hand_temporarily(h_s)
  91.     log_message("Checking " .. h_s .. " hand...") -- This is an important step in startup.
  92.     local e_s = nil
  93.     for i = 16, 1, -1 do -- Prefer higher slots for temp storage
  94.         if turtle.getItemCount(i) == 0 then e_s = i; break end
  95.     end
  96.     if not e_s then error_stop("No empty inventory slot available for hand check operation.") return nil end
  97.    
  98.     if DEBUG_MODE then log_message("Debug: Using temp slot " .. e_s .. " for " .. h_s .. " hand check.") end
  99.     local o_s = turtle.getSelectedSlot()
  100.     turtle.select(e_s)
  101.     local u_ok -- "unequip_ok" or "usage_ok"
  102.     if h_s == "left" then u_ok = turtle.equipLeft()
  103.     elseif h_s == "right" then u_ok = turtle.equipRight()
  104.     else
  105.         turtle.select(o_s)
  106.         error_stop("Invalid hand specified for get_item_from_hand_temporarily: " .. h_s)
  107.         return nil -- Should not be reached due to error_stop
  108.     end
  109.  
  110.     local i_d = nil -- item_detail
  111.     if u_ok then
  112.         i_d = turtle.getItemDetail(e_s)
  113.         if i_d and i_d.name ~= AIR_ITEM_NAME then
  114.             log_message(h_s .. " hand contained: " .. i_d.name, (DEBUG_MODE and i_d or nil) )
  115.             turtle.select(e_s) -- Ensure e_s (now holding the item) is selected
  116.             local r_ok -- "re_equip_ok"
  117.             if h_s == "left" then r_ok = turtle.equipLeft() -- Equip item from e_s back to hand
  118.             else r_ok = turtle.equipRight() end
  119.             if not r_ok then error_stop("CRIT: Failed to re-equip " .. i_d.name .. " to " .. h_s .. " hand from slot " .. e_s) end
  120.             if DEBUG_MODE then log_message("Debug: Item " .. i_d.name .. " re-equipped to " .. h_s .. " hand.") end
  121.         else
  122.             log_message(h_s .. " hand is empty or holds air.")
  123.             i_d = nil -- Ensure i_d is nil if hand was effectively empty
  124.         end
  125.     else
  126.         -- This case implies hand was empty, so equipLeft/Right (to unequip) moved nothing.
  127.         log_message(h_s .. " hand was already empty (or unequip attempt reported no action, u_ok="..tostring(u_ok)..").")
  128.         i_d = nil
  129.     end
  130.     turtle.select(o_s) -- Restore original selected slot
  131.     return i_d
  132. end
  133.  
  134. local function safe_dig_generic(d_f,dir_name,insp_f)
  135.     if not d_f() then -- Dig attempt failed
  136.         local insp_s, blk_d = insp_f() -- Inspect to see what's there
  137.         if insp_s then -- Successfully inspected a block
  138.             if blk_d.name:lower() == BEDROCK_ITEM_NAME:lower() then
  139.                 log_message("Cannot dig " .. dir_name .. ", encountered " .. blk_d.name .. ".")
  140.                 return false -- Indicate undiggable block (bedrock)
  141.             end
  142.             -- Some other block is there that couldn't be dug
  143.             error_stop("Failed to dig " .. dir_name .. " (block present: " .. blk_d.name .. "). Possible tool issue or other unbreakable block?")
  144.         else
  145.             -- Inspect failed. Could be air, or some non-block entity.
  146.             -- Assume it's effectively clear or became clear.
  147.             return true
  148.         end
  149.     end
  150.     if DEBUG_MODE then log_message("Debug: Successfully dug " .. dir_name .. ".") end
  151.     return true -- Dig was successful
  152. end
  153.  
  154. local function safe_dig()return safe_dig_generic(turtle.dig,"fwd",turtle.inspect)end
  155. local function safe_dig_up()return safe_dig_generic(turtle.digUp,"up",turtle.inspectUp)end
  156. local function safe_dig_down()return safe_dig_generic(turtle.digDown,"down",turtle.inspectDown)end
  157.  
  158. local function safe_move_generic(m_f,dir)if not m_f()then error_stop("Failed to move "..dir)end; if DEBUG_MODE then log_message("Debug: Moved "..dir) end; return true end
  159. local function safe_forward()return safe_move_generic(turtle.forward,"fwd")end;local function safe_back()return safe_move_generic(turtle.back,"back")end;local function safe_up()return safe_move_generic(turtle.up,"up")end;local function safe_down()return safe_move_generic(turtle.down,"down")end
  160. local function safe_place(s)if not s then error_stop("safe_place: no slot specified.")end;local o=turtle.getSelectedSlot();turtle.select(s);if not turtle.place()then turtle.select(o);error_stop("Failed to place item from slot "..s)end;turtle.select(o); if DEBUG_MODE then log_message("Debug: Placed item from slot "..s) end; return true end
  161.  
  162. local function retrieve_specific_ender_chest_item(nbt, name_for_log)
  163.     log_message("Verifying item " .. name_for_log .. " (NBT: " .. tostring(nbt) .. ") is in inventory.")
  164.     os.sleep(0.1) -- Short delay, might help with inventory update timings
  165.     local s, d = find_item_in_inventory(function(it) return it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == nbt end, "Confirm " .. name_for_log)
  166.     if not s then
  167.         error_stop("CRIT: Required Ender Chest '" .. name_for_log .. "' with NBT '" .. tostring(nbt) .. "' not found in inventory when expected.")
  168.     end
  169.     log_message(name_for_log .. " (NBT " .. tostring(nbt) .. ") confirmed in slot " .. s .. ".")
  170.     return s, d
  171. end
  172.  
  173. local function decrement_dig_move_actions()dig_and_move_actions_before_check=dig_and_move_actions_before_check-1 end
  174.  
  175. local function perform_initial_setup(dump_ec_s,coal_s,cc_s,pick_s)
  176.     log_message("SP1 Setup: Performing initial item setup and Fuel EC NBT acquisition...")
  177.     log_message("Refueling with initial coal from slot " .. coal_s .. ".")
  178.     turtle.select(coal_s)
  179.     local r = turtle.refuel(1) -- Use one coal block from the selected stack
  180.     if r == false then error_stop("SP1: Failed initial refuel (refuel(1) returned false).")
  181.     elseif type(r) == "number" then
  182.         if r > 0 then log_message("SP1: Initial refuel successful, gained " .. r .. " fuel.")
  183.         else log_message("WARN: SP1: Initial refuel returned 0 (turtle full or item not valid fuel).") end
  184.     elseif r == true then log_message("SP1: Initial coal item consumed, fuel gained was 0 (turtle was already full). This is OK.")
  185.     else error_stop("SP1: Unexpected return value from initial turtle.refuel(1): " .. tostring(r)) end
  186.  
  187.     log_message("Equipping Chunk Controller from slot " .. cc_s .. " to right hand.")
  188.     turtle.select(cc_s)
  189.     if not turtle.equipRight() then error_stop("SP1: Failed to equip Chunk Controller.") end
  190.     log_message("Chunk Controller equipped.")
  191.  
  192.     log_message("Equipping Pickaxe from slot " .. pick_s .. " to left hand.")
  193.     turtle.select(pick_s)
  194.     if not turtle.equipLeft() then error_stop("SP1: Failed to equip Pickaxe.") end
  195.     log_message("Pickaxe equipped.")
  196.     turtle.select(1) -- Select a default non-tool slot
  197.  
  198.     -- Sanity check inventory after equips
  199.     local items_left_in_inv = 0
  200.     local found_dump_ec_after_equips = false
  201.     for i = 1, 16 do
  202.         local it = turtle.getItemDetail(i)
  203.         if it and it.name ~= AIR_ITEM_NAME then
  204.             items_left_in_inv = items_left_in_inv + 1
  205.             if it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == ITEM_DUMP_ENDER_CHEST_NBT then
  206.                 found_dump_ec_after_equips = true
  207.             end
  208.         end
  209.     end
  210.  
  211.     if not found_dump_ec_after_equips then error_stop("SP1: Item-Dump Ender Chest is missing from inventory after equipping tools.") end
  212.     if items_left_in_inv > 1 then -- Should only be the Item-Dump EC left
  213.         error_stop("SP1: Too many items (" .. items_left_in_inv .. ") in inventory after equipping tools. Expected only Item-Dump EC.", turtle.getItemDetail()) -- Log all for debug
  214.     end
  215.     log_message("SP1: Item-Dump EC is confirmed as the only item in inventory.")
  216.  
  217.     log_message("SP1: Expecting Fuel EC to be placed in front. Inspecting block in front...")
  218.     local insp_s, front_d = turtle.inspect()
  219.     if not insp_s then error_stop("SP1: No block detected in front (expected Fuel EC). Reason given: " .. tostring(front_d)) end
  220.     if DEBUG_MODE then log_message("Debug: Block in front details:", front_d) end
  221.     if front_d.name:lower() ~= ENDER_CHEST_ITEM_NAME:lower() then error_stop("SP1: Block in front is not an Ender Chest. Found: " .. front_d.name) end
  222.     log_message("SP1: Block in front confirmed as an Ender Chest by name.")
  223.     -- Cannot confirm NBT of placed Fuel EC yet.
  224.  
  225.     log_message("SP1: Attempting to suck items (fuel) from Fuel EC in front.")
  226.     if not turtle.suck(64) then log_message("WARN: SP1: Failed to suck from front Fuel EC (or it was empty).")
  227.     else log_message("SP1: Sucked items from front Fuel EC.") end
  228.  
  229.     local coal_after_suck_slot = nil
  230.     for i = 1, 16 do
  231.         local it = turtle.getItemDetail(i)
  232.         if it and it.name:lower() == COAL_BLOCK_ITEM_NAME:lower() then
  233.              -- Ensure it's not the ItemDumpEC if it somehow got coal_block name (highly unlikely)
  234.              if not (it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == ITEM_DUMP_ENDER_CHEST_NBT) then
  235.                 coal_after_suck_slot = i
  236.                 break
  237.              end
  238.         end
  239.     end
  240.  
  241.     if coal_after_suck_slot then
  242.         log_message("SP1: Coal block found in slot " .. coal_after_suck_slot .. " after sucking from Fuel EC. Refueling.")
  243.         turtle.select(coal_after_suck_slot)
  244.         local ref_suck_r = turtle.refuel() -- Refuel with all items in selected slot
  245.         if ref_suck_r == false then log_message("WARN: SP1: turtle.refuel() returned false after sucking from Fuel EC.")
  246.         elseif type(ref_suck_r) == "number" then
  247.             if ref_suck_r > 0 then log_message("SP1: Refueled " .. ref_suck_r .. " fuel from sucked items.")
  248.             else log_message("SP1: No fuel gained from sucked items (turtle full or item not fuel).") end
  249.         elseif ref_suck_r == true then log_message("SP1: Sucked item(s) consumed, 0 fuel gained (turtle was full). OK.")
  250.         else log_message("WARN: SP1: Unexpected return value from turtle.refuel() after suck: " .. tostring(ref_suck_r)) end
  251.     else
  252.         log_message("SP1: No coal block found in inventory after sucking from Fuel EC.")
  253.     end
  254.     turtle.select(1) -- Reset selected slot
  255.  
  256.     log_message("SP1: Digging the Fuel EC in front to retrieve it and its NBT.")
  257.     if not safe_dig() then error_stop("SP1: Failed to dig the Fuel EC from front.") end
  258.     -- Auto-suck should pick up the item if enabled, or it might be in slot from dig.
  259.     -- A direct turtle.suck() after dig might be needed if auto-suck is off or item lands awkwardly.
  260.     -- For now, assume it's picked up or we find it.
  261.     os.sleep(0.5) -- Give time for item to drop / be picked up
  262.  
  263.     log_message("SP1: Finding NBT of the dug Fuel EC item in inventory...")
  264.     local fuel_ec_item_slot, fuel_ec_item_detail = nil, nil
  265.     for i = 1, 16 do
  266.         local it = turtle.getItemDetail(i)
  267.         if it and it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() then
  268.             if DEBUG_MODE then log_message("  Debug SP1: Checking inv slot " .. i .. " for new Fuel EC:", it) end
  269.             if it.nbt ~= ITEM_DUMP_ENDER_CHEST_NBT then -- Must not be the ItemDumpEC
  270.                 if fuel_ec_item_slot then error_stop("SP1: Found multiple 'new' (non-ItemDump) Ender Chest items in inventory after digging Fuel EC.") end
  271.                 fuel_ec_item_slot = i
  272.                 fuel_ec_item_detail = it
  273.                 if DEBUG_MODE then log_message("    Debug SP1: Candidate Fuel EC item found in slot " .. i) end
  274.             else
  275.                 if DEBUG_MODE then log_message("    Debug SP1: Slot " .. i .. " is the ItemDump EC, skipping as Fuel EC candidate.") end
  276.             end
  277.         end
  278.     end
  279.  
  280.     if not fuel_ec_item_detail or not fuel_ec_item_detail.nbt then
  281.         error_stop("SP1: Could not find the Fuel EC item (with NBT) in inventory after digging it, or it has no NBT.", fuel_ec_item_detail)
  282.     end
  283.  
  284.     FUEL_ENDER_CHEST_NBT = fuel_ec_item_detail.nbt
  285.     log_message("SP1: Fuel EC NBT successfully captured from item: " .. FUEL_ENDER_CHEST_NBT)
  286.  
  287.     if FUEL_ENDER_CHEST_NBT == ITEM_DUMP_ENDER_CHEST_NBT then
  288.         error_stop("SP1: CRITICAL! Fuel EC NBT is identical to Item-Dump EC NBT. This should not happen.")
  289.     end
  290.     log_message("SP1 complete. Fuel and Item-Dump Ender Chest NBTs secured.")
  291. end
  292.  
  293. local function update_dig_move_action_count()
  294.     dig_and_move_actions_before_check = count_free_slots()
  295.     if DEBUG_MODE then log_message("Debug: Inventory space check: " .. dig_and_move_actions_before_check .. " actions possible before next deposit.") end
  296. end
  297.  
  298. local function fuel_check()
  299.     if DEBUG_MODE then log_message("Debug: Initiating fuel check...") end
  300.     local cur_f = turtle.getFuelLevel()
  301.     local max_f = turtle.getFuelLimit()
  302.  
  303.     if max_f == "unlimited" or max_f == 0 then -- max_f == 0 for creative turtles (effectively unlimited)
  304.         if DEBUG_MODE then log_message("Debug: Fuel is unlimited or not applicable.") end
  305.         return
  306.     end
  307.     if type(max_f) ~= "number" or type(cur_f) ~= "number" then
  308.         error_stop("Fuel check: Could not get valid numeric fuel levels (cur: "..tostring(cur_f)..", max: "..tostring(max_f)..").")
  309.     end
  310.  
  311.     local perc = (cur_f / max_f) * 100
  312.     if DEBUG_MODE then log_message("Debug: Fuel level: " .. cur_f .. "/" .. max_f .. " (" .. string.format("%.1f", perc) .. "%)") end
  313.  
  314.     if perc < FUEL_ALERT_PERCENTAGE then
  315.         log_message("Fuel low (" .. string.format("%.1f", perc) .. "%). Refueling procedure started.")
  316.         if not FUEL_ENDER_CHEST_NBT then error_stop("Cannot refuel: Fuel EC NBT is not known.") end
  317.  
  318.         local ec_s, _ = find_item_in_inventory(function(it) return it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == FUEL_ENDER_CHEST_NBT end, "Fuel EC for refueling placement")
  319.         if not ec_s then error_stop("Fuel EC (NBT " .. tostring(FUEL_ENDER_CHEST_NBT) .. ") not found in inventory for refueling procedure.") end
  320.  
  321.         turn_around()
  322.         if not safe_dig() then if DEBUG_MODE then log_message("Debug Refuel: Did not need to dig behind turtle for Fuel EC placement (already clear).") end end
  323.         safe_place(ec_s)
  324.         log_message("Placed Fuel EC behind turtle for refueling.")
  325.  
  326.         if not turtle.suck() then -- Try to suck one item (e.g., one coal block)
  327.             log_message("WARN: Failed to suck fuel item from Fuel EC. Retrieving Fuel EC.")
  328.             if not safe_dig() then error_stop("CRIT: Failed to dig Fuel EC after a failed suck attempt.") end
  329.             if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (following failed suck).") end
  330.             retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (after failed suck)")
  331.             turn_around()
  332.             error_stop("Refueling failed: Unable to suck fuel item from placed Fuel EC.")
  333.         end
  334.         log_message("Successfully sucked a fuel item from Fuel EC.")
  335.  
  336.         local coal_s = nil
  337.         for i = 1, 16 do
  338.             local it = turtle.getItemDetail(i)
  339.             if it and it.name:lower() == COAL_BLOCK_ITEM_NAME:lower() then
  340.                 if not (it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and (it.nbt == ITEM_DUMP_ENDER_CHEST_NBT or it.nbt == FUEL_ENDER_CHEST_NBT)) then
  341.                     coal_s = i
  342.                     break
  343.                 end
  344.             end
  345.         end
  346.  
  347.         if not coal_s then
  348.             log_message("No coal block found in inventory after sucking from Fuel EC. Retrieving Fuel EC.")
  349.             if not safe_dig() then error_stop("CRIT: Failed to dig Fuel EC (no coal found after suck).") end
  350.             if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (no coal found).") end
  351.             retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (no coal after suck)")
  352.             turn_around()
  353.             error_stop("Refueling failed: No coal block obtained from Fuel EC.")
  354.         end
  355.  
  356.         local o_s = turtle.getSelectedSlot()
  357.         turtle.select(coal_s)
  358.         local ref_res = turtle.refuel() -- Refuel with all from selected slot
  359.         turtle.select(o_s)
  360.  
  361.         if ref_res == false then
  362.             log_message("Refuel command returned false with obtained fuel item. Retrieving Fuel EC.")
  363.             if not safe_dig() then error_stop("CRIT: Failed to dig Fuel EC (refuel command failed).") end
  364.             if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (refuel command failed).") end
  365.             retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (refuel command failed)")
  366.             turn_around()
  367.             error_stop("Refueling failed: turtle.refuel() returned false with item from Fuel EC.")
  368.         elseif type(ref_res) == "number" then
  369.             if ref_res > 0 then log_message("Refueled " .. ref_res .. " points.")
  370.             else log_message("WARN: Refuel command returned 0 (turtle full or item not valid fuel).") end
  371.         elseif ref_res == true then
  372.             log_message("Fuel item(s) consumed, 0 fuel gained (turtle was already full). This is OK.")
  373.         else
  374.             error_stop("Unexpected return value from turtle.refuel() with Fuel EC item: " .. tostring(ref_res))
  375.         end
  376.  
  377.         log_message("Digging Fuel EC to retrieve it after refueling.")
  378.         if not safe_dig() then error_stop("Failed to dig Fuel EC after refueling.") end
  379.         if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (post-refuel).") end
  380.         retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (post-refuel)")
  381.         turn_around()
  382.         log_message("Refueling complete.")
  383.     else
  384.         if DEBUG_MODE then log_message("Debug: Fuel level is OK.") end
  385.     end
  386. end
  387.  
  388. local function item_deposit_check()
  389.     if DEBUG_MODE then log_message("Debug: Initiating item deposit check...") end
  390.     local free_slots = count_free_slots()
  391.     if DEBUG_MODE then log_message("Debug: Current free slots: " .. free_slots) end
  392.  
  393.     if free_slots < MIN_FREE_SLOTS_FOR_OPERATION then
  394.         log_message("Inventory space low (" .. free_slots .. " free). Depositing items.")
  395.         if not ITEM_DUMP_ENDER_CHEST_NBT or not FUEL_ENDER_CHEST_NBT then
  396.             error_stop("Cannot deposit items: Ender Chest NBTs (Item-Dump or Fuel) are missing.")
  397.         end
  398.  
  399.         local dump_s, _ = find_item_in_inventory(function(it) return it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == ITEM_DUMP_ENDER_CHEST_NBT end, "Item-Dump EC for deposit placement")
  400.         if not dump_s then error_stop("Item-Dump EC (NBT " .. tostring(ITEM_DUMP_ENDER_CHEST_NBT) .. ") not found in inventory for deposit.") end
  401.  
  402.         turn_around()
  403.         if not safe_dig() then if DEBUG_MODE then log_message("Debug Deposit: Did not need to dig behind turtle for Item-Dump EC placement (already clear).") end end
  404.         safe_place(dump_s)
  405.         log_message("Placed Item-Dump EC behind turtle for item deposit.")
  406.  
  407.         local o_s = turtle.getSelectedSlot()
  408.         for i = 1, 16 do
  409.             turtle.select(i)
  410.             local it_d = turtle.getItemDetail(i)
  411.             if it_d and it_d.name ~= AIR_ITEM_NAME then
  412.                 if not (it_d.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it_d.nbt == FUEL_ENDER_CHEST_NBT) then
  413.                     if DEBUG_MODE then log_message("Debug: Attempting to deposit slot " .. i .. ": " .. it_d.name .. " x" .. it_d.count) end
  414.                     local items_to_drop = it_d.count
  415.                     for _ = 1, items_to_drop do
  416.                         if turtle.getItemCount(i) == 0 then break end
  417.                         if not turtle.drop() then
  418.                             log_message("WARN: Failed to drop item from slot " .. i .. " (" .. it_d.name .. "). Item-Dump EC might be full. Stopping deposit for this slot.")
  419.                             break
  420.                         end
  421.                     end
  422.                     if turtle.getItemCount(i) == 0 then
  423.                         if DEBUG_MODE then log_message("Debug: Slot " .. i .. " (" .. it_d.name .. ") emptied successfully.") end
  424.                     else
  425.                         log_message("WARN: Slot " .. i .. " (" .. it_d.name .. ") not fully emptied. Remaining: " .. turtle.getItemCount(i))
  426.                     end
  427.                 else
  428.                     if DEBUG_MODE then log_message("Debug: Skipping Fuel EC in slot " .. i .. " during deposit.") end
  429.                 end
  430.             end
  431.         end
  432.         turtle.select(o_s)
  433.  
  434.         log_message("Digging Item-Dump EC to retrieve it after deposit.")
  435.         if not safe_dig() then error_stop("Failed to dig Item-Dump EC after deposit.") end
  436.         if not turtle.suck() then log_message("WARN: Failed to pick up Item-Dump EC item after digging (post-deposit).") end
  437.         retrieve_specific_ender_chest_item(ITEM_DUMP_ENDER_CHEST_NBT, "Item-Dump Ender Chest (post-deposit)")
  438.         turn_around()
  439.         log_message("Item deposit procedure complete. Current free slots: " .. count_free_slots())
  440.     else
  441.         if DEBUG_MODE then log_message("Debug: Sufficient inventory space available (" .. free_slots .. " free).") end
  442.     end
  443.     update_dig_move_action_count()
  444. end
  445.  
  446. local function system_check()
  447.     log_message("--- Sys Check ---")
  448.     fuel_check()
  449.     item_deposit_check()
  450.     log_message("--- Sys Check Done ---")
  451.     if dig_and_move_actions_before_check <= 0 then
  452.         log_message("WARN: System check completed, but no dig/move actions are available (inventory likely full and deposit failed to clear enough space).")
  453.     end
  454. end
  455.  
  456. local function calibrate_y_level()
  457.     log_message("Y-cal: Starting Y-level calibration by digging to bedrock...")
  458.     local distance_dug_down = 0
  459.     while true do
  460.         local b_s, b_d = turtle.inspectDown()
  461.         if b_s and b_d.name:lower() == BEDROCK_ITEM_NAME:lower() then
  462.             log_message("Y-cal: Bedrock detected below.")
  463.             break
  464.         end
  465.         if not safe_dig_down() then
  466.             log_message("Y-cal: Encountered unbreakable block (assumed bedrock) while digging down.")
  467.             break
  468.         end
  469.         if not safe_down() then error_stop("Y-cal: Failed to move down during calibration.") end
  470.         distance_dug_down = distance_dug_down + 1
  471.         if distance_dug_down % 20 == 0 and DEBUG_MODE then
  472.             log_message("Debug Y-cal: Descended " .. distance_dug_down .. " blocks so far.")
  473.         end
  474.         if distance_dug_down > WORLD_BOTTOM_Y_CALIBRATION_DEPTH + 200 then
  475.             error_stop("Y-cal: Descended significantly further than expected (" .. distance_dug_down .. " blocks). Stopping calibration.")
  476.         end
  477.     end
  478.     log_message("Y-cal: Reached bedrock (or unbreakable layer) after digging down " .. distance_dug_down .. " blocks.")
  479.  
  480.     log_message("Y-cal: Ascending " .. WORLD_BOTTOM_Y_CALIBRATION_DEPTH .. " blocks to establish relative Y=0.")
  481.     for i = 1, WORLD_BOTTOM_Y_CALIBRATION_DEPTH do
  482.         if not safe_dig_up() then error_stop("Y-cal: Failed to dig up at step " .. i .. " of " .. WORLD_BOTTOM_Y_CALIBRATION_DEPTH .. " while ascending.") end
  483.         if not safe_up() then error_stop("Y-cal: Failed to move up at step " .. i .. " of " .. WORLD_BOTTOM_Y_CALIBRATION_DEPTH .. " while ascending.") end
  484.         if i % 20 == 0 and DEBUG_MODE then
  485.             log_message("Debug Y-cal: Ascended " .. i .. " blocks so far.")
  486.         end
  487.     end
  488.     current_y_relative = 0
  489.     is_y_calibrated = true
  490.     log_message("Y-cal: Y-level calibration complete. Current relative Y is 0.")
  491. end
  492.  
  493. local function mine_shaft_down()
  494.     if DEBUG_MODE then log_message("Debug: Mine Down: Starting descent from Y=" .. current_y_relative) end
  495.     while true do
  496.         if dig_and_move_actions_before_check <= 0 then
  497.             system_check()
  498.             if dig_and_move_actions_before_check <= 0 then
  499.                 error_stop("No actions available after system check during mine_shaft_down.")
  500.             end
  501.         end
  502.  
  503.         local b_s, b_d = turtle.inspectDown()
  504.         if b_s and b_d.name:lower() == BEDROCK_ITEM_NAME:lower() then
  505.             if DEBUG_MODE then log_message("Debug: Mine Down: Bedrock detected below at Y=" .. (current_y_relative -1) .. ". Stopping descent.") end
  506.             break
  507.         end
  508.         if not safe_dig_down() then
  509.             if DEBUG_MODE then log_message("Debug: Mine Down: Encountered unbreakable block (assumed bedrock) by dig at Y=" .. (current_y_relative -1) .. ". Stopping descent.") end
  510.             break
  511.         end
  512.         decrement_dig_move_actions()
  513.         if not safe_down() then error_stop("Mine Down: Failed to move down. Current Y=" .. current_y_relative) end
  514.         current_y_relative = current_y_relative - 1
  515.        
  516.         if DEBUG_MODE and (current_y_relative % 10 == 0 or current_y_relative == -1) then log_message("Debug: Mine Down: Reached Y=" .. current_y_relative) end
  517.  
  518.         if current_y_relative < -(WORLD_BOTTOM_Y_CALIBRATION_DEPTH + 250) then
  519.             log_message("WARN: Mine Down: Reached very low Y-level (" .. current_y_relative .. "). Stopping descent as a precaution.")
  520.             break
  521.         end
  522.     end
  523.     if DEBUG_MODE then log_message("Debug: Mine Down: Finished descent. Current Y=" .. current_y_relative) end
  524. end
  525.  
  526. local function mine_shaft_up()
  527.     if DEBUG_MODE then log_message("Debug: Mine Up: Starting ascent to Y=0 from Y=" .. current_y_relative) end
  528.     while current_y_relative < 0 do
  529.         if dig_and_move_actions_before_check <= 0 then
  530.             system_check()
  531.             if dig_and_move_actions_before_check <= 0 then
  532.                 error_stop("No actions available after system check during mine_shaft_up.")
  533.             end
  534.         end
  535.         if not safe_dig_up() then error_stop("Mine Up: Failed to dig up. Current Y=" .. current_y_relative) end
  536.         decrement_dig_move_actions()
  537.         if not safe_up() then error_stop("Mine Up: Failed to move up. Current Y=" .. current_y_relative) end
  538.         current_y_relative = current_y_relative + 1
  539.  
  540.         if DEBUG_MODE and (current_y_relative % 10 == 0 or current_y_relative == -1) then log_message("Debug: Mine Up: Reached Y=" .. current_y_relative) end
  541.        
  542.         if current_y_relative > 50 then
  543.             log_message("WARN: Mine Up: Ascended significantly above Y=0 (Current Y=" .. current_y_relative .. "). Stopping ascent.")
  544.             break
  545.         end
  546.     end
  547.     if current_y_relative == 0 then
  548.         if DEBUG_MODE then log_message("Debug: Mine Up: Successfully reached target Y=0.") end
  549.     else
  550.         log_message("WARN: Mine Up: Finished ascent, but not at Y=0. Final Y=" .. current_y_relative)
  551.     end
  552. end
  553.  
  554. --------------------------------------------------------------------------------
  555. -- Main Program Logic: Startup & Loop
  556. --------------------------------------------------------------------------------
  557. log_message("--- Initializing Miner: Determining Start Scenario ---")
  558. local inv_item_dump_ec_slot = nil
  559. local inv_coal_block_slot = nil
  560. local inv_chunk_loader_slot = nil
  561. local inv_pickaxe_candidate_slots = {}
  562. local inv_ender_chest_details = {}
  563.  
  564. log_message("Scanning inventory slots 1-16 for initial items...")
  565. for i = 1, 16 do
  566.     local item = turtle.getItemDetail(i)
  567.     if item and item.name ~= AIR_ITEM_NAME then
  568.         if DEBUG_MODE then log_message("  Debug SP Scan: Slot " .. i .. ":", item) end
  569.         if item.name:lower() == ENDER_CHEST_ITEM_NAME:lower() then
  570.             table.insert(inv_ender_chest_details, {slot = i, detail = item})
  571.             if item.nbt == ITEM_DUMP_ENDER_CHEST_NBT then
  572.                 if inv_item_dump_ec_slot then error_stop("SP Scan: Duplicate Item-Dump ECs found in inventory.") end
  573.                 inv_item_dump_ec_slot = i
  574.                 if DEBUG_MODE then log_message("    Debug SP Scan: Found Item-Dump EC in slot " .. i) end
  575.             end
  576.         elseif item.name:lower() == COAL_BLOCK_ITEM_NAME:lower() then
  577.             if inv_coal_block_slot then
  578.                 if DEBUG_MODE then log_message("  WARN SP Scan: Multiple coal block stacks found. Using first one (slot " .. inv_coal_block_slot .. ").") end
  579.             else inv_coal_block_slot = i end
  580.         elseif item.name:lower() == CHUNK_CONTROLLER_ITEM_NAME:lower() then
  581.             if inv_chunk_loader_slot then
  582.                 if DEBUG_MODE then log_message("  WARN SP Scan: Multiple chunk controllers found. Using first one (slot " .. inv_chunk_loader_slot .. ").") end
  583.             else inv_chunk_loader_slot = i end
  584.         end
  585.        
  586.         if (item.maxDamage and item.maxDamage > 0) or string.find(item.name:lower(), "pickaxe") then
  587.              if DEBUG_MODE then log_message("    Debug SP Scan: Slot "..i.." ("..item.name..") considered potential tool. Adding to pickaxe candidates.") end
  588.              table.insert(inv_pickaxe_candidate_slots, i)
  589.         end
  590.     end
  591. end
  592. if DEBUG_MODE then log_message("  Debug SP Scan: Raw inv_pickaxe_candidate_slots: {" .. table.concat(inv_pickaxe_candidate_slots, ", ") .. "}") end
  593.  
  594. local actual_pickaxe_slot_for_sp1 = nil
  595. if #inv_pickaxe_candidate_slots > 0 then
  596.     local filtered_pickaxe_slots = {}
  597.     if DEBUG_MODE then log_message("  Debug SP Scan: Filtering pickaxe candidates for SP1 setup:") end
  598.     for _, p_s in ipairs(inv_pickaxe_candidate_slots) do
  599.         local it_d_filter = turtle.getItemDetail(p_s) -- Re-fetch, though should be same
  600.         local candidate_name = it_d_filter and it_d_filter.name or "UnknownItem"
  601.         if DEBUG_MODE then log_message("    Debug SP Scan: Filtering candidate pickaxe slot " .. p_s .. " (" .. candidate_name .. "):") end
  602.        
  603.         local is_cc_slot = (inv_chunk_loader_slot and p_s == inv_chunk_loader_slot)
  604.         local is_any_ec_slot = false
  605.         for _, ec_entry in ipairs(inv_ender_chest_details) do
  606.             if ec_entry.slot == p_s then is_any_ec_slot = true; break end
  607.         end
  608.  
  609.         if DEBUG_MODE then log_message("      IsCC? " .. tostring(is_cc_slot) .. " IsAnyEC? " .. tostring(is_any_ec_slot)) end
  610.         if not (is_any_ec_slot or is_cc_slot) then
  611.             table.insert(filtered_pickaxe_slots, p_s)
  612.             if DEBUG_MODE then log_message("      Added slot " .. p_s .. " ("..candidate_name..") to filtered pickaxe list.") end
  613.         else
  614.             if DEBUG_MODE then log_message("      Skipped slot " .. p_s .. " ("..candidate_name..") (it's an EC or CC).") end
  615.         end
  616.     end
  617.     if DEBUG_MODE then log_message("  Debug SP Scan: Final filtered pickaxe candidates: {" .. table.concat(filtered_pickaxe_slots, ", ") .. "}") end
  618.    
  619.     if #filtered_pickaxe_slots == 1 then
  620.         actual_pickaxe_slot_for_sp1 = filtered_pickaxe_slots[1]
  621.     elseif #filtered_pickaxe_slots > 1 then
  622.         log_message("WARN SP Scan: Multiple suitable pickaxe candidates found for SP1: {" .. table.concat(filtered_pickaxe_slots, ", ") .. "}. Using the first one: " .. filtered_pickaxe_slots[1])
  623.         actual_pickaxe_slot_for_sp1 = filtered_pickaxe_slots[1]
  624.     else
  625.         if DEBUG_MODE then log_message("Debug SP Scan: No suitable pickaxe candidate found after filtering for SP1.") end
  626.     end
  627. else
  628.     if DEBUG_MODE then log_message("Debug SP Scan: No raw pickaxe candidates found in inventory.") end
  629. end
  630.  
  631. log_message("Initial inventory scan summary for Start Scenario determination:")
  632. log_message("  Item-Dump EC (NBT " .. ITEM_DUMP_ENDER_CHEST_NBT .. ") in inv slot: " .. tostring(inv_item_dump_ec_slot))
  633. log_message("  Coal Block in inv slot: " .. tostring(inv_coal_block_slot))
  634. log_message("  Chunk Controller in inv slot: " .. tostring(inv_chunk_loader_slot))
  635. log_message("  Selected Pickaxe candidate for SP1 in inv slot: " .. tostring(actual_pickaxe_slot_for_sp1))
  636. log_message("  Total Ender Chests count in inventory: " .. #inv_ender_chest_details)
  637. if DEBUG_MODE then
  638.     for idx, ec_e in ipairs(inv_ender_chest_details) do
  639.         log_message("    Debug EC #" .. idx .. " slot " .. ec_e.slot .. ": " .. ec_e.detail.name .. " (NBT: " .. tostring(ec_e.detail.nbt) .. ")")
  640.     end
  641. end
  642.  
  643. log_message("Checking currently equipped items (left/right hand)...")
  644. local eq_left_item_detail = get_item_from_hand_temporarily("left")
  645. local eq_right_item_detail = get_item_from_hand_temporarily("right")
  646.  
  647. local is_pickaxe_effectively_equipped = (eq_left_item_detail and eq_left_item_detail.name ~= AIR_ITEM_NAME and
  648.                                       ((eq_left_item_detail.maxDamage and eq_left_item_detail.maxDamage > 0) or string.find(eq_left_item_detail.name:lower(), "pickaxe")))
  649. local is_chunk_controller_equipped = (eq_right_item_detail and eq_right_item_detail.name:lower() == CHUNK_CONTROLLER_ITEM_NAME:lower())
  650.  
  651. log_message("Equipped items check summary:")
  652. log_message("  Pickaxe effectively in left hand: " .. tostring(is_pickaxe_effectively_equipped) .. (is_pickaxe_effectively_equipped and (" (" .. eq_left_item_detail.name .. ")") or ""))
  653. log_message("  Chunk Controller effectively in right hand: " .. tostring(is_chunk_controller_equipped) .. (is_chunk_controller_equipped and (" (" .. eq_right_item_detail.name .. ")") or ""))
  654.  
  655. local sp1_conditions_met = inv_item_dump_ec_slot and inv_coal_block_slot and inv_chunk_loader_slot and actual_pickaxe_slot_for_sp1 and
  656.                            #inv_ender_chest_details == 1 and (inv_ender_chest_details[1] and inv_ender_chest_details[1].slot == inv_item_dump_ec_slot) and
  657.                            not is_pickaxe_effectively_equipped and not is_chunk_controller_equipped
  658.  
  659. if sp1_conditions_met then
  660.     log_message("Start Scenario: Conditions for Start Point 1 (initial setup) met. Proceeding with SP1.")
  661.     perform_initial_setup(inv_item_dump_ec_slot, inv_coal_block_slot, inv_chunk_loader_slot, actual_pickaxe_slot_for_sp1)
  662. else
  663.     log_message("Start Scenario: Conditions for Start Point 1 NOT met. Checking for Start Point 2 (resumed operation)...")
  664.     local fuel_ec_detail_for_sp2 = nil
  665.     local item_dump_ec_present_for_sp2 = false
  666.     if #inv_ender_chest_details == 2 then
  667.         for _, ec_entry in ipairs(inv_ender_chest_details) do
  668.             if ec_entry.detail.nbt == ITEM_DUMP_ENDER_CHEST_NBT then
  669.                 item_dump_ec_present_for_sp2 = true
  670.             elseif ec_entry.detail.nbt and ec_entry.detail.nbt ~= ITEM_DUMP_ENDER_CHEST_NBT then
  671.                 if fuel_ec_detail_for_sp2 then error_stop("SP2 Check: Multiple candidate Fuel Ender Chests found in inventory.") end
  672.                 fuel_ec_detail_for_sp2 = ec_entry.detail
  673.             end
  674.         end
  675.     end
  676.  
  677.     local sp2_conditions_met = is_pickaxe_effectively_equipped and is_chunk_controller_equipped and
  678.                                item_dump_ec_present_for_sp2 and fuel_ec_detail_for_sp2
  679.    
  680.     if sp2_conditions_met then
  681.         log_message("Start Scenario: Conditions for Start Point 2 (resumed operation) met.")
  682.         FUEL_ENDER_CHEST_NBT = fuel_ec_detail_for_sp2.nbt
  683.         log_message("Fuel EC NBT identified from inventory (SP2): " .. FUEL_ENDER_CHEST_NBT)
  684.         if not find_item_in_inventory(function(it) return it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == ITEM_DUMP_ENDER_CHEST_NBT end, "SP2 ItemDump EC Sanity Check") then
  685.             error_stop("SP2 Sanity Check: Item-Dump EC (NBT " .. ITEM_DUMP_ENDER_CHEST_NBT .. ") became unfindable in inventory.")
  686.         end
  687.         log_message("SP2 confirmed. Miner is ready to resume.")
  688.     else
  689.         log_message("Start Scenario: Conditions for Start Point 2 NOT met.")
  690.         log_message("--- Start Scenario Determination Failure ---")
  691.         log_message("  Debug Info - SP1 Met: " .. tostring(sp1_conditions_met))
  692.         log_message("  Debug Info - SP2 Met: " .. tostring(sp2_conditions_met))
  693.         log_message("  Inv Detail - Item-Dump EC Slot: " .. tostring(inv_item_dump_ec_slot))
  694.         log_message("  Inv Detail - Coal Block Slot: " .. tostring(inv_coal_block_slot))
  695.         log_message("  Inv Detail - Chunk Controller Slot: " .. tostring(inv_chunk_loader_slot))
  696.         log_message("  Inv Detail - Pickaxe Slot for SP1: " .. tostring(actual_pickaxe_slot_for_sp1))
  697.         log_message("  Inv Detail - Number of ECs in inv: " .. #inv_ender_chest_details)
  698.         log_message("  Equip Detail - Pickaxe Equipped: " .. tostring(is_pickaxe_effectively_equipped))
  699.         log_message("  Equip Detail - CC Equipped: " .. tostring(is_chunk_controller_equipped))
  700.         log_message("  SP2 Check - ItemDumpEC Present: " .. tostring(item_dump_ec_present_for_sp2))
  701.         log_message("  SP2 Check - FuelEC Detail: " .. ((fuel_ec_detail_for_sp2 and fuel_ec_detail_for_sp2.name .. " NBT:" .. tostring(fuel_ec_detail_for_sp2.nbt)) or "nil"))
  702.         error_stop("Unable to determine a valid start scenario (SP1 or SP2). Please check turtle inventory, equipped items, and external Fuel EC for SP1 if applicable. Review console log for details.")
  703.     end
  704. end
  705.  
  706. system_check()
  707. if not is_y_calibrated then
  708.     calibrate_y_level()
  709.     system_check()
  710. end
  711.  
  712. log_message("--- Starting Main Mining Loop ---")
  713. local current_cycle_number = 0
  714. while true do
  715.     current_cycle_number = current_cycle_number + 1
  716.     log_message("\n--- Cycle #" .. current_cycle_number .. " ---")
  717.     if DEBUG_MODE then log_message("Debug: Current Y=" .. current_y_relative .. ". Actions before next check: " .. dig_and_move_actions_before_check) end
  718.    
  719.     if dig_and_move_actions_before_check <= 0 then
  720.         system_check()
  721.         if dig_and_move_actions_before_check <= 0 then
  722.             error_stop("No actions available after system check at the start of main loop cycle " .. current_cycle_number .. ".")
  723.         end
  724.     end
  725.    
  726.     if DEBUG_MODE then log_message("Debug: Mining layer: Digging forward then moving forward (at Y=" .. current_y_relative .. ").") end
  727.     if not safe_dig() then
  728.         log_message("WARN: safe_dig() returned false (encountered undiggable block) at main mining Y-level (Y="..current_y_relative.."). Attempting to move forward regardless...")
  729.     end
  730.     if not safe_forward() then error_stop("Failed to move forward at main mining Y-level (Y=" .. current_y_relative .. ") after dig attempt.") end
  731.     decrement_dig_move_actions()
  732.  
  733.     mine_shaft_down()
  734.    
  735.     if dig_and_move_actions_before_check <= 0 then
  736.         system_check()
  737.         if dig_and_move_actions_before_check <= 0 then
  738.             error_stop("No actions available after system check before moving forward at bedrock layer (Cycle " .. current_cycle_number .. ").")
  739.         end
  740.     end
  741.    
  742.     if DEBUG_MODE then log_message("Debug: Bedrock layer: Digging forward then moving forward (at Y=" .. current_y_relative .. ").") end
  743.     if not safe_dig() then
  744.         log_message("WARN: safe_dig() returned false (encountered undiggable block) at bedrock Y-level (Y="..current_y_relative.."). Attempting to move forward regardless...")
  745.     end
  746.     if not safe_forward() then error_stop("Failed to move forward at bedrock layer (Y=" .. current_y_relative .. ") after dig attempt.") end
  747.     decrement_dig_move_actions()
  748.  
  749.     mine_shaft_up()
  750.     log_message("Cycle #" .. current_cycle_number .. " completed. Returned to Y=0 (relative).")
  751. end
Add Comment
Please, Sign In to add comment