Compare commits

..

2 Commits

Author SHA1 Message Date
dtookey
79f1e9e0ce that was a lie, now everything has a kdoc 2023-08-03 14:22:20 -04:00
dtookey
18e243a431 everything has kdocs now 2023-08-03 14:08:30 -04:00
3 changed files with 444 additions and 89 deletions

View File

@ -1,29 +1,80 @@
import java.awt.Point
import java.awt.Robot
import java.awt.event.KeyEvent
import kotlin.math.ceil
/**
* Agent represents an autonomous agent that can simulate mouse and keyboard actions.
*
* This class provides methods for the agent to perform actions like moving the mouse,
* clicking, pressing keys, prompting the user, and looping through repetitive tasks.
*
* The Agent uses a Doer instance internally to execute low-level keyboard and mouse operations.
*
* @property doer The Doer used by this Agent for simulating user input.
*/
class Agent {
companion object {
/**
* Constant for the F6 key code.
*/
const val F6 = KeyEvent.VK_F6
/**
* Constant for the Spacebar key code.
*/
const val Space = KeyEvent.VK_SPACE
/**
* Constant for the Minus/Dash key code.
*/
const val Minus = KeyEvent.VK_MINUS
}
/**
* The Doer instance used by this Agent for simulated mouse and keyboard actions.
*/
private val doer = Doer()
/**
* Calculates the total number of steps needed to process the given volume.
*
* @param totalVolume The total volume that needs to be processed.
* @param volumePerStep The volume that can be processed per step.
*
* @return The computed total steps based on the total volume and volume per step.
*
* This method calculates the total steps by dividing the total volume by the volume per step,
* rounding up to account for any remainder/partial volume, and adding 1 to get an inclusive count.
*
* For example, with totalVolume = 101 and volumePerStep = 20, it would return 6 total steps.
*/
private fun computeTotalSteps(totalVolume: Int, volumePerStep: Int) =
totalVolume / volumePerStep + 1
/**
* Performs a loop to repeatedly execute a task for automated steps.
*
* @param totalVolume The total number of units to process across all steps.
* @param volumePerStep The number of units to process per step.
* @param task The task function to execute on each step. It receives the Agent.
*
* This method handles iterating through the steps, reporting progress,
* timing the overall execution, and calling the task on each iteration.
*
* It uses computeTotalSteps to calculate how many iterations needed based on total
* and per step volumes. The task typically simulates some action like banking.
*/
fun doLoop(totalVolume: Int, volumePerStep: Int, task: (Agent) -> Unit) {
require(totalVolume>0){
require(totalVolume > 0) {
"You must make at least 1 thing in total"
}
require(volumePerStep>0){
require(volumePerStep > 0) {
"You must consume at least 1 thing per step"
}
fun computeTotalSteps(totalVolume: Int, volumePerStep: Int) = (ceil((totalVolume / volumePerStep).toDouble()) + 1).toInt()
val totalSteps =computeTotalSteps(totalVolume, volumePerStep)
val totalSteps = computeTotalSteps(totalVolume, volumePerStep)
val start = System.currentTimeMillis()
for (i in 0 until totalSteps) {
@ -35,11 +86,39 @@ class Agent {
println("Finished everything in ${prettyTimeString(finish - start)}")
}
/**
* Prints a progress report for the current step.
*
* @param step The current step number.
* @param of The total number of steps.
* @param dur The duration in milliseconds so far.
*
* This method prints a progress report to the console in the format:
* "Step {step} of {of} ({formattedDuration} complete | ~{remainingTime} remaining)"
*
* It calculates the estimated remaining time based on the current duration and
* number of steps completed vs total steps.
*
* The output is printed on the same line to dynamically update the progress.
*/
fun report(step: Int, of: Int, dur: Long) {
val remaining = (dur / step) * (of - step)
print("\rStep $step of $of (${prettyTimeString(dur)} complete\t|\t~${prettyTimeString(remaining)} remaining) ")
}
/**
* Formats the given duration in milliseconds into a human readable time string.
*
* @param durationMillis The duration to format in milliseconds.
*
* @return A formatted time string showing the duration broken down into hours, minutes, and seconds.
*
* This converts the duration into hours, minutes, and seconds based on millis per second,
* minute, and hour constants. It returns a string in the format "XhYmZs" where X, Y, and Z are
* the calculated hours, minutes, and seconds.
*
* If durationMillis is 0, it returns "No time data yet" instead.
*/
fun prettyTimeString(durationMillis: Long): String {
if (durationMillis == 0L) {
return "No time data yet"
@ -56,11 +135,25 @@ class Agent {
}
}
/**
* Prompts the user to position the mouse pointer and returns the pointer location.
*
* @param prompt The message to display to the user as a prompt.
*
* @return The Point containing the mouse pointer location after prompting.
*
* This first prints the prompt message to the console.
* It then uses the Doer to count down from 5 seconds while printing a countdown.
* After the countdown, it gets the current mouse pointer location using the Doer
* and returns the Point.
*
* This allows prompting the user to move the mouse before taking a snapshot of the pointer position.
*/
fun promptUserForPoint(prompt: String): Point {
println(prompt)
doer.countDown(5){
doer.countDown(5) {
print("\rtaking point snapshot in $it... ")
if(it == 0){
if (it == 0) {
println("\r ")
}
}
@ -68,17 +161,51 @@ class Agent {
return doer.getPointerLocation()
}
fun scrollOutToHeight(height: Int){
/**
* Scrolls out to the specified height by scrolling in and then back out.
*
* @param height The height in pixels to scroll out to.
* @param scrollWaitAndVariance The number of milliseconds to wait between scroll steps. Defaults to 16.
*
* This method first sleeps for 1 second. It then scrolls in by the height amount
* using repeated small scroll in steps.
*
* After scrolling in fully, it then scrolls back out using a few repeated small scroll outs.
*
* This allows smoothly animating the scroll all the way in and then back out to a specific height
*
* The scrollWaitAndVariance controls the pacing between scroll steps. The default of 16ms provides
* a reasonable scroll animation speed.
*/
fun scrollOutToHeight(height: Int, scrollWaitAndVariance: Long = 10L) {
doer.sleep(1000)
for(i in 0 until height){
doer.scrollIn(16, 16)
for (i in 0 until height*2) {
doer.scrollIn(scrollWaitAndVariance, scrollWaitAndVariance)
}
for(i in 0 until 8){
doer.scrollOut(16, 16)
for (i in 0 until height) {
doer.scrollOut(scrollWaitAndVariance, scrollWaitAndVariance)
}
}
/**
* Performs automated banking steps in a loop at the given chest location.
*
* @param chest The Point location of the bank chest to click on.
* @param invHotkey The key for the inventory preset to withdraw.
* @param hotbarHotkey The key for the crafting preset to open.
* @param waitDurationMillis The time in ms to wait at each loop iteration.
* @param waitDurationVariance Random variance to add to wait time.
*
* This handles the steps to open the bank interface, withdraw a preset,
* open a crafting interface, and wait for the desired duration.
*
* It clicks the bank chest, presses the inventory hotkey, presses the crafting hotkey,
* presses spacebar to accept, and waits before repeating.
*
* Useful for automated banking behaviors like crafting or herblore.
*/
fun bankStandForLoop(
chest: Point,
invHotkey: Int,
@ -102,6 +229,21 @@ class Agent {
doer.sleep(waitDurationMillis, waitDurationVariance)
}
/**
* Performs banking actions at a bank without additional dialog prompts.
*
* @param chest The Point location of the bank chest or stand to interact with.
* @param invKey The key code for the inventory preset hotkey to withdraw.
* @param hotKey The key code for the action hotkey, like crafting.
*
* This method handles clicking the chest, withdrawing a preset inventory,
* and activating a process like crafting that doesn't require additional prompts.
*
* It clicks the chest location, presses the inventory preset hotkey, waits briefly,
* then presses the action hotkey like crafting. This allows automated crafting at the bank.
*
* The sleeps provide a brief pause between actions to allow animations.
*/
fun bankStandWithoutDialog(chest: Point, invKey: Int, hotKey: Int) {
//open the bank located by the chest parameter
doer.moveMouseLeftClickAndSleep(doer.getAlmostPoint(chest, Doer.WiggleParams()), 900, 400)
@ -116,6 +258,24 @@ class Agent {
doer.sleepForNTicks(1)
}
/**
* Performs processing steps between a bank and nearby crafting station.
*
* @param chest The Point location of the bank chest.
* @param station The Point location of the processing station.
* @param invHotkey The inventory preset hotkey to withdraw at bank.
* @param travelDurationMillis Base travel time between bank and station.
* @param travelDurationVariance Random variance to add to travel time.
* @param waitDurationMillis Base wait time for processing at station.
* @param waitDurationVariance Random variance to add to wait time.
*
* This handles the steps to go to the bank, withdraw a preset, go to the station,
* open the processing interface, wait, and then loop.
*
* It goes between the bank and station locations, simulating travel time.
* At the bank it withdraws using the preset hotkey.
* At the station it activates processing and waits.
*/
fun processAtStationNearBank(
chest: Point,
station: Point,
@ -126,7 +286,11 @@ class Agent {
waitDurationVariance: Long
) {
//move to the bank and open the interface
doer.moveMouseLeftClickAndSleep(doer.getAlmostPoint(chest, Doer.WiggleParams()), travelDurationMillis, travelDurationVariance)
doer.moveMouseLeftClickAndSleep(
doer.getAlmostPoint(chest, Doer.WiggleParams()),
travelDurationMillis,
travelDurationVariance
)
//withdraw desired loadout
doer.keypress(invHotkey)
@ -145,7 +309,18 @@ class Agent {
/*==============================================================================================================
cheater functions
==============================================================================================================*/
fun getBankPoint():Point{
/**
* Prompts the user to position the mouse over the bank and returns the pointer location.
*
* @return The Point containing the mouse pointer location over the bank.
*
* This first prompts the user with a message to hold the mouse over the bank.
* It then uses promptUserForPoint() to display a countdown and get the mouse position.
*
* The returned Point can be used as the bank location for automated banking functions.
*/
fun getBankPoint(): Point {
return promptUserForPoint("Hold your mouse over the bank...")
}
}

View File

@ -32,13 +32,8 @@ import kotlin.random.Random
*
* @constructor Creates a Doer instance with a Robot.
*/
class Doer {
class Doer(private val robot: Robot = Robot()) {
/**
* The Robot instance used to perform mouse and keyboard actions.
*/
private val robot = Robot()
companion object {
/**
* The duration in milliseconds of one "tick". The duration of 600ms matches the tick duration of game servers.
*
@ -49,7 +44,7 @@ class Doer {
*
* For example, 5 ticks with this value would be 5 * 600 = 3000ms sleep duration.
*/
const val TICK_DURATION_MS = 600L
private val TICK_DURATION_MS = 600L
/**
* Extra padding in milliseconds added before actions to account for latency. 500ms is entirely arbitrary. It is
@ -61,8 +56,7 @@ class Doer {
* It is to account for latency in the system before actions like mouse moves
* and clicks actually take effect.
*/
const val LATENCY_PADDING_MS = 500L
}
private val LATENCY_PADDING_MS = 500L
/**
* Data class to hold parameters for random wiggle amounts when moving the mouse. This is useful for avoiding

View File

@ -1,142 +1,328 @@
import java.awt.Point
import java.awt.event.KeyEvent
/**
* Routines contains utility functions to perform common bot tasks and workflows.
*
* This includes functions like:
* - fullRunIncense: Handles the full incense stick crafting workflow.
* - processInventoryAtFurnace: Processes a total volume of inventory at a furnace near the bank.
* - processRefinedPlanksIntoFrames:Processes refined planks into frames at a sawmill near the bank.
*
* The routines use an Agent instance to perform actions like banking,
* depositing items, withdrawing presets, etc.
*
* The routines are encapsulated for pure convenience
*/
object Routines {
fun fullRunIncense(volHerbs: Int, volLogs: Int, volAshes: Int, volCleanHerbs: Int){
/**
* Performs the full incense stick crafting process from start to finish.
*
* @param volHerbs The number of grimy herbs to clean.
* @param volLogs The number of magic logs to cut into sticks.
* @param volAshes The number of sticks to coat in ashes.
* @param volCleanHerbs The number of clean herbs to infuse into sticks.
*
* This handles the entire incense stick crafting process:
* - Cleaning grimy herbs
* - Cutting magic logs into sticks
* - Coating sticks in ashes
* - Infusing clean herbs into sticks
*
* It loops through each step based on the provided volumes, performing the
* actions at the bank. The bank location is prompted from the user.
*
* Progress is printed after each step. Total elapsed time is printed at the end.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun fullRunIncense(volHerbs: Int, volLogs: Int, volAshes: Int, volCleanHerbs: Int) {
val agent = Agent()
val start = System.currentTimeMillis()
val chest = agent.getBankPoint()
//process any grimy herbs we might need
if(volHerbs > 0){
agent.doLoop(volHerbs, 28){
agent.bankStandWithoutDialog(chest, KeyEvent.VK_F1, KeyEvent.VK_1)
}
// Loop to clean grimy herbs:
// Withdraw herb preset, clean without dialog at bank
if (volHerbs > 0) {
cleanHerbs(volHerbs, agent = agent, chest = chest)
}
println("\rHerbs cleaned")
//cut up any magic logs we might need
if(volLogs > 0){
agent.doLoop(volLogs, 26){
agent.bankStandForLoop(chest, KeyEvent.VK_F2, KeyEvent.VK_2, 26000, 1200)
}
// Loop to cut magic logs into sticks:
// Withdraw log preset, cut logs using hotkey at bank
if (volLogs > 0) {
cutIncenseSticks(volLogs, agent = agent, chest = chest)
}
println("\rLogs cut into sticks")
//coat any sticks
if(volAshes > 0){
agent.doLoop(volAshes, 26){
agent.bankStandForLoop(chest, KeyEvent.VK_F3, KeyEvent.VK_3, 21000, 600)
}
// Loop to coat sticks in ashes:
// Withdraw ash preset, coat sticks using hotkey at bank
if (volAshes > 0) {
coatIncenseSticks(volAshes, agent = agent, chest = chest)
}
println("\rSticks coated in ashes")
//infuse any sticks
if(volCleanHerbs > 0){
agent.doLoop(volCleanHerbs, 27){
agent.bankStandForLoop(chest, KeyEvent.VK_F4, KeyEvent.VK_4, 48600, 600)
}
// Loop to infuse clean herbs into sticks:
// Withdraw herb preset, infuse sticks using hotkey at bank
if (volCleanHerbs > 0) {
infuseIncenseSticks(volCleanHerbs, agent = agent, chest = chest)
}
println("\rClean herbs infused")
val finish = System.currentTimeMillis()
println("Entire chain finished in ${agent.prettyTimeString(finish-start)}")
println("Entire chain finished in ${agent.prettyTimeString(finish - start)}")
}
fun cleanHerbs(volume: Int, step: Int = 14){
val agent = Agent()
val chest = agent.getBankPoint()
agent.doLoop(volume, step){
/**
* Cleans a volume of grimy herbs at the bank.
*
* @param totalVolume The total number of grimy herbs to clean.
* @param volumePerStep The number of herbs to clean per loop iteration.
*
* This handles cleaning the given total volume of grimy herbs by looping
* and cleaning the volumePerStep amount each iteration at the bank.
*
* It gets the bank location point from the user with a prompt.
*
* Inside the loop, it withdraws the herb cleaning preset and activates
* the cleaning without additional dialog boxes.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun cleanHerbs(totalVolume: Int, volumePerStep: Int = 14, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
agent.doLoop(totalVolume, volumePerStep) {
agent.bankStandWithoutDialog(chest, KeyEvent.VK_F1, KeyEvent.VK_1)
}
}
fun cutIncenseSticks(volume: Int, step: Int = 28){
/**
* Cuts a specified total volume of magic logs into incense sticks at the bank.
*
* @param totalVolume the total number of magic logs to cut into sticks
* @param volumePerStep the number of logs to cut per loop iteration. Default is 28.
*
* This handles cutting the given total volume of logs into sticks by looping
* and cutting the volumePerStep amount each iteration at the bank.
*
* It gets the bank location point by prompting the user.
*
* Inside the loop, it withdraws the log cutting preset and cuts the logs into
* sticks using the specified hotkeys.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun cutIncenseSticks(totalVolume: Int, volumePerStep: Int = 28, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
val agent = Agent()
val chest = agent.getBankPoint()
agent.doLoop(volume, step){
agent.doLoop(totalVolume, volumePerStep) {
agent.bankStandForLoop(chest, KeyEvent.VK_F2, KeyEvent.VK_2, 26000, 1200)
}
}
fun coatIncenseSticks(volume: Int, step: Int = 26){
/**
* Coats a specified number of incense sticks in ashes at the bank.
*
* @param totalVolume the total number of sticks to coat in ashes
* @param volumePerStep the number of sticks to coat per loop iteration. Default is 26.
*
* This handles coating the given total number of sticks in ashes by looping
* and coating volumePerStep sticks each iteration at the bank.
*
* It gets the bank location point from the Agent.
*
* Inside the loop, it withdraws the ash coating preset and coats the sticks
* using the specified hotkeys.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun coatIncenseSticks(totalVolume: Int, volumePerStep: Int = 26, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
val agent = Agent()
val chest = agent.getBankPoint()
agent.doLoop(volume, step){
agent.doLoop(totalVolume, volumePerStep) {
agent.bankStandForLoop(chest, KeyEvent.VK_F3, KeyEvent.VK_3, 21000, 600)
}
}
fun infuseIncenseSticks(volume: Int, step: Int = 27 ){
/**
* Infuses a specified number of incense sticks with clean herbs at the bank.
*
* @param totalVolume the total number of sticks to infuse with herbs
* @param volumePerStep the number of sticks to infuse per loop iteration. Default is 27.
*
* This handles infusing the given total number of sticks with clean herbs by looping
* and infusing volumePerStep sticks each iteration at the bank.
*
* It gets the bank location point from the Agent.
*
* Inside the loop, it withdraws the herb infusing preset and infuses the sticks
* using the specified hotkeys.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun infuseIncenseSticks(totalVolume: Int, volumePerStep: Int = 27, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
val agent = Agent()
val chest = agent.getBankPoint()
agent.doLoop(volume, step){
agent.doLoop(totalVolume, volumePerStep) {
agent.bankStandForLoop(chest, KeyEvent.VK_F4, KeyEvent.VK_4, 48600, 600)
}
}
fun potionGrind(volume: Int, step: Int = 14){
/**
* Crafts potions at the bank in a loop.
*
* @param totalVolume the total number of potions to craft
* @param volumePerStep the number of potions to craft per loop iteration. Default is 14.
*
* This handles crafting the given total volume of potions by looping
* and crafting the volumePerStep amount each iteration at the bank.
*
* It gets the bank location point by prompting the user.
*
* Inside the loop, it withdraws the potion crafting preset and crafts
* using the crafting hotkey which doesn't produce a dialogue box.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun craftPotionAtBank(totalVolume: Int, volumePerStep: Int = 14, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
val agent = Agent()
val chest = agent.getBankPoint()
agent.doLoop(volume, step){
agent.doLoop(totalVolume, volumePerStep) {
agent.bankStandForLoop(chest, Agent.F6, Agent.Minus, 19200, 600)
}
}
fun potionGrindWithWell(volume: Int, step: Int = 14){
/**
* Grinds a total volume of potions using a well near the bank.
*
* @param totalVolume the total number of potions to grind
* @param volumePerStep the number of potions to grind per loop iteration. Default is 14.
* @param travelDurationInMillis the time in milliseconds for the agent to travel between the bank and the well.
* Default is 0.
*
* This handles crafting the given total volume of potions by looping accounting for the crafting of volumePerStep
* potions amount each iteration using a well near the bank.
*
* It gets the bank location point and well location point by prompting the user.
*
* Inside the loop, it withdraws the potion grinding preset and creates potions using the well.
*
* After creating the potions, it banks again before the next iteration.
*
* The travelDurationInMillis parameter allows configuring the travel time between the bank and the well.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun potionGrindWithWell(totalVolume: Int, volumePerStep: Int = 14, travelDurationInMillis: Long = 0, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
val agent = Agent()
val chest = agent.getBankPoint()
val well = agent.promptUserForPoint("Put your mouse over the well...")
agent.doLoop(volume, step){
agent.processAtStationNearBank(chest, well, Agent.F6, 0, 0, 18600, 600)
agent.doLoop(totalVolume, volumePerStep) {
agent.processAtStationNearBank(chest, well, Agent.F6, travelDurationInMillis, 0, 18600, 600)
}
}
fun supremeOverloadGrind(volume: Int, step: Int = 4){
/**
* Grinds a total volume of supreme overload potions using a well near the bank.
*
* @param totalVolume the total number of potions to grind
* @param volumePerStep the number of potions to grind per loop iteration. Default is 4.
*
* This handles crafting the given total volume of supreme overload potions by looping
* and accounting for producing volumePerStep amount of potions each iteration using a well near the bank.
*
* It gets the bank location point and well location point by prompting the user.
*
* Inside the loop, it withdraws the potion grinding preset and grinds
* using the well.
*
* After crafting finishes, it banks again before the next iteration.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun supremeOverloadGrind(totalVolume: Int, volumePerStep: Int = 4, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
val agent = Agent()
val chest = agent.getBankPoint()
val well = agent.promptUserForPoint("Put your mouse over the well...")
agent.doLoop(volume, step){
agent.doLoop(totalVolume, volumePerStep) {
agent.processAtStationNearBank(chest, well, Agent.F6, 0, 0, 6500, 1000)
}
}
fun processInventoryAtFurnace(volume: Int, step: Int = 28){
/**
* Processes a total volume of inventory at a furnace near the bank.
*
* @param totalVolume the total number of inventory items to process
* @param volumePerStep the number of items to process per loop iteration. Default is 28.
*
* This handles processing the given total volume of inventory by looping
* and processing volumePerStep items each iteration at a furnace near the bank.
*
* It uses pre-defined points for the furnace location relative to the bank chest.
*
* Inside the loop, it travels to the furnace, processes the items using the
* process hotkey, and travels back to the bank before the next iteration.
*
* The camera is reset before starting.
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun processInventoryAtFurnace(totalVolume: Int, volumePerStep: Int = 28, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
val agent = Agent()
println("Reset the camera and zoom in")
agent.scrollOutToHeight(2)
println("Reset the camera")
agent.scrollOutToHeight(8)
val furnaceFromChest = Point(776, 321)
val chestFromFurance = Point(1713, 843)
agent.doLoop(volume, step){
agent.doLoop(totalVolume, volumePerStep) {
agent.processAtStationNearBank(chestFromFurance, furnaceFromChest, Agent.F6, 2500, 600, 53200, 600)
}
}
/**
* Processes refined planks into frames at a sawmill near the bank.
*
* @param totalVolume the total number of planks to process into frames
* @param volumePerStep the number of planks to process per loop iteration
*
* This handles processing the given total volume of refined planks into frames
* by looping and processing volumePerStep planks each iteration at a sawmill near the bank.
*
* It uses pre-defined points for the sawmill location relative to the bank chest.
*
* Inside the loop, it travels to the sawmill, processes the planks into frames
* using the process hotkey, and travels back to the bank before the next iteration.
*
* @deprecated Needs validation before using for real, as sawmill points are hardcoded
*/
@Deprecated("Needs validation before you use it for realsies")
fun processRefinedPlanksIntoFrames(volume: Int, step: Int){
fun processRefinedPlanksIntoFrames(totalVolume: Int, volumePerStep: Int, agent: Agent = Agent(), chest: Point = agent.getBankPoint()) {
println("You must zoom in all the way and have the compass pointing straight N with a completely top-down view\n you must also be standing at the touch point on the saw")
val agent = Agent()
agent.scrollOutToHeight(8)
val sawFromChest = Point(1079, 907)
val chestFromSaw = Point(1226, 180)
agent.doLoop(volume, step){
agent.doLoop(totalVolume, volumePerStep) {
// //standing at bank with full inv
// d.mouseMove(sawFromChest)
// d.sleep(100, 50)