Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Advanced Mining Turtle for CC: Tweaked
- -- Configuration
- local DEBUG_MODE = false
- -- No LOG_FILE, LOG_CYCLE_LIMIT, or old global main_loop_cycle_count_for_log needed
- -- Delete old log file if it exists (one-time operation)
- local OLD_LOG_FILE_NAME = "miner_log.txt"
- if fs.exists(OLD_LOG_FILE_NAME) then
- fs.delete(OLD_LOG_FILE_NAME)
- print(os.date("%Y-%m-%d %H:%M:%S") .. " - Deleted old log file: " .. OLD_LOG_FILE_NAME)
- end
- local FUEL_ENDER_CHEST_NBT = nil
- local ITEM_DUMP_ENDER_CHEST_NBT = "12dc70dc0c75dbe36569479175a42608"
- local FUEL_ALERT_PERCENTAGE = 40
- local MIN_FREE_SLOTS_FOR_OPERATION = 2
- local WORLD_BOTTOM_Y_CALIBRATION_DEPTH = 317
- local ENDER_CHEST_ITEM_NAME = "enderstorage:ender_chest"
- local COAL_BLOCK_ITEM_NAME = "minecraft:coal_block"
- local CHUNK_CONTROLLER_ITEM_NAME = "advancedperipherals:chunk_controller"
- local BEDROCK_ITEM_NAME = "minecraft:bedrock"
- local AIR_ITEM_NAME = "minecraft:air"
- local is_y_calibrated = false
- local dig_and_move_actions_before_check = 0
- local current_y_relative = 0
- --------------------------------------------------------------------------------
- -- Logging, Error Handling, and Table Serialization
- --------------------------------------------------------------------------------
- -- serialize_table remains unchanged as it's a general utility
- 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
- local function log_message(msg, data_tbl)
- local is_important_msg = msg:find("FATAL ERROR") or
- msg:find("--- Initializing") or
- msg:find("--- Sys Check") or -- Covers "--- Sys Check ---" and "--- Sys Check Done ---"
- msg:find("Start Scenario") or -- Covers startup scenario messages
- msg:find("Starting Main Mining Loop") or
- msg:find("Cycle #") or
- msg:find("Y-cal:") or -- Covers Y-calibration messages
- msg:find("Refuel") or -- Covers "Refueling...", "Refueled", "Refueling complete."
- msg:find("Deposit") or -- Covers "Depositing...", "Deposit done."
- msg:find("WARN:") or msg:find("CRIT:") or -- Covers warnings and critical non-fatal messages
- msg:find("SP1 complete") or msg:find("SP2 confirmed") or -- Important startup milestones
- msg:find("Equipped items check summary") or msg:find("Initial inventory scan summary")
- if DEBUG_MODE or is_important_msg then
- print(os.date("%Y-%m-%d %H:%M:%S") .. " - " .. msg)
- if DEBUG_MODE and data_tbl then
- print("Data (Debug):\n" .. serialize_table(data_tbl))
- end
- end
- end
- local function error_stop(msg, data_tbl)
- local full_msg = "FATAL ERROR: " .. msg
- -- log_message will print the error message (as it contains "FATAL ERROR")
- log_message(full_msg, data_tbl)
- print(os.date("%Y-%m-%d %H:%M:%S") .. " - Stopping due to fatal error.") -- Explicit stop message
- error(full_msg, 0) -- Halt script execution
- end
- --------------------------------------------------------------------------------
- -- Helper Functions (Logging calls updated)
- --------------------------------------------------------------------------------
- local function find_item_in_inventory(f, dbg_ctx)
- if DEBUG_MODE and dbg_ctx then log_message("Debug: find_item_in_inventory for: " .. dbg_ctx) end
- for i = 1, 16 do
- local d = turtle.getItemDetail(i)
- if d and d.name ~= AIR_ITEM_NAME then
- if DEBUG_MODE and dbg_ctx then log_message(" Debug: Chk slot " .. i .. " for '" .. dbg_ctx .. "':", d) end
- if f(d, i) then
- if DEBUG_MODE and dbg_ctx then log_message(" Debug: Found match slot " .. i .. " for '" .. dbg_ctx .. "'") end
- return i, d
- end
- end
- end
- if DEBUG_MODE and dbg_ctx then log_message(" Debug: No match for '" .. dbg_ctx .. "'") end
- return nil, nil
- end
- 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
- local function turn_around()turtle.turnLeft();turtle.turnLeft()end
- local function get_item_from_hand_temporarily(h_s)
- log_message("Checking " .. h_s .. " hand...") -- This is an important step in startup.
- local e_s = nil
- for i = 16, 1, -1 do -- Prefer higher slots for temp storage
- if turtle.getItemCount(i) == 0 then e_s = i; break end
- end
- if not e_s then error_stop("No empty inventory slot available for hand check operation.") return nil end
- if DEBUG_MODE then log_message("Debug: Using temp slot " .. e_s .. " for " .. h_s .. " hand check.") end
- local o_s = turtle.getSelectedSlot()
- turtle.select(e_s)
- local u_ok -- "unequip_ok" or "usage_ok"
- if h_s == "left" then u_ok = turtle.equipLeft()
- elseif h_s == "right" then u_ok = turtle.equipRight()
- else
- turtle.select(o_s)
- error_stop("Invalid hand specified for get_item_from_hand_temporarily: " .. h_s)
- return nil -- Should not be reached due to error_stop
- end
- local i_d = nil -- item_detail
- if u_ok then
- i_d = turtle.getItemDetail(e_s)
- if i_d and i_d.name ~= AIR_ITEM_NAME then
- log_message(h_s .. " hand contained: " .. i_d.name, (DEBUG_MODE and i_d or nil) )
- turtle.select(e_s) -- Ensure e_s (now holding the item) is selected
- local r_ok -- "re_equip_ok"
- if h_s == "left" then r_ok = turtle.equipLeft() -- Equip item from e_s back to hand
- else r_ok = turtle.equipRight() end
- if not r_ok then error_stop("CRIT: Failed to re-equip " .. i_d.name .. " to " .. h_s .. " hand from slot " .. e_s) end
- if DEBUG_MODE then log_message("Debug: Item " .. i_d.name .. " re-equipped to " .. h_s .. " hand.") end
- else
- log_message(h_s .. " hand is empty or holds air.")
- i_d = nil -- Ensure i_d is nil if hand was effectively empty
- end
- else
- -- This case implies hand was empty, so equipLeft/Right (to unequip) moved nothing.
- log_message(h_s .. " hand was already empty (or unequip attempt reported no action, u_ok="..tostring(u_ok)..").")
- i_d = nil
- end
- turtle.select(o_s) -- Restore original selected slot
- return i_d
- end
- local function safe_dig_generic(d_f,dir_name,insp_f)
- if not d_f() then -- Dig attempt failed
- local insp_s, blk_d = insp_f() -- Inspect to see what's there
- if insp_s then -- Successfully inspected a block
- if blk_d.name:lower() == BEDROCK_ITEM_NAME:lower() then
- log_message("Cannot dig " .. dir_name .. ", encountered " .. blk_d.name .. ".")
- return false -- Indicate undiggable block (bedrock)
- end
- -- Some other block is there that couldn't be dug
- error_stop("Failed to dig " .. dir_name .. " (block present: " .. blk_d.name .. "). Possible tool issue or other unbreakable block?")
- else
- -- Inspect failed. Could be air, or some non-block entity.
- -- Assume it's effectively clear or became clear.
- return true
- end
- end
- if DEBUG_MODE then log_message("Debug: Successfully dug " .. dir_name .. ".") end
- return true -- Dig was successful
- end
- local function safe_dig()return safe_dig_generic(turtle.dig,"fwd",turtle.inspect)end
- local function safe_dig_up()return safe_dig_generic(turtle.digUp,"up",turtle.inspectUp)end
- local function safe_dig_down()return safe_dig_generic(turtle.digDown,"down",turtle.inspectDown)end
- 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
- 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
- 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
- local function retrieve_specific_ender_chest_item(nbt, name_for_log)
- log_message("Verifying item " .. name_for_log .. " (NBT: " .. tostring(nbt) .. ") is in inventory.")
- os.sleep(0.1) -- Short delay, might help with inventory update timings
- 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)
- if not s then
- error_stop("CRIT: Required Ender Chest '" .. name_for_log .. "' with NBT '" .. tostring(nbt) .. "' not found in inventory when expected.")
- end
- log_message(name_for_log .. " (NBT " .. tostring(nbt) .. ") confirmed in slot " .. s .. ".")
- return s, d
- end
- local function decrement_dig_move_actions()dig_and_move_actions_before_check=dig_and_move_actions_before_check-1 end
- local function perform_initial_setup(dump_ec_s,coal_s,cc_s,pick_s)
- log_message("SP1 Setup: Performing initial item setup and Fuel EC NBT acquisition...")
- log_message("Refueling with initial coal from slot " .. coal_s .. ".")
- turtle.select(coal_s)
- local r = turtle.refuel(1) -- Use one coal block from the selected stack
- if r == false then error_stop("SP1: Failed initial refuel (refuel(1) returned false).")
- elseif type(r) == "number" then
- if r > 0 then log_message("SP1: Initial refuel successful, gained " .. r .. " fuel.")
- else log_message("WARN: SP1: Initial refuel returned 0 (turtle full or item not valid fuel).") end
- elseif r == true then log_message("SP1: Initial coal item consumed, fuel gained was 0 (turtle was already full). This is OK.")
- else error_stop("SP1: Unexpected return value from initial turtle.refuel(1): " .. tostring(r)) end
- log_message("Equipping Chunk Controller from slot " .. cc_s .. " to right hand.")
- turtle.select(cc_s)
- if not turtle.equipRight() then error_stop("SP1: Failed to equip Chunk Controller.") end
- log_message("Chunk Controller equipped.")
- log_message("Equipping Pickaxe from slot " .. pick_s .. " to left hand.")
- turtle.select(pick_s)
- if not turtle.equipLeft() then error_stop("SP1: Failed to equip Pickaxe.") end
- log_message("Pickaxe equipped.")
- turtle.select(1) -- Select a default non-tool slot
- -- Sanity check inventory after equips
- local items_left_in_inv = 0
- local found_dump_ec_after_equips = false
- for i = 1, 16 do
- local it = turtle.getItemDetail(i)
- if it and it.name ~= AIR_ITEM_NAME then
- items_left_in_inv = items_left_in_inv + 1
- if it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == ITEM_DUMP_ENDER_CHEST_NBT then
- found_dump_ec_after_equips = true
- end
- end
- end
- if not found_dump_ec_after_equips then error_stop("SP1: Item-Dump Ender Chest is missing from inventory after equipping tools.") end
- if items_left_in_inv > 1 then -- Should only be the Item-Dump EC left
- 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
- end
- log_message("SP1: Item-Dump EC is confirmed as the only item in inventory.")
- log_message("SP1: Expecting Fuel EC to be placed in front. Inspecting block in front...")
- local insp_s, front_d = turtle.inspect()
- if not insp_s then error_stop("SP1: No block detected in front (expected Fuel EC). Reason given: " .. tostring(front_d)) end
- if DEBUG_MODE then log_message("Debug: Block in front details:", front_d) end
- 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
- log_message("SP1: Block in front confirmed as an Ender Chest by name.")
- -- Cannot confirm NBT of placed Fuel EC yet.
- log_message("SP1: Attempting to suck items (fuel) from Fuel EC in front.")
- if not turtle.suck(64) then log_message("WARN: SP1: Failed to suck from front Fuel EC (or it was empty).")
- else log_message("SP1: Sucked items from front Fuel EC.") end
- local coal_after_suck_slot = nil
- for i = 1, 16 do
- local it = turtle.getItemDetail(i)
- if it and it.name:lower() == COAL_BLOCK_ITEM_NAME:lower() then
- -- Ensure it's not the ItemDumpEC if it somehow got coal_block name (highly unlikely)
- if not (it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it.nbt == ITEM_DUMP_ENDER_CHEST_NBT) then
- coal_after_suck_slot = i
- break
- end
- end
- end
- if coal_after_suck_slot then
- log_message("SP1: Coal block found in slot " .. coal_after_suck_slot .. " after sucking from Fuel EC. Refueling.")
- turtle.select(coal_after_suck_slot)
- local ref_suck_r = turtle.refuel() -- Refuel with all items in selected slot
- if ref_suck_r == false then log_message("WARN: SP1: turtle.refuel() returned false after sucking from Fuel EC.")
- elseif type(ref_suck_r) == "number" then
- if ref_suck_r > 0 then log_message("SP1: Refueled " .. ref_suck_r .. " fuel from sucked items.")
- else log_message("SP1: No fuel gained from sucked items (turtle full or item not fuel).") end
- elseif ref_suck_r == true then log_message("SP1: Sucked item(s) consumed, 0 fuel gained (turtle was full). OK.")
- else log_message("WARN: SP1: Unexpected return value from turtle.refuel() after suck: " .. tostring(ref_suck_r)) end
- else
- log_message("SP1: No coal block found in inventory after sucking from Fuel EC.")
- end
- turtle.select(1) -- Reset selected slot
- log_message("SP1: Digging the Fuel EC in front to retrieve it and its NBT.")
- if not safe_dig() then error_stop("SP1: Failed to dig the Fuel EC from front.") end
- -- Auto-suck should pick up the item if enabled, or it might be in slot from dig.
- -- A direct turtle.suck() after dig might be needed if auto-suck is off or item lands awkwardly.
- -- For now, assume it's picked up or we find it.
- os.sleep(0.5) -- Give time for item to drop / be picked up
- log_message("SP1: Finding NBT of the dug Fuel EC item in inventory...")
- local fuel_ec_item_slot, fuel_ec_item_detail = nil, nil
- for i = 1, 16 do
- local it = turtle.getItemDetail(i)
- if it and it.name:lower() == ENDER_CHEST_ITEM_NAME:lower() then
- if DEBUG_MODE then log_message(" Debug SP1: Checking inv slot " .. i .. " for new Fuel EC:", it) end
- if it.nbt ~= ITEM_DUMP_ENDER_CHEST_NBT then -- Must not be the ItemDumpEC
- if fuel_ec_item_slot then error_stop("SP1: Found multiple 'new' (non-ItemDump) Ender Chest items in inventory after digging Fuel EC.") end
- fuel_ec_item_slot = i
- fuel_ec_item_detail = it
- if DEBUG_MODE then log_message(" Debug SP1: Candidate Fuel EC item found in slot " .. i) end
- else
- if DEBUG_MODE then log_message(" Debug SP1: Slot " .. i .. " is the ItemDump EC, skipping as Fuel EC candidate.") end
- end
- end
- end
- if not fuel_ec_item_detail or not fuel_ec_item_detail.nbt then
- 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)
- end
- FUEL_ENDER_CHEST_NBT = fuel_ec_item_detail.nbt
- log_message("SP1: Fuel EC NBT successfully captured from item: " .. FUEL_ENDER_CHEST_NBT)
- if FUEL_ENDER_CHEST_NBT == ITEM_DUMP_ENDER_CHEST_NBT then
- error_stop("SP1: CRITICAL! Fuel EC NBT is identical to Item-Dump EC NBT. This should not happen.")
- end
- log_message("SP1 complete. Fuel and Item-Dump Ender Chest NBTs secured.")
- end
- local function update_dig_move_action_count()
- dig_and_move_actions_before_check = count_free_slots()
- if DEBUG_MODE then log_message("Debug: Inventory space check: " .. dig_and_move_actions_before_check .. " actions possible before next deposit.") end
- end
- local function fuel_check()
- if DEBUG_MODE then log_message("Debug: Initiating fuel check...") end
- local cur_f = turtle.getFuelLevel()
- local max_f = turtle.getFuelLimit()
- if max_f == "unlimited" or max_f == 0 then -- max_f == 0 for creative turtles (effectively unlimited)
- if DEBUG_MODE then log_message("Debug: Fuel is unlimited or not applicable.") end
- return
- end
- if type(max_f) ~= "number" or type(cur_f) ~= "number" then
- error_stop("Fuel check: Could not get valid numeric fuel levels (cur: "..tostring(cur_f)..", max: "..tostring(max_f)..").")
- end
- local perc = (cur_f / max_f) * 100
- if DEBUG_MODE then log_message("Debug: Fuel level: " .. cur_f .. "/" .. max_f .. " (" .. string.format("%.1f", perc) .. "%)") end
- if perc < FUEL_ALERT_PERCENTAGE then
- log_message("Fuel low (" .. string.format("%.1f", perc) .. "%). Refueling procedure started.")
- if not FUEL_ENDER_CHEST_NBT then error_stop("Cannot refuel: Fuel EC NBT is not known.") end
- 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")
- if not ec_s then error_stop("Fuel EC (NBT " .. tostring(FUEL_ENDER_CHEST_NBT) .. ") not found in inventory for refueling procedure.") end
- turn_around()
- 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
- safe_place(ec_s)
- log_message("Placed Fuel EC behind turtle for refueling.")
- if not turtle.suck() then -- Try to suck one item (e.g., one coal block)
- log_message("WARN: Failed to suck fuel item from Fuel EC. Retrieving Fuel EC.")
- if not safe_dig() then error_stop("CRIT: Failed to dig Fuel EC after a failed suck attempt.") end
- if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (following failed suck).") end
- retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (after failed suck)")
- turn_around()
- error_stop("Refueling failed: Unable to suck fuel item from placed Fuel EC.")
- end
- log_message("Successfully sucked a fuel item from Fuel EC.")
- local coal_s = nil
- for i = 1, 16 do
- local it = turtle.getItemDetail(i)
- if it and it.name:lower() == COAL_BLOCK_ITEM_NAME:lower() then
- 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
- coal_s = i
- break
- end
- end
- end
- if not coal_s then
- log_message("No coal block found in inventory after sucking from Fuel EC. Retrieving Fuel EC.")
- if not safe_dig() then error_stop("CRIT: Failed to dig Fuel EC (no coal found after suck).") end
- if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (no coal found).") end
- retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (no coal after suck)")
- turn_around()
- error_stop("Refueling failed: No coal block obtained from Fuel EC.")
- end
- local o_s = turtle.getSelectedSlot()
- turtle.select(coal_s)
- local ref_res = turtle.refuel() -- Refuel with all from selected slot
- turtle.select(o_s)
- if ref_res == false then
- log_message("Refuel command returned false with obtained fuel item. Retrieving Fuel EC.")
- if not safe_dig() then error_stop("CRIT: Failed to dig Fuel EC (refuel command failed).") end
- if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (refuel command failed).") end
- retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (refuel command failed)")
- turn_around()
- error_stop("Refueling failed: turtle.refuel() returned false with item from Fuel EC.")
- elseif type(ref_res) == "number" then
- if ref_res > 0 then log_message("Refueled " .. ref_res .. " points.")
- else log_message("WARN: Refuel command returned 0 (turtle full or item not valid fuel).") end
- elseif ref_res == true then
- log_message("Fuel item(s) consumed, 0 fuel gained (turtle was already full). This is OK.")
- else
- error_stop("Unexpected return value from turtle.refuel() with Fuel EC item: " .. tostring(ref_res))
- end
- log_message("Digging Fuel EC to retrieve it after refueling.")
- if not safe_dig() then error_stop("Failed to dig Fuel EC after refueling.") end
- if not turtle.suck() then log_message("WARN: Failed to pick up Fuel EC item after digging (post-refuel).") end
- retrieve_specific_ender_chest_item(FUEL_ENDER_CHEST_NBT, "Fuel EC (post-refuel)")
- turn_around()
- log_message("Refueling complete.")
- else
- if DEBUG_MODE then log_message("Debug: Fuel level is OK.") end
- end
- end
- local function item_deposit_check()
- if DEBUG_MODE then log_message("Debug: Initiating item deposit check...") end
- local free_slots = count_free_slots()
- if DEBUG_MODE then log_message("Debug: Current free slots: " .. free_slots) end
- if free_slots < MIN_FREE_SLOTS_FOR_OPERATION then
- log_message("Inventory space low (" .. free_slots .. " free). Depositing items.")
- if not ITEM_DUMP_ENDER_CHEST_NBT or not FUEL_ENDER_CHEST_NBT then
- error_stop("Cannot deposit items: Ender Chest NBTs (Item-Dump or Fuel) are missing.")
- end
- 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")
- if not dump_s then error_stop("Item-Dump EC (NBT " .. tostring(ITEM_DUMP_ENDER_CHEST_NBT) .. ") not found in inventory for deposit.") end
- turn_around()
- 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
- safe_place(dump_s)
- log_message("Placed Item-Dump EC behind turtle for item deposit.")
- local o_s = turtle.getSelectedSlot()
- for i = 1, 16 do
- turtle.select(i)
- local it_d = turtle.getItemDetail(i)
- if it_d and it_d.name ~= AIR_ITEM_NAME then
- if not (it_d.name:lower() == ENDER_CHEST_ITEM_NAME:lower() and it_d.nbt == FUEL_ENDER_CHEST_NBT) then
- if DEBUG_MODE then log_message("Debug: Attempting to deposit slot " .. i .. ": " .. it_d.name .. " x" .. it_d.count) end
- local items_to_drop = it_d.count
- for _ = 1, items_to_drop do
- if turtle.getItemCount(i) == 0 then break end
- if not turtle.drop() then
- log_message("WARN: Failed to drop item from slot " .. i .. " (" .. it_d.name .. "). Item-Dump EC might be full. Stopping deposit for this slot.")
- break
- end
- end
- if turtle.getItemCount(i) == 0 then
- if DEBUG_MODE then log_message("Debug: Slot " .. i .. " (" .. it_d.name .. ") emptied successfully.") end
- else
- log_message("WARN: Slot " .. i .. " (" .. it_d.name .. ") not fully emptied. Remaining: " .. turtle.getItemCount(i))
- end
- else
- if DEBUG_MODE then log_message("Debug: Skipping Fuel EC in slot " .. i .. " during deposit.") end
- end
- end
- end
- turtle.select(o_s)
- log_message("Digging Item-Dump EC to retrieve it after deposit.")
- if not safe_dig() then error_stop("Failed to dig Item-Dump EC after deposit.") end
- if not turtle.suck() then log_message("WARN: Failed to pick up Item-Dump EC item after digging (post-deposit).") end
- retrieve_specific_ender_chest_item(ITEM_DUMP_ENDER_CHEST_NBT, "Item-Dump Ender Chest (post-deposit)")
- turn_around()
- log_message("Item deposit procedure complete. Current free slots: " .. count_free_slots())
- else
- if DEBUG_MODE then log_message("Debug: Sufficient inventory space available (" .. free_slots .. " free).") end
- end
- update_dig_move_action_count()
- end
- local function system_check()
- log_message("--- Sys Check ---")
- fuel_check()
- item_deposit_check()
- log_message("--- Sys Check Done ---")
- if dig_and_move_actions_before_check <= 0 then
- log_message("WARN: System check completed, but no dig/move actions are available (inventory likely full and deposit failed to clear enough space).")
- end
- end
- local function calibrate_y_level()
- log_message("Y-cal: Starting Y-level calibration by digging to bedrock...")
- local distance_dug_down = 0
- while true do
- local b_s, b_d = turtle.inspectDown()
- if b_s and b_d.name:lower() == BEDROCK_ITEM_NAME:lower() then
- log_message("Y-cal: Bedrock detected below.")
- break
- end
- if not safe_dig_down() then
- log_message("Y-cal: Encountered unbreakable block (assumed bedrock) while digging down.")
- break
- end
- if not safe_down() then error_stop("Y-cal: Failed to move down during calibration.") end
- distance_dug_down = distance_dug_down + 1
- if distance_dug_down % 20 == 0 and DEBUG_MODE then
- log_message("Debug Y-cal: Descended " .. distance_dug_down .. " blocks so far.")
- end
- if distance_dug_down > WORLD_BOTTOM_Y_CALIBRATION_DEPTH + 200 then
- error_stop("Y-cal: Descended significantly further than expected (" .. distance_dug_down .. " blocks). Stopping calibration.")
- end
- end
- log_message("Y-cal: Reached bedrock (or unbreakable layer) after digging down " .. distance_dug_down .. " blocks.")
- log_message("Y-cal: Ascending " .. WORLD_BOTTOM_Y_CALIBRATION_DEPTH .. " blocks to establish relative Y=0.")
- for i = 1, WORLD_BOTTOM_Y_CALIBRATION_DEPTH do
- 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
- 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
- if i % 20 == 0 and DEBUG_MODE then
- log_message("Debug Y-cal: Ascended " .. i .. " blocks so far.")
- end
- end
- current_y_relative = 0
- is_y_calibrated = true
- log_message("Y-cal: Y-level calibration complete. Current relative Y is 0.")
- end
- local function mine_shaft_down()
- if DEBUG_MODE then log_message("Debug: Mine Down: Starting descent from Y=" .. current_y_relative) end
- while true do
- if dig_and_move_actions_before_check <= 0 then
- system_check()
- if dig_and_move_actions_before_check <= 0 then
- error_stop("No actions available after system check during mine_shaft_down.")
- end
- end
- local b_s, b_d = turtle.inspectDown()
- if b_s and b_d.name:lower() == BEDROCK_ITEM_NAME:lower() then
- if DEBUG_MODE then log_message("Debug: Mine Down: Bedrock detected below at Y=" .. (current_y_relative -1) .. ". Stopping descent.") end
- break
- end
- if not safe_dig_down() then
- 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
- break
- end
- decrement_dig_move_actions()
- if not safe_down() then error_stop("Mine Down: Failed to move down. Current Y=" .. current_y_relative) end
- current_y_relative = current_y_relative - 1
- 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
- if current_y_relative < -(WORLD_BOTTOM_Y_CALIBRATION_DEPTH + 250) then
- log_message("WARN: Mine Down: Reached very low Y-level (" .. current_y_relative .. "). Stopping descent as a precaution.")
- break
- end
- end
- if DEBUG_MODE then log_message("Debug: Mine Down: Finished descent. Current Y=" .. current_y_relative) end
- end
- local function mine_shaft_up()
- if DEBUG_MODE then log_message("Debug: Mine Up: Starting ascent to Y=0 from Y=" .. current_y_relative) end
- while current_y_relative < 0 do
- if dig_and_move_actions_before_check <= 0 then
- system_check()
- if dig_and_move_actions_before_check <= 0 then
- error_stop("No actions available after system check during mine_shaft_up.")
- end
- end
- if not safe_dig_up() then error_stop("Mine Up: Failed to dig up. Current Y=" .. current_y_relative) end
- decrement_dig_move_actions()
- if not safe_up() then error_stop("Mine Up: Failed to move up. Current Y=" .. current_y_relative) end
- current_y_relative = current_y_relative + 1
- 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
- if current_y_relative > 50 then
- log_message("WARN: Mine Up: Ascended significantly above Y=0 (Current Y=" .. current_y_relative .. "). Stopping ascent.")
- break
- end
- end
- if current_y_relative == 0 then
- if DEBUG_MODE then log_message("Debug: Mine Up: Successfully reached target Y=0.") end
- else
- log_message("WARN: Mine Up: Finished ascent, but not at Y=0. Final Y=" .. current_y_relative)
- end
- end
- --------------------------------------------------------------------------------
- -- Main Program Logic: Startup & Loop
- --------------------------------------------------------------------------------
- log_message("--- Initializing Miner: Determining Start Scenario ---")
- local inv_item_dump_ec_slot = nil
- local inv_coal_block_slot = nil
- local inv_chunk_loader_slot = nil
- local inv_pickaxe_candidate_slots = {}
- local inv_ender_chest_details = {}
- log_message("Scanning inventory slots 1-16 for initial items...")
- for i = 1, 16 do
- local item = turtle.getItemDetail(i)
- if item and item.name ~= AIR_ITEM_NAME then
- if DEBUG_MODE then log_message(" Debug SP Scan: Slot " .. i .. ":", item) end
- if item.name:lower() == ENDER_CHEST_ITEM_NAME:lower() then
- table.insert(inv_ender_chest_details, {slot = i, detail = item})
- if item.nbt == ITEM_DUMP_ENDER_CHEST_NBT then
- if inv_item_dump_ec_slot then error_stop("SP Scan: Duplicate Item-Dump ECs found in inventory.") end
- inv_item_dump_ec_slot = i
- if DEBUG_MODE then log_message(" Debug SP Scan: Found Item-Dump EC in slot " .. i) end
- end
- elseif item.name:lower() == COAL_BLOCK_ITEM_NAME:lower() then
- if inv_coal_block_slot then
- if DEBUG_MODE then log_message(" WARN SP Scan: Multiple coal block stacks found. Using first one (slot " .. inv_coal_block_slot .. ").") end
- else inv_coal_block_slot = i end
- elseif item.name:lower() == CHUNK_CONTROLLER_ITEM_NAME:lower() then
- if inv_chunk_loader_slot then
- if DEBUG_MODE then log_message(" WARN SP Scan: Multiple chunk controllers found. Using first one (slot " .. inv_chunk_loader_slot .. ").") end
- else inv_chunk_loader_slot = i end
- end
- if (item.maxDamage and item.maxDamage > 0) or string.find(item.name:lower(), "pickaxe") then
- if DEBUG_MODE then log_message(" Debug SP Scan: Slot "..i.." ("..item.name..") considered potential tool. Adding to pickaxe candidates.") end
- table.insert(inv_pickaxe_candidate_slots, i)
- end
- end
- end
- if DEBUG_MODE then log_message(" Debug SP Scan: Raw inv_pickaxe_candidate_slots: {" .. table.concat(inv_pickaxe_candidate_slots, ", ") .. "}") end
- local actual_pickaxe_slot_for_sp1 = nil
- if #inv_pickaxe_candidate_slots > 0 then
- local filtered_pickaxe_slots = {}
- if DEBUG_MODE then log_message(" Debug SP Scan: Filtering pickaxe candidates for SP1 setup:") end
- for _, p_s in ipairs(inv_pickaxe_candidate_slots) do
- local it_d_filter = turtle.getItemDetail(p_s) -- Re-fetch, though should be same
- local candidate_name = it_d_filter and it_d_filter.name or "UnknownItem"
- if DEBUG_MODE then log_message(" Debug SP Scan: Filtering candidate pickaxe slot " .. p_s .. " (" .. candidate_name .. "):") end
- local is_cc_slot = (inv_chunk_loader_slot and p_s == inv_chunk_loader_slot)
- local is_any_ec_slot = false
- for _, ec_entry in ipairs(inv_ender_chest_details) do
- if ec_entry.slot == p_s then is_any_ec_slot = true; break end
- end
- if DEBUG_MODE then log_message(" IsCC? " .. tostring(is_cc_slot) .. " IsAnyEC? " .. tostring(is_any_ec_slot)) end
- if not (is_any_ec_slot or is_cc_slot) then
- table.insert(filtered_pickaxe_slots, p_s)
- if DEBUG_MODE then log_message(" Added slot " .. p_s .. " ("..candidate_name..") to filtered pickaxe list.") end
- else
- if DEBUG_MODE then log_message(" Skipped slot " .. p_s .. " ("..candidate_name..") (it's an EC or CC).") end
- end
- end
- if DEBUG_MODE then log_message(" Debug SP Scan: Final filtered pickaxe candidates: {" .. table.concat(filtered_pickaxe_slots, ", ") .. "}") end
- if #filtered_pickaxe_slots == 1 then
- actual_pickaxe_slot_for_sp1 = filtered_pickaxe_slots[1]
- elseif #filtered_pickaxe_slots > 1 then
- 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])
- actual_pickaxe_slot_for_sp1 = filtered_pickaxe_slots[1]
- else
- if DEBUG_MODE then log_message("Debug SP Scan: No suitable pickaxe candidate found after filtering for SP1.") end
- end
- else
- if DEBUG_MODE then log_message("Debug SP Scan: No raw pickaxe candidates found in inventory.") end
- end
- log_message("Initial inventory scan summary for Start Scenario determination:")
- log_message(" Item-Dump EC (NBT " .. ITEM_DUMP_ENDER_CHEST_NBT .. ") in inv slot: " .. tostring(inv_item_dump_ec_slot))
- log_message(" Coal Block in inv slot: " .. tostring(inv_coal_block_slot))
- log_message(" Chunk Controller in inv slot: " .. tostring(inv_chunk_loader_slot))
- log_message(" Selected Pickaxe candidate for SP1 in inv slot: " .. tostring(actual_pickaxe_slot_for_sp1))
- log_message(" Total Ender Chests count in inventory: " .. #inv_ender_chest_details)
- if DEBUG_MODE then
- for idx, ec_e in ipairs(inv_ender_chest_details) do
- log_message(" Debug EC #" .. idx .. " slot " .. ec_e.slot .. ": " .. ec_e.detail.name .. " (NBT: " .. tostring(ec_e.detail.nbt) .. ")")
- end
- end
- log_message("Checking currently equipped items (left/right hand)...")
- local eq_left_item_detail = get_item_from_hand_temporarily("left")
- local eq_right_item_detail = get_item_from_hand_temporarily("right")
- local is_pickaxe_effectively_equipped = (eq_left_item_detail and eq_left_item_detail.name ~= AIR_ITEM_NAME and
- ((eq_left_item_detail.maxDamage and eq_left_item_detail.maxDamage > 0) or string.find(eq_left_item_detail.name:lower(), "pickaxe")))
- local is_chunk_controller_equipped = (eq_right_item_detail and eq_right_item_detail.name:lower() == CHUNK_CONTROLLER_ITEM_NAME:lower())
- log_message("Equipped items check summary:")
- log_message(" Pickaxe effectively in left hand: " .. tostring(is_pickaxe_effectively_equipped) .. (is_pickaxe_effectively_equipped and (" (" .. eq_left_item_detail.name .. ")") or ""))
- log_message(" Chunk Controller effectively in right hand: " .. tostring(is_chunk_controller_equipped) .. (is_chunk_controller_equipped and (" (" .. eq_right_item_detail.name .. ")") or ""))
- 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
- #inv_ender_chest_details == 1 and (inv_ender_chest_details[1] and inv_ender_chest_details[1].slot == inv_item_dump_ec_slot) and
- not is_pickaxe_effectively_equipped and not is_chunk_controller_equipped
- if sp1_conditions_met then
- log_message("Start Scenario: Conditions for Start Point 1 (initial setup) met. Proceeding with SP1.")
- perform_initial_setup(inv_item_dump_ec_slot, inv_coal_block_slot, inv_chunk_loader_slot, actual_pickaxe_slot_for_sp1)
- else
- log_message("Start Scenario: Conditions for Start Point 1 NOT met. Checking for Start Point 2 (resumed operation)...")
- local fuel_ec_detail_for_sp2 = nil
- local item_dump_ec_present_for_sp2 = false
- if #inv_ender_chest_details == 2 then
- for _, ec_entry in ipairs(inv_ender_chest_details) do
- if ec_entry.detail.nbt == ITEM_DUMP_ENDER_CHEST_NBT then
- item_dump_ec_present_for_sp2 = true
- elseif ec_entry.detail.nbt and ec_entry.detail.nbt ~= ITEM_DUMP_ENDER_CHEST_NBT then
- if fuel_ec_detail_for_sp2 then error_stop("SP2 Check: Multiple candidate Fuel Ender Chests found in inventory.") end
- fuel_ec_detail_for_sp2 = ec_entry.detail
- end
- end
- end
- local sp2_conditions_met = is_pickaxe_effectively_equipped and is_chunk_controller_equipped and
- item_dump_ec_present_for_sp2 and fuel_ec_detail_for_sp2
- if sp2_conditions_met then
- log_message("Start Scenario: Conditions for Start Point 2 (resumed operation) met.")
- FUEL_ENDER_CHEST_NBT = fuel_ec_detail_for_sp2.nbt
- log_message("Fuel EC NBT identified from inventory (SP2): " .. FUEL_ENDER_CHEST_NBT)
- 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
- error_stop("SP2 Sanity Check: Item-Dump EC (NBT " .. ITEM_DUMP_ENDER_CHEST_NBT .. ") became unfindable in inventory.")
- end
- log_message("SP2 confirmed. Miner is ready to resume.")
- else
- log_message("Start Scenario: Conditions for Start Point 2 NOT met.")
- log_message("--- Start Scenario Determination Failure ---")
- log_message(" Debug Info - SP1 Met: " .. tostring(sp1_conditions_met))
- log_message(" Debug Info - SP2 Met: " .. tostring(sp2_conditions_met))
- log_message(" Inv Detail - Item-Dump EC Slot: " .. tostring(inv_item_dump_ec_slot))
- log_message(" Inv Detail - Coal Block Slot: " .. tostring(inv_coal_block_slot))
- log_message(" Inv Detail - Chunk Controller Slot: " .. tostring(inv_chunk_loader_slot))
- log_message(" Inv Detail - Pickaxe Slot for SP1: " .. tostring(actual_pickaxe_slot_for_sp1))
- log_message(" Inv Detail - Number of ECs in inv: " .. #inv_ender_chest_details)
- log_message(" Equip Detail - Pickaxe Equipped: " .. tostring(is_pickaxe_effectively_equipped))
- log_message(" Equip Detail - CC Equipped: " .. tostring(is_chunk_controller_equipped))
- log_message(" SP2 Check - ItemDumpEC Present: " .. tostring(item_dump_ec_present_for_sp2))
- 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"))
- 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.")
- end
- end
- system_check()
- if not is_y_calibrated then
- calibrate_y_level()
- system_check()
- end
- log_message("--- Starting Main Mining Loop ---")
- local current_cycle_number = 0
- while true do
- current_cycle_number = current_cycle_number + 1
- log_message("\n--- Cycle #" .. current_cycle_number .. " ---")
- if DEBUG_MODE then log_message("Debug: Current Y=" .. current_y_relative .. ". Actions before next check: " .. dig_and_move_actions_before_check) end
- if dig_and_move_actions_before_check <= 0 then
- system_check()
- if dig_and_move_actions_before_check <= 0 then
- error_stop("No actions available after system check at the start of main loop cycle " .. current_cycle_number .. ".")
- end
- end
- if DEBUG_MODE then log_message("Debug: Mining layer: Digging forward then moving forward (at Y=" .. current_y_relative .. ").") end
- if not safe_dig() then
- log_message("WARN: safe_dig() returned false (encountered undiggable block) at main mining Y-level (Y="..current_y_relative.."). Attempting to move forward regardless...")
- end
- if not safe_forward() then error_stop("Failed to move forward at main mining Y-level (Y=" .. current_y_relative .. ") after dig attempt.") end
- decrement_dig_move_actions()
- mine_shaft_down()
- if dig_and_move_actions_before_check <= 0 then
- system_check()
- if dig_and_move_actions_before_check <= 0 then
- error_stop("No actions available after system check before moving forward at bedrock layer (Cycle " .. current_cycle_number .. ").")
- end
- end
- if DEBUG_MODE then log_message("Debug: Bedrock layer: Digging forward then moving forward (at Y=" .. current_y_relative .. ").") end
- if not safe_dig() then
- log_message("WARN: safe_dig() returned false (encountered undiggable block) at bedrock Y-level (Y="..current_y_relative.."). Attempting to move forward regardless...")
- end
- if not safe_forward() then error_stop("Failed to move forward at bedrock layer (Y=" .. current_y_relative .. ") after dig attempt.") end
- decrement_dig_move_actions()
- mine_shaft_up()
- log_message("Cycle #" .. current_cycle_number .. " completed. Returned to Y=0 (relative).")
- end
Add Comment
Please, Sign In to add comment