Created: 16 days ago on 05/29/2025, 08:59:01 PM
Description: Update to Mining Script thanks to @Johanssen (Денис) and until updates to assistant or client on different tools we can use this seems to be the best one yet! Thank you again!
🪓 Auto-Mining with Ore Combine - How it Works
1️⃣ Script Start
Automatically calculates your weight limits:
Max Weight -15 = stop mining
Max Weight -35 = combine ore to reduce load,
,
,
2️⃣ Pickaxe Handling
If you don't have a pickaxe equipped:
Clears your hands
Equips any available pickaxe from your backpack,
,
,
3️⃣ Tile Targeting
On first run: prompts you to target a mining tile
Stores your selected tile for re-use in future loops,
⚠️ IMPORTANT: After ore combining you need to re-target manually!,
,
4️⃣ Mining Cycle
Uses pickaxe to mine the tile
Watches for errors: "too far", "no ore", "can't see", etc.,
,
5️⃣ Tool Breaks
If your pickaxe breaks:
Re-equips a new one from your backpack
Automatically resumes mining,
,
,
6️⃣ Weight Checks
If you're overweight:
Tries to combine ore piles
If weight is still too high, stops mining,
,
,
7️⃣ Loop Forever
Keeps mining until you’re too heavy or the tile becomes invalid,
✅ Fully automatic
✅ Handles broken tools
✅ Combines ore intelligently
💡 Tip: Have multiple pickaxes ready and enough backpack space.
--==========================--
-- Phase 3.0: Add Ore Combining on Weight Threshold --
--==========================--
-- Constants
local COLOR_INFO = 93 -- Blue
local COLOR_ALERT = 33 -- Red
local COLOR_ACTION = 73 -- Green
local COLOR_HINT = 53 -- Yellow
local COLOR_WARNING = 48 -- Orange
local COLOR_SUCCESS = 84 -- Light Blue
-- Weight Limits
local function GetDynamicWeightLimits()
local maxWeight = Player.MaxWeight
return maxWeight - 15, maxWeight - 35
end
local WEIGHT_LIMIT, COMBINE_THRESHOLD = GetDynamicWeightLimits()
-- Globals
local lastTileSerial = nil
-- Utility Functions
local function IsOverweight(threshold)
return Player.Weight >= (threshold or WEIGHT_LIMIT)
end
local function TryCombineOrePair(largeOre, smallOre)
Player.UseObject(largeOre.Serial)
if Targeting.WaitForTarget(1000) then
Targeting.Target(smallOre.Serial)
Pause(625)
return true
end
return false
end
function GetEquippedPickaxe()
local pickaxe = Items.FindByLayer(1)
if pickaxe and string.find(string.lower(pickaxe.Name or ""), "pickaxe") then
return pickaxe
end
return nil
end
function EquipPickaxe()
local function ClearHands()
local hands = { ["left"] = 1, ["right"] = 2 }
for hand, layer in pairs(hands) do
local held = Items.FindByLayer(layer)
if held then
Messages.Overhead("Clear " .. hand .. " hand", COLOR_WARNING, Player.Serial)
local cleared = Player.ClearHands(hand)
if cleared then Pause(625) end
end
end
end
local function FindPickaxes()
local items = Items.FindByFilter({ onground = false })
local result = {}
for _, item in ipairs(items) do
if item.RootContainer == Player.Serial and item.Layer ~= 1 and item.Layer ~= 2 then
if string.find(string.lower(item.Name or ""), "pickaxe") then
table.insert(result, item)
end
end
end
return result
end
ClearHands()
local pickaxes = FindPickaxes()
if #pickaxes == 0 then
Messages.Overhead("No pickaxes", COLOR_ALERT, Player.Serial)
return nil
end
for _, pickaxe in ipairs(pickaxes) do
Messages.Overhead("Equip: " .. (pickaxe.Name or "Unnamed"), COLOR_HINT, Player.Serial)
Player.Equip(pickaxe.Serial)
Pause(625) -- Might be higher due to lag
local timeout = os.clock() + 1.0
while os.clock() < timeout do
local equippedNow = Items.FindByLayer(1)
if equippedNow and equippedNow.Serial == pickaxe.Serial then
Messages.Overhead("Equipped!", COLOR_SUCCESS, Player.Serial)
return equippedNow
end
Pause(125)
end
end
Messages.Overhead("Equip failed", COLOR_ALERT, Player.Serial)
return nil
end
function HandleMiningErrors(currentPickaxe)
if Journal.Contains("You have worn out your tool!") then
Messages.Overhead("Tool broke", COLOR_ALERT, Player.Serial)
if Targeting.WaitForTarget(100) then
Targeting.Cancel()
end
local newPickaxe = EquipPickaxe()
if not newPickaxe then
Messages.Overhead("No tools", COLOR_WARNING, Player.Serial)
return nil, true
end
Player.UseObject(newPickaxe.Serial)
Pause(125)
Journal.Clear()
return newPickaxe, false
end
return currentPickaxe, false
end
function CombineOrePiles()
local largeOreGraphics = { [0x19B9] = true, [0x19B8] = true, [0x19BA] = true }
local smallOreGraphic = 0x19B7
local didCombineAnything = false
repeat
local didCombine = false
local itemList = Items.FindByFilter({})
for _, item1 in ipairs(itemList) do
if item1 and item1.RootContainer == Player.Serial and largeOreGraphics[item1.Graphic] then
for _, item2 in ipairs(itemList) do
if item2 and item2.RootContainer == Player.Serial
and item1.Hue == item2.Hue
and item2.Graphic == smallOreGraphic then
if TryCombineOrePair(item1, item2) then
Messages.Overhead("Combining...", COLOR_HINT, Player.Serial)
didCombine = true
didCombineAnything = true
Pause(625) -- let the stack settle
break
end
end
end
end
if didCombine then break end
end
until not didCombine
if didCombineAnything then
Messages.Overhead("Ore combined.", COLOR_SUCCESS, Player.Serial)
return true
else
return false
end
end
function TargetMiningTile(firstRun)
if firstRun then
Messages.Overhead("Target tile", COLOR_INFO, Player.Serial)
local pickaxe = GetEquippedPickaxe()
if not pickaxe then return nil end
if not Targeting.WaitForTarget(1000) then return nil end
lastTileSerial = Targeting.LastTarget
return false
else
if Targeting.WaitForTarget(1000) then
if lastTileSerial then
Targeting.Target(lastTileSerial)
else
Targeting.TargetLast()
end
end
return firstRun
end
end
function CheckEndConditions()
if Journal.Contains("There is no metal here to mine.") then
Messages.Overhead("No ore", COLOR_WARNING, Player.Serial)
return true
end
if Journal.Contains("too far") then
Messages.Overhead("Too far", COLOR_WARNING, Player.Serial)
return true
end
if Journal.Contains("cannot be seen") then
Messages.Overhead("Not visible", COLOR_WARNING, Player.Serial)
return true
end
if Journal.Contains("can't mine") or Journal.Contains("cannot mine that") then
Messages.Overhead("Mining error", COLOR_WARNING, Player.Serial)
return true
end
return false
end
function PerformMiningAction(firstRun)
if IsOverweight() then
if CombineOrePiles() and not IsOverweight() then
Messages.Overhead("Resuming...", COLOR_SUCCESS, Player.Serial)
else
Messages.Overhead("Too heavy", COLOR_ALERT, Player.Serial)
return nil, firstRun
end
end
local pickaxe = GetEquippedPickaxe()
if not pickaxe then
Messages.Overhead("No pickaxe", COLOR_ALERT, Player.Serial)
pickaxe = EquipPickaxe()
if not pickaxe then return nil, firstRun end
end
Journal.Clear()
Player.UseObject(pickaxe.Serial)
local updatedFirstRun = TargetMiningTile(firstRun)
if updatedFirstRun == nil then return nil, firstRun end
local timeout = os.clock() + 1.0
while os.clock() < timeout do
if CheckEndConditions() then
return nil, firstRun
end
Pause(125)
end
local newPickaxe, abort = HandleMiningErrors(pickaxe)
if abort then return nil, firstRun end
return true, updatedFirstRun
end
function Main()
local firstRun = true
Journal.Clear()
while true do
::nextmine::
local success, updatedFirstRun = PerformMiningAction(firstRun)
if not success then return end
if IsOverweight(COMBINE_THRESHOLD) then
if CombineOrePiles() then
firstRun = true
goto nextmine
end
end
firstRun = updatedFirstRun
end
end
Main()