refactored to couple Agent and Doer in a more sensible way through inheritance.

This commit is contained in:
dtookey 2023-08-05 07:32:37 -04:00
parent 065d85dd59
commit a39268a7fc
3 changed files with 54 additions and 57 deletions

View File

@ -11,24 +11,18 @@ import java.awt.event.KeyEvent
* *
* @property doer The Doer used by this Agent for simulating user input. * @property doer The Doer used by this Agent for simulating user input.
*/ */
class Agent { class Agent: Doer() {
companion object { companion object {
/** /**
* Constant for the F6 key code. * Performs a standing crafting task loop for the agent.
*
* The agent will repeatedly go to the bank, withdraw items,
* open the crafting interface, craft items, close it,
* and deposit items back until the total volume is reached.
*
* @param params the parameters configuring how to perform the standing task
*/ */
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
fun doStandingTask(params: StandingTaskParams) { fun doStandingTask(params: StandingTaskParams) {
val agent = params.agent val agent = params.agent
agent.doLoop(params.totalVolume, params.volumePerStep) { agent.doLoop(params.totalVolume, params.volumePerStep) {
@ -42,6 +36,14 @@ class Agent {
} }
} }
/**
* Performs a looped travel task for the agent.
*
* This handles having the agent repeatedly travel from the bank
* to a station, process items, and travel back.
*
* @param params the parameters configuring how to perform the task
*/
fun doTravelTask(params: TravelTaskParams) { fun doTravelTask(params: TravelTaskParams) {
val agent = params.agent val agent = params.agent
agent.doLoop(params.totalVolume, params.volumePerStep) { agent.doLoop(params.totalVolume, params.volumePerStep) {
@ -58,26 +60,20 @@ class Agent {
} }
} }
/**
* 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. * Computes the total number of steps needed to process the given total volume.
* *
* @param totalVolume The total volume that needs to be processed. * @param totalVolume the total amount that needs to be processed
* @param volumePerStep The volume that can be processed per step. * @param volumePerStep the amount to process per step
* * @return the number of steps required to process the total volume
* @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) = private fun computeTotalSteps(totalVolume: Int, volumePerStep: Int) =
totalVolume / volumePerStep + 1 totalVolume / volumePerStep + if (totalVolume % volumePerStep > 0) {
1
} else {
0
}
/** /**
@ -179,14 +175,14 @@ class Agent {
*/ */
fun promptUserForPoint(prompt: String): Point { fun promptUserForPoint(prompt: String): Point {
println(prompt) println(prompt)
doer.countDown(5) { countDown(5) {
print("\rtaking point snapshot in $it... ") print("\rtaking point snapshot in $it... ")
if (it == 0) { if (it == 0) {
println("\r ") println("\r ")
} }
} }
return doer.getPointerLocation() return getPointerLocation()
} }
/** /**
@ -206,14 +202,14 @@ class Agent {
* a reasonable scroll animation speed. * a reasonable scroll animation speed.
*/ */
fun scrollOutToHeight(height: Int, scrollWaitAndVariance: Long = 10L) { fun scrollOutToHeight(height: Int, scrollWaitAndVariance: Long = 10L) {
doer.sleep(1000) sleep(1000)
for (i in 0 until height * 2) { for (i in 0 until height * 2) {
doer.scrollIn(scrollWaitAndVariance, scrollWaitAndVariance) scrollIn(scrollWaitAndVariance, scrollWaitAndVariance)
} }
for (i in 0 until height) { for (i in 0 until height) {
doer.scrollOut(scrollWaitAndVariance, scrollWaitAndVariance) scrollOut(scrollWaitAndVariance, scrollWaitAndVariance)
} }
} }
@ -242,19 +238,19 @@ class Agent {
waitDurationVariance: Long waitDurationVariance: Long
) { ) {
//open the bank located by the chest parameter //open the bank located by the chest parameter
doer.moveMouseLeftClickAndSleep(doer.getAlmostPoint(chest, Doer.WiggleParams()), 900, 400) moveMouseLeftClickAndSleep(getAlmostPoint(chest, Doer.WiggleParams()), 900, 400)
//withdraw the desired inventory preset //withdraw the desired inventory preset
doer.keypress(bankPresetHotkey) keypress(bankPresetHotkey)
//sleep for a server tick //sleep for a server tick
doer.sleepForNTicks(1) sleepForNTicks(1)
//open the crafting dialog with the correct hotkey //open the crafting dialog with the correct hotkey
doer.keypress(craftingDialogueHotkey) keypress(craftingDialogueHotkey)
//sleep for a server tick //sleep for a server tick
doer.sleepForNTicks(1) sleepForNTicks(1)
//press the "accept" default hotkey //press the "accept" default hotkey
doer.keypress(Space) keypress(KeyEvent.VK_SPACE)
//wait for the desired time to finish //wait for the desired time to finish
doer.sleep(waitDurationMillis, waitDurationVariance) sleep(waitDurationMillis, waitDurationVariance)
} }
/** /**
@ -274,16 +270,16 @@ class Agent {
*/ */
fun bankStandWithoutDialog(chest: Point, invKey: Int, hotKey: Int) { fun bankStandWithoutDialog(chest: Point, invKey: Int, hotKey: Int) {
//open the bank located by the chest parameter //open the bank located by the chest parameter
doer.moveMouseLeftClickAndSleep(doer.getAlmostPoint(chest, Doer.WiggleParams()), 900, 400) moveMouseLeftClickAndSleep(getAlmostPoint(chest, Doer.WiggleParams()), 900, 400)
//withdraw the desired inventory preset //withdraw the desired inventory preset
doer.keypress(invKey) keypress(invKey)
doer.sleepForNTicks(1) sleepForNTicks(1)
//press the hotkey that causes action without dialogue //press the hotkey that causes action without dialogue
doer.keypress(hotKey) keypress(hotKey)
doer.sleepForNTicks(1) sleepForNTicks(1)
} }
/** /**
@ -314,24 +310,24 @@ class Agent {
waitDurationVarianceMillis: Long waitDurationVarianceMillis: Long
) { ) {
//move to the bank and open the interface //move to the bank and open the interface
doer.moveMouseLeftClickAndSleep( moveMouseLeftClickAndSleep(
doer.getAlmostPoint(chest, Doer.WiggleParams()), getAlmostPoint(chest, Doer.WiggleParams()),
travelDurationMillis, travelDurationMillis,
travelDurationVarianceMillis travelDurationVarianceMillis
) )
//withdraw desired loadout //withdraw desired loadout
doer.keypress(bankPresetHotkey) keypress(bankPresetHotkey)
doer.sleepForNTicks(1) sleepForNTicks(1)
//move to station and open the crafting dialog //move to station and open the crafting dialog
doer.moveMouseLeftClickAndSleep(station, travelDurationMillis, travelDurationVarianceMillis) moveMouseLeftClickAndSleep(station, travelDurationMillis, travelDurationVarianceMillis)
//start the crafting task //start the crafting task
doer.keypress(KeyEvent.VK_SPACE) keypress(KeyEvent.VK_SPACE)
//wait for it to complete //wait for it to complete
doer.sleep(waitDurationMillis, waitDurationVarianceMillis) sleep(waitDurationMillis, waitDurationVarianceMillis)
} }
/*============================================================================================================== /*==============================================================================================================

View File

@ -32,7 +32,7 @@ import kotlin.random.Random
* *
* @constructor Creates a Doer instance with a Robot. * @constructor Creates a Doer instance with a Robot.
*/ */
class Doer(private val robot: Robot = Robot()) { open class Doer(private val robot: Robot = Robot()) {
companion object{ companion object{
/** /**
* The duration in milliseconds of one "tick". The duration of 600ms matches the tick duration of game servers. * The duration in milliseconds of one "tick". The duration of 600ms matches the tick duration of game servers.
@ -130,7 +130,7 @@ class Doer(private val robot: Robot = Robot()) {
* *
* Returns immediately If button is negative. Button must be a positive integer. * Returns immediately If button is negative. Button must be a positive integer.
*/ */
private fun click(button: Int) { fun click(button: Int) {
//guardian logic //guardian logic
if (button < 0) { if (button < 0) {
return return

View File

@ -1,4 +1,5 @@
import java.awt.Point import java.awt.Point
import java.awt.event.InputEvent
import java.awt.event.KeyEvent import java.awt.event.KeyEvent
/** /**
@ -184,7 +185,7 @@ object Routines {
val well = agent.promptUserForPoint("Put your mouse over the well...") val well = agent.promptUserForPoint("Put your mouse over the well...")
agent.doLoop(params.totalVolume, params.volumePerStep) { agent.doLoop(params.totalVolume, params.volumePerStep) {
agent.processAtStationNearBank(chest, well, Agent.F6, 0, 0, 6500, 1000) agent.processAtStationNearBank(chest, well, KeyEvent.VK_F6, 0, 0, 6500, 1000)
} }
} }
@ -240,7 +241,7 @@ object Routines {
val chestFromSaw = Point(1226, 180) val chestFromSaw = Point(1226, 180)
agent.doLoop(params.totalVolume, params.volumePerStep) { agent.doLoop(params.totalVolume, params.volumePerStep) {
agent.processAtStationNearBank(chestFromSaw, sawFromChest, Agent.F6, 2700, 500, 64000, 1000) agent.processAtStationNearBank(chestFromSaw, sawFromChest, KeyEvent.VK_F6, 2700, 500, 64000, 1000)
} }
} }
} }