diff --git a/build.gradle.kts b/build.gradle.kts
index da97c81e1..095783d41 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -15,8 +15,6 @@
* along with this program. If not, see .
*/
-import org.apache.tools.ant.taskdefs.condition.Os
-import org.gradle.internal.jvm.Jvm
import java.util.*
val modId: String by project
@@ -214,6 +212,10 @@ tasks {
}
kotlin {
+ compilerOptions {
+ freeCompilerArgs.add("-Xcontext-parameters")
+ }
+
jvmToolchain(21)
}
diff --git a/src/main/java/com/lambda/mixin/entity/EntityMixin.java b/src/main/java/com/lambda/mixin/entity/EntityMixin.java
index 8bd0ada26..0e99fed9f 100644
--- a/src/main/java/com/lambda/mixin/entity/EntityMixin.java
+++ b/src/main/java/com/lambda/mixin/entity/EntityMixin.java
@@ -150,7 +150,7 @@ private boolean modifyGetFlagGlowing(boolean original) {
private boolean wrapSetYaw(Entity instance, float yaw) {
return (instance != Lambda.getMc().player ||
RotationLock.INSTANCE.isDisabled() ||
- RotationLock.getRotationSettings().getRotationMode() != RotationMode.Lock ||
+ RotationLock.INSTANCE.getRotationConfig().getRotationMode() != RotationMode.Lock ||
RotationLock.getYawMode() == RotationLock.RotationMode.None);
}
@@ -158,7 +158,7 @@ private boolean wrapSetYaw(Entity instance, float yaw) {
private boolean wrapSetPitch(Entity instance, float yaw) {
return (instance != Lambda.getMc().player ||
RotationLock.INSTANCE.isDisabled() ||
- RotationLock.getRotationSettings().getRotationMode() != RotationMode.Lock ||
+ RotationLock.INSTANCE.getRotationConfig().getRotationMode() != RotationMode.Lock ||
RotationLock.getPitchMode() == RotationLock.RotationMode.None);
}
}
diff --git a/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt b/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt
index 7e8d20b2f..1591a801d 100644
--- a/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt
+++ b/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt
@@ -25,6 +25,7 @@ import com.lambda.brigadier.argument.value
import com.lambda.brigadier.executeWithResult
import com.lambda.brigadier.required
import com.lambda.command.LambdaCommand
+import com.lambda.context.AutomationConfig
import com.lambda.interaction.construction.StructureRegistry
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint
@@ -61,11 +62,13 @@ object BuildCommand : LambdaCommand(
.loadStructureByRelativePath(Path.of(pathString))
.let { template ->
info("Building structure $pathString with dimensions ${template.size.toShortString()} created by ${template.author}")
- lastBuildTask = template.toStructure()
- .move(player.blockPos)
- .toBlueprint()
- .build()
- .run()
+ lastBuildTask = with(AutomationConfig) {
+ template.toStructure()
+ .move(player.blockPos)
+ .toBlueprint()
+ .build()
+ .run()
+ }
return@executeWithResult success()
}
diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt
index 599b54c1f..267c735ee 100644
--- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt
+++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt
@@ -27,6 +27,7 @@ import com.lambda.brigadier.argument.value
import com.lambda.brigadier.executeWithResult
import com.lambda.brigadier.required
import com.lambda.command.LambdaCommand
+import com.lambda.context.AutomationConfig
import com.lambda.interaction.material.StackSelection.Companion.selectStack
import com.lambda.interaction.material.container.ContainerManager
import com.lambda.interaction.material.container.ContainerManager.containerWithMaterial
@@ -52,8 +53,10 @@ object TransferCommand : LambdaCommand(
val selection = selectStack(count) {
isItem(stack(ctx).value().item)
}
- selection.containerWithMaterial().forEachIndexed { i, container ->
- builder.suggest("\"${i + 1}. ${container.name}\"", container.description(selection))
+ with(AutomationConfig) {
+ selection.containerWithMaterial().forEachIndexed { i, container ->
+ builder.suggest("\"${i + 1}. ${container.name}\"", container.description(selection))
+ }
}
builder.buildFuture()
}
@@ -62,8 +65,10 @@ object TransferCommand : LambdaCommand(
val selection = selectStack(amount(ctx).value()) {
isItem(stack(ctx).value().item)
}
- containerWithSpace(selection).forEachIndexed { i, container ->
- builder.suggest("\"${i + 1}. ${container.name}\"", container.description(selection))
+ with(AutomationConfig) {
+ containerWithSpace(selection).forEachIndexed { i, container ->
+ builder.suggest("\"${i + 1}. ${container.name}\"", container.description(selection))
+ }
}
builder.buildFuture()
}
@@ -79,22 +84,24 @@ object TransferCommand : LambdaCommand(
it.name == to().value().split(".").last().trim()
} ?: return@executeWithResult failure("To container not found")
- when (val transaction = fromContainer.transfer(selection, toContainer)) {
- is TransferResult.ContainerTransfer -> {
- info("${transaction.name} started.")
- lastContainerTransfer = transaction
- transaction.finally {
- info("${transaction.name} completed.")
- }.run()
- return@executeWithResult success()
- }
+ with(AutomationConfig) {
+ when (val transaction = fromContainer.transfer(selection, toContainer)) {
+ is TransferResult.ContainerTransfer -> {
+ info("${transaction.name} started.")
+ lastContainerTransfer = transaction
+ transaction.finally {
+ info("${transaction.name} completed.")
+ }.run()
+ return@executeWithResult success()
+ }
- is TransferResult.MissingItems -> {
- return@executeWithResult failure("Missing items: ${transaction.missing}")
- }
+ is TransferResult.MissingItems -> {
+ return@executeWithResult failure("Missing items: ${transaction.missing}")
+ }
- is TransferResult.NoSpace -> {
- return@executeWithResult failure("No space in ${toContainer.name}")
+ is TransferResult.NoSpace -> {
+ return@executeWithResult failure("No space in ${toContainer.name}")
+ }
}
}
diff --git a/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt b/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt
index 44820c364..4e8c70271 100644
--- a/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt
+++ b/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt
@@ -30,13 +30,13 @@ interface BuildConfig {
val interactionTimeout: Int
// Breaking
- val breaking: BreakSettings
+ val breakConfig: BreakSettings
// Placing
- val placing: PlaceSettings
+ val placeConfig: PlaceSettings
// Interacting
- val interacting: InteractSettings
+ val interactConfig: InteractSettings
enum class SwingType(
override val displayName: String,
diff --git a/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt b/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt
index 736ffd2be..c7d537870 100644
--- a/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt
+++ b/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt
@@ -42,17 +42,17 @@ class BuildSettings(
override val maxPendingInteractions by c.setting("Max Pending Interactions", 15, 1..30, 1, "The maximum count of pending interactions to allow before pausing future interactions", visibility = vis).group(*groupPath, Group.General)
// Breaking
- override val breaking = BreakSettings(c, groupPath.toList() + Group.Break, vis)
+ override val breakConfig = BreakSettings(c, groupPath.toList() + Group.Break, vis)
// Placing
- override val placing = PlaceSettings(c, groupPath.toList() + Group.Place, vis)
+ override val placeConfig = PlaceSettings(c, groupPath.toList() + Group.Place, vis)
//Interacting
- override val interacting = InteractSettings(c, groupPath.toList() + Group.Interact, vis)
+ override val interactConfig = InteractSettings(c, groupPath.toList() + Group.Interact, vis)
override val interactionTimeout by c.setting("Interaction Timeout", 10, 1..30, 1, "Timeout for block breaks in ticks", unit = " ticks") {
- vis() && (placing.placeConfirmationMode != PlaceConfig.PlaceConfirmationMode.None
- || breaking.breakConfirmation != BreakConfirmationMode.None
- || interacting.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.None)
+ vis() && (placeConfig.placeConfirmationMode != PlaceConfig.PlaceConfirmationMode.None
+ || breakConfig.breakConfirmation != BreakConfirmationMode.None
+ || interactConfig.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.None)
}.group(*groupPath, Group.Break, BreakSettings.Group.General).group(*groupPath, Group.Place).group(*groupPath, Group.Interact)
}
diff --git a/src/main/kotlin/com/lambda/config/groups/EatConfig.kt b/src/main/kotlin/com/lambda/config/groups/EatConfig.kt
index 6088fda4d..bfc044896 100644
--- a/src/main/kotlin/com/lambda/config/groups/EatConfig.kt
+++ b/src/main/kotlin/com/lambda/config/groups/EatConfig.kt
@@ -17,7 +17,8 @@
package com.lambda.config.groups
-import com.lambda.context.SafeContext
+import com.lambda.context.Automated
+import com.lambda.context.AutomatedSafeContext
import com.lambda.interaction.material.StackSelection.Companion.selectStack
import com.lambda.threading.runSafe
import com.lambda.util.Describable
@@ -77,10 +78,11 @@ interface EatConfig {
fun shouldEat() = this != None
- fun shouldKeepEating(config: EatConfig, stack: ItemStack?) = runSafe {
+ context(c: Automated)
+ fun shouldKeepEating(stack: ItemStack?) = runSafe {
if (stack == null || stack.isEmpty) return@runSafe false
when(this@Reason) {
- Hunger -> when(config.saturated) {
+ Hunger -> when(c.eatConfig.saturated) {
Saturation.EatSmart -> stack.item.nutrition + player.hungerManager.foodLevel <= 20
Saturation.EatUntilFull -> player.hungerManager.isNotFull
}
@@ -90,21 +92,22 @@ interface EatConfig {
}
} ?: false
- fun selector(config: EatConfig) = selectStack(sorter = config.selectionPriority.comparator) {
+ context(c: Automated)
+ fun selector() = selectStack(sorter = c.eatConfig.selectionPriority.comparator) {
when(this@Reason) {
None -> any()
- Hunger -> isOneOfItems(config.nutritiousFood)
- Damage -> isOneOfItems(config.regenerationFood)
- Fire -> isOneOfItems(config.resistanceFood)
- } and if (config.ignoreBadFood) isNoneOfItems(config.badFood) else any()
+ Hunger -> isOneOfItems(c.eatConfig.nutritiousFood)
+ Damage -> isOneOfItems(c.eatConfig.regenerationFood)
+ Fire -> isOneOfItems(c.eatConfig.resistanceFood)
+ } and if (c.eatConfig.ignoreBadFood) isNoneOfItems(c.eatConfig.badFood) else any()
}
}
companion object {
- fun SafeContext.reasonEating(config: EatConfig) = when {
- config.eatOnHunger && player.hungerManager.foodLevel <= config.minFoodLevel -> Reason.Hunger
- config.eatOnDamage && player.health <= config.minDamage && !player.hasStatusEffect(StatusEffects.REGENERATION) -> Reason.Damage
- config.eatOnFire && player.isOnFire && !player.hasStatusEffect(StatusEffects.FIRE_RESISTANCE) -> Reason.Fire
+ fun AutomatedSafeContext.reasonEating() = when {
+ eatConfig.eatOnHunger && player.hungerManager.foodLevel <= eatConfig.minFoodLevel -> Reason.Hunger
+ eatConfig.eatOnDamage && player.health <= eatConfig.minDamage && !player.hasStatusEffect(StatusEffects.REGENERATION) -> Reason.Damage
+ eatConfig.eatOnFire && player.isOnFire && !player.hasStatusEffect(StatusEffects.FIRE_RESISTANCE) -> Reason.Fire
else -> Reason.None
}
}
diff --git a/src/main/kotlin/com/lambda/context/AbstractContext.kt b/src/main/kotlin/com/lambda/context/AbstractContext.kt
deleted file mode 100644
index dfaf10d57..000000000
--- a/src/main/kotlin/com/lambda/context/AbstractContext.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2025 Lambda
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.lambda.context
-
-import net.minecraft.client.MinecraftClient
-import net.minecraft.client.network.ClientPlayNetworkHandler
-import net.minecraft.client.network.ClientPlayerEntity
-import net.minecraft.client.network.ClientPlayerInteractionManager
-import net.minecraft.client.world.ClientWorld
-
-/**
- * Representing an abstract context in the [MinecraftClient].
- *
- * @property mc The Minecraft client instance.
- * @property world The world in which the player is currently located, or `null` if the world is not available.
- * @property player The player entity, or `null` if the player is not available.
- * @property interaction The interaction manager for the player, or `null` if the interaction manager is not available.
- * @property connection The network handler for the player, or `null` if the network handler is not available.
- */
-abstract class AbstractContext {
- val mc: MinecraftClient = MinecraftClient.getInstance()
- abstract val world: ClientWorld?
- abstract val player: ClientPlayerEntity?
- abstract val interaction: ClientPlayerInteractionManager?
- abstract val connection: ClientPlayNetworkHandler?
-}
diff --git a/src/main/kotlin/com/lambda/context/Automated.kt b/src/main/kotlin/com/lambda/context/Automated.kt
new file mode 100644
index 000000000..0cbbeea57
--- /dev/null
+++ b/src/main/kotlin/com/lambda/context/Automated.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.context
+
+import com.lambda.config.groups.BuildConfig
+import com.lambda.config.groups.EatConfig
+import com.lambda.config.groups.InteractionConfig
+import com.lambda.interaction.request.hotbar.HotbarConfig
+import com.lambda.interaction.request.inventory.InventoryConfig
+import com.lambda.interaction.request.rotating.RotationConfig
+
+interface Automated {
+ val buildConfig: BuildConfig
+ val rotationConfig: RotationConfig
+ val interactionConfig: InteractionConfig
+ val inventoryConfig: InventoryConfig
+ val hotbarConfig: HotbarConfig
+ val eatConfig: EatConfig
+}
+
+val Automated.breakConfig get() = buildConfig.breakConfig
+val Automated.placeConfig get() = buildConfig.placeConfig
+val Automated.interactConfig get() = buildConfig.interactConfig
\ No newline at end of file
diff --git a/src/main/kotlin/com/lambda/context/AutomatedSafeContext.kt b/src/main/kotlin/com/lambda/context/AutomatedSafeContext.kt
new file mode 100644
index 000000000..0969ace69
--- /dev/null
+++ b/src/main/kotlin/com/lambda/context/AutomatedSafeContext.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.context
+
+class AutomatedSafeContext(
+ safeContext: SafeContext,
+ automated: Automated
+) : SafeContext by safeContext, Automated by automated
\ No newline at end of file
diff --git a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt b/src/main/kotlin/com/lambda/context/AutomationConfig.kt
similarity index 68%
rename from src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt
rename to src/main/kotlin/com/lambda/context/AutomationConfig.kt
index 80c7e92e2..d6d78cd51 100644
--- a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt
+++ b/src/main/kotlin/com/lambda/context/AutomationConfig.kt
@@ -15,8 +15,10 @@
* along with this program. If not, see .
*/
-package com.lambda.module.modules.client
+package com.lambda.context
+import com.lambda.config.Configurable
+import com.lambda.config.configurations.LambdaConfig
import com.lambda.config.groups.BuildSettings
import com.lambda.config.groups.EatSettings
import com.lambda.config.groups.HotbarSettings
@@ -24,18 +26,13 @@ import com.lambda.config.groups.InteractionSettings
import com.lambda.config.groups.InventorySettings
import com.lambda.config.groups.RotationSettings
import com.lambda.event.events.onStaticRender
-import com.lambda.interaction.construction.result.BuildResult
import com.lambda.interaction.construction.result.Drawable
-import com.lambda.module.Module
-import com.lambda.module.tag.ModuleTag
import com.lambda.util.NamedEnum
import com.lambda.util.world.raycast.InteractionMask
-object TaskFlowModule : Module(
- name = "TaskFlow",
- description = "Settings for task automation",
- tag = ModuleTag.CLIENT,
-) {
+object AutomationConfig : Configurable(LambdaConfig), Automated {
+ override val name = "automation"
+
enum class Group(override val displayName: String) : NamedEnum {
Build("Build"),
Rotation("Rotation"),
@@ -43,15 +40,18 @@ object TaskFlowModule : Module(
Inventory("Inventory"),
Hotbar("Hotbar"),
Eat("Eat"),
+ Render("Render"),
Debug("Debug")
}
- val build = BuildSettings(this, Group.Build)
- val rotation = RotationSettings(this, Group.Rotation)
- val interaction = InteractionSettings(this, Group.Interaction, InteractionMask.Both)
- val inventory = InventorySettings(this, Group.Inventory)
- val hotbar = HotbarSettings(this, Group.Hotbar)
- val eat = EatSettings(this, Group.Eat)
+ val renders by setting("Render", false).group(Group.Render)
+
+ override val buildConfig = BuildSettings(this, Group.Build)
+ override val rotationConfig = RotationSettings(this, Group.Rotation)
+ override val interactionConfig = InteractionSettings(this, Group.Interaction, InteractionMask.Both)
+ override val inventoryConfig = InventorySettings(this, Group.Inventory)
+ override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
+ override val eatConfig = EatSettings(this, Group.Eat)
val showAllEntries by setting("Show All Entries", false, "Show all entries in the task tree").group(Group.Debug)
val shrinkFactor by setting("Shrink Factor", 0.001, 0.0..1.0, 0.001).group(Group.Debug)
@@ -62,7 +62,8 @@ object TaskFlowModule : Module(
init {
onStaticRender {
- with(it) { drawables.forEach { with(it) { buildRenderer() } } }
+ if (renders)
+ with(it) { drawables.forEach { with(it) { buildRenderer() } } }
}
}
-}
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lambda/context/ClientContext.kt b/src/main/kotlin/com/lambda/context/ClientContext.kt
deleted file mode 100644
index 636fd681c..000000000
--- a/src/main/kotlin/com/lambda/context/ClientContext.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2025 Lambda
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.lambda.context
-
-import net.minecraft.client.MinecraftClient
-import net.minecraft.client.network.ClientPlayNetworkHandler
-import net.minecraft.client.network.ClientPlayerEntity
-import net.minecraft.client.network.ClientPlayerInteractionManager
-import net.minecraft.client.world.ClientWorld
-
-/**
- * A class extending the [AbstractContext] in the [MinecraftClient].
- * This is considered the "unsafe" variant of the contexts as the properties can be null.
- * Methods in this context will always need to perform null checks for type safety.
- *
- * @property world The world in which the player is currently located, or `null` if the world is not available.
- * @property player The player entity, or `null` if the player is not available.
- * @property interaction The interaction manager for the player, or `null` if the interaction manager is not available.
- * @property connection The network handler for the player, or `null` if the network handler is not available.
- *
- * @function toSafe Converts the `ClientContext` to a `SafeContext` if all properties are not `null`, or returns `null` otherwise.
- */
-open class ClientContext : AbstractContext() {
- final override val world: ClientWorld? = mc.world
- final override val player: ClientPlayerEntity? = mc.player
- final override val interaction: ClientPlayerInteractionManager? = mc.interactionManager
- final override val connection: ClientPlayNetworkHandler? = mc.networkHandler
-
- fun toSafe(): SafeContext? {
- if (world == null || player == null || interaction == null || connection == null) {
- return null
- }
- return SafeContext(world, player, interaction, connection)
- }
-}
diff --git a/src/main/kotlin/com/lambda/context/SafeContext.kt b/src/main/kotlin/com/lambda/context/SafeContext.kt
index 116f2cc55..379c40bb6 100644
--- a/src/main/kotlin/com/lambda/context/SafeContext.kt
+++ b/src/main/kotlin/com/lambda/context/SafeContext.kt
@@ -17,6 +17,8 @@
package com.lambda.context
+import com.lambda.Lambda
+import com.lambda.Lambda.mc
import net.minecraft.client.MinecraftClient
import net.minecraft.client.network.ClientPlayNetworkHandler
import net.minecraft.client.network.ClientPlayerEntity
@@ -46,9 +48,26 @@ import net.minecraft.client.world.ClientWorld
* @property interaction The interaction manager for the player.
* @property connection The network handler for the player.
**/
-open class SafeContext internal constructor(
- override val world: ClientWorld,
- override val player: ClientPlayerEntity,
- override val interaction: ClientPlayerInteractionManager,
- override val connection: ClientPlayNetworkHandler,
-) : AbstractContext()
+interface SafeContext {
+ val mc: MinecraftClient
+ val world: ClientWorld
+ val player: ClientPlayerEntity
+ val interaction: ClientPlayerInteractionManager
+ val connection: ClientPlayNetworkHandler
+
+ companion object {
+ fun create(): SafeContext? {
+ val world = mc.world ?: return null
+ val player = mc.player ?: return null
+ val interaction = mc.interactionManager ?: return null
+ val connection = mc.networkHandler ?: return null
+ return object : SafeContext {
+ override val mc = Lambda.mc
+ override val world = world
+ override val player = player
+ override val interaction = interaction
+ override val connection = connection
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/com/lambda/event/listener/SafeListener.kt b/src/main/kotlin/com/lambda/event/listener/SafeListener.kt
index 9b5c6f7af..1b8196c21 100644
--- a/src/main/kotlin/com/lambda/event/listener/SafeListener.kt
+++ b/src/main/kotlin/com/lambda/event/listener/SafeListener.kt
@@ -65,7 +65,7 @@ class SafeListener(
override val priority: Int = 0,
override val owner: Any,
override val alwaysListen: Boolean = false,
- val function: SafeContext.(T) -> Unit,
+ val function: SafeContext.(T) -> Unit
) : Listener(), ReadOnlyProperty {
/**
* The last processed event signal.
diff --git a/src/main/kotlin/com/lambda/event/listener/UnsafeListener.kt b/src/main/kotlin/com/lambda/event/listener/UnsafeListener.kt
index 5c1410c36..15c3cf325 100644
--- a/src/main/kotlin/com/lambda/event/listener/UnsafeListener.kt
+++ b/src/main/kotlin/com/lambda/event/listener/UnsafeListener.kt
@@ -17,7 +17,6 @@
package com.lambda.event.listener
-import com.lambda.context.SafeContext
import com.lambda.event.Event
import com.lambda.event.EventFlow
import com.lambda.event.Muteable
diff --git a/src/main/kotlin/com/lambda/gui/MenuBar.kt b/src/main/kotlin/com/lambda/gui/MenuBar.kt
index a555db6c3..919fa6c9c 100644
--- a/src/main/kotlin/com/lambda/gui/MenuBar.kt
+++ b/src/main/kotlin/com/lambda/gui/MenuBar.kt
@@ -22,6 +22,7 @@ import com.lambda.Lambda.REPO_URL
import com.lambda.Lambda.mc
import com.lambda.command.CommandRegistry
import com.lambda.config.Configuration
+import com.lambda.context.AutomationConfig
import com.lambda.core.Loader
import com.lambda.event.EventFlow
import com.lambda.graphics.texture.TextureOwner.upload
@@ -35,7 +36,6 @@ import com.lambda.interaction.BaritoneManager
import com.lambda.module.ModuleRegistry
import com.lambda.module.tag.ModuleTag
import com.lambda.network.LambdaAPI
-import com.lambda.network.NetworkManager
import com.lambda.threading.runSafe
import com.lambda.util.Communication.info
import com.lambda.util.Diagnostics.gatherDiagnostics
@@ -50,7 +50,7 @@ import imgui.flag.ImGuiWindowFlags
import net.fabricmc.loader.api.FabricLoader
import net.minecraft.util.Util
import net.minecraft.world.GameMode
-import java.util.Locale
+import java.util.*
object MenuBar {
private var aboutRequested = false
@@ -141,6 +141,9 @@ object MenuBar {
menu("Baritone Settings") {
buildConfigSettingsContext(BaritoneManager)
}
+ menu("Automation Settings") {
+ buildConfigSettingsContext(AutomationConfig)
+ }
}
separator()
menu("Open Folder") {
diff --git a/src/main/kotlin/com/lambda/interaction/BaritoneManager.kt b/src/main/kotlin/com/lambda/interaction/BaritoneManager.kt
index 659059258..917453404 100644
--- a/src/main/kotlin/com/lambda/interaction/BaritoneManager.kt
+++ b/src/main/kotlin/com/lambda/interaction/BaritoneManager.kt
@@ -24,10 +24,12 @@ import baritone.api.pathing.goals.Goal
import com.lambda.config.Configurable
import com.lambda.config.configurations.LambdaConfig
import com.lambda.config.groups.RotationSettings
+import com.lambda.context.Automated
+import com.lambda.context.AutomationConfig
import com.lambda.util.BlockUtils.blockPos
import com.lambda.util.NamedEnum
-object BaritoneManager : Configurable(LambdaConfig) {
+object BaritoneManager : Configurable(LambdaConfig), Automated by AutomationConfig {
override val name = "baritone"
private val baritone = BaritoneAPI.getProvider()
@@ -66,7 +68,7 @@ object BaritoneManager : Configurable(LambdaConfig) {
Schematic("Schematic")
}
- val rotation: RotationSettings
+ override val rotationConfig = RotationSettings(this@BaritoneManager, Group.Rotation)
init {
// ToDo: Dont actually save the settings as its duplicate data
@@ -97,9 +99,6 @@ object BaritoneManager : Configurable(LambdaConfig) {
setting("Anti Cheat Compatibility", antiCheatCompatibility.value).group(Group.General, SubGroup.Misc).onValueChange { _, it -> antiCheatCompatibility.value = it }
- // ROTATION
- rotation = RotationSettings(this@BaritoneManager, Group.Rotation)
-
// PATHING
setting("Pathing Max Chunk Border Fetch", pathingMaxChunkBorderFetch.value, 0..64).group(Group.Pathing, SubGroup.PathingCore).onValueChange { _, it -> pathingMaxChunkBorderFetch.value = it }
setting("Pathing Map Default Size", pathingMapDefaultSize.value, 0..2048).group(Group.Pathing, SubGroup.PathingCore).onValueChange { _, it -> pathingMapDefaultSize.value = it }
diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt
index cce1f76a3..f08948e4e 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.construction.context
+import com.lambda.context.interactConfig
import com.lambda.graphics.renderer.esp.DirectionMask.mask
import com.lambda.graphics.renderer.esp.ShapeBuilder
import com.lambda.interaction.request.LogContext
@@ -67,8 +68,8 @@ class InteractionContext(
}
fun requestDependencies(request: InteractRequest): Boolean {
- val hotbarRequest = submit(HotbarRequest(hotbarIndex, request.hotbar), false)
- val validRotation = if (request.rotate) submit(rotation, false).done else true
+ val hotbarRequest = submit(HotbarRequest(hotbarIndex, request), false)
+ val validRotation = if (request.interactConfig.rotate) submit(rotation, false).done else true
return hotbarRequest.done && validRotation
}
diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt
index 61f11a486..b81db31e6 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt
@@ -18,6 +18,8 @@
package com.lambda.interaction.construction.context
import com.lambda.Lambda.mc
+import com.lambda.context.Automated
+import com.lambda.context.placeConfig
import com.lambda.graphics.renderer.esp.DirectionMask.mask
import com.lambda.graphics.renderer.esp.ShapeBuilder
import com.lambda.interaction.request.LogContext
@@ -43,8 +45,9 @@ data class PlaceContext(
override val expectedState: BlockState,
val sneak: Boolean,
val insideBlock: Boolean,
- val currentDirIsValid: Boolean = false
-) : BuildContext(), LogContext {
+ val currentDirIsValid: Boolean = false,
+ private val automated: Automated
+) : BuildContext(), LogContext, Automated by automated {
private val baseColor = Color(35, 188, 254, 25)
private val sideColor = Color(35, 188, 254, 100)
@@ -76,8 +79,8 @@ data class PlaceContext(
}
fun requestDependencies(request: PlaceRequest): Boolean {
- val hotbarRequest = submit(HotbarRequest(hotbarIndex, request.hotbar), false)
- val validRotation = if (request.rotateForPlace) {
+ val hotbarRequest = submit(HotbarRequest(hotbarIndex, this), false)
+ val validRotation = if (request.placeConfig.rotateForPlace) {
submit(rotation, false).done && currentDirIsValid
} else true
return hotbarRequest.done && validRotation
diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt
index 58092620a..b7b8ef340 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt
@@ -19,6 +19,7 @@ package com.lambda.interaction.construction.result
import baritone.api.pathing.goals.GoalBlock
import baritone.api.pathing.goals.GoalInverted
+import com.lambda.context.Automated
import com.lambda.graphics.renderer.esp.DirectionMask.mask
import com.lambda.graphics.renderer.esp.ShapeBuilder
import com.lambda.interaction.construction.context.BreakContext
@@ -26,7 +27,6 @@ import com.lambda.interaction.material.StackSelection.Companion.selectStack
import com.lambda.interaction.material.container.ContainerManager.transfer
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.interaction.material.container.containers.MainHandContainer
-import com.lambda.interaction.request.inventory.InventoryConfig
import net.minecraft.block.BlockState
import net.minecraft.item.Item
import net.minecraft.util.math.BlockPos
@@ -89,23 +89,23 @@ sealed class BreakResult : BuildResult() {
data class ItemCantMine(
override val blockPos: BlockPos,
val blockState: BlockState,
- val badItem: Item,
- val inventory: InventoryConfig
+ val badItem: Item
) : Drawable, Resolvable, BreakResult() {
override val rank = Rank.BREAK_ITEM_CANT_MINE
private val color = Color(255, 0, 0, 100)
override val pausesParent get() = true
+ context(automated: Automated)
override fun resolve() =
selectStack {
isItem(badItem).not()
}.let { selection ->
- selection.transfer(MainHandContainer, inventory)
+ selection.transfer(MainHandContainer)
?: MaterialContainer.AwaitItemTask(
"Couldn't find a tool for ${blockState.block.name.string} with $badItem in main hand.",
selection,
- inventory
+ automated
)
}
diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt
index bd00f9e5c..9b2c98e7e 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt
@@ -19,6 +19,7 @@ package com.lambda.interaction.construction.result
import baritone.api.pathing.goals.GoalBlock
import baritone.api.pathing.goals.GoalNear
+import com.lambda.context.Automated
import com.lambda.graphics.renderer.esp.ShapeBuilder
import com.lambda.interaction.construction.context.BuildContext
import com.lambda.interaction.material.StackSelection
@@ -26,7 +27,6 @@ import com.lambda.interaction.material.StackSelection.Companion.select
import com.lambda.interaction.material.container.ContainerManager.transfer
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.interaction.material.container.containers.MainHandContainer
-import com.lambda.interaction.request.inventory.InventoryConfig
import com.lambda.util.Nameable
import net.minecraft.block.BlockState
import net.minecraft.item.ItemStack
@@ -194,8 +194,7 @@ abstract class BuildResult : ComparableResult, Nameable {
override val blockPos: BlockPos,
val context: BuildContext,
val neededSelection: StackSelection,
- val currentItem: ItemStack,
- val inventory: InventoryConfig
+ val currentItem: ItemStack
) : Drawable, Resolvable, BuildResult() {
override val name: String get() = "Wrong item ($currentItem) for ${blockPos.toShortString()} need $neededSelection"
override val rank = Rank.WRONG_ITEM
@@ -203,12 +202,13 @@ abstract class BuildResult : ComparableResult, Nameable {
override val pausesParent get() = true
+ context(automated: Automated)
override fun resolve() =
- neededSelection.transfer(MainHandContainer, inventory)
+ neededSelection.transfer(MainHandContainer)
?: MaterialContainer.AwaitItemTask(
"Couldn't find $neededSelection anywhere.",
neededSelection,
- inventory
+ automated
)
override fun ShapeBuilder.buildRenderer() {
@@ -231,8 +231,7 @@ abstract class BuildResult : ComparableResult, Nameable {
data class WrongStack(
override val blockPos: BlockPos,
val context: BuildContext,
- val neededStack: ItemStack,
- val inventory: InventoryConfig
+ val neededStack: ItemStack
) : Drawable, Resolvable, BuildResult() {
override val name: String get() = "Wrong stack for ${blockPos.toShortString()} need $neededStack."
override val rank = Rank.WRONG_ITEM
@@ -240,13 +239,14 @@ abstract class BuildResult : ComparableResult, Nameable {
override val pausesParent get() = true
+ context(automated: Automated)
override fun resolve() =
neededStack.select().let { selection ->
- selection.transfer(MainHandContainer, inventory)
+ selection.transfer(MainHandContainer)
?: MaterialContainer.AwaitItemTask(
"Couldn't find ${neededStack.item.name.string} anywhere.",
selection,
- inventory
+ automated
)
}
diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt
index e70102e26..6b05538d4 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt
@@ -17,7 +17,6 @@
package com.lambda.interaction.construction.result
-import com.lambda.context.SafeContext
import com.lambda.graphics.renderer.esp.ShapeBuilder
import com.lambda.interaction.construction.context.InteractionContext
import net.minecraft.util.math.BlockPos
diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt
index 067eb08e7..4cfd034a0 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt
@@ -19,7 +19,7 @@ package com.lambda.interaction.construction.result
import baritone.api.pathing.goals.GoalBlock
import baritone.api.pathing.goals.GoalInverted
-import com.lambda.context.SafeContext
+import com.lambda.context.Automated
import com.lambda.graphics.renderer.esp.ShapeBuilder
import com.lambda.interaction.construction.context.PlaceContext
import com.lambda.task.tasks.BuildTask.Companion.breakBlock
@@ -109,7 +109,8 @@ sealed class PlaceResult : BuildResult() {
) : Resolvable, PlaceResult() {
override val rank = Rank.PLACE_CANT_REPLACE
- override fun resolve() = breakBlock(blockPos)
+ context(automated: Automated)
+ override fun resolve() = automated.breakBlock(blockPos)
}
/**
diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt b/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt
index 91f9c529f..951256cb0 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt
@@ -17,8 +17,10 @@
package com.lambda.interaction.construction.result
+import com.lambda.context.Automated
import com.lambda.task.Task
interface Resolvable {
+ context(automated: Automated)
fun resolve(): Task<*>
}
diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt
index 46c5258ce..cda8fe558 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt
@@ -17,9 +17,9 @@
package com.lambda.interaction.construction.simulation
-import com.lambda.config.groups.BuildConfig
-import com.lambda.config.groups.InteractionConfig
-import com.lambda.context.SafeContext
+import com.lambda.context.AutomatedSafeContext
+import com.lambda.context.breakConfig
+import com.lambda.context.placeConfig
import com.lambda.interaction.construction.blueprint.Blueprint
import com.lambda.interaction.construction.context.BreakContext
import com.lambda.interaction.construction.context.InteractionContext
@@ -37,12 +37,8 @@ import com.lambda.interaction.material.StackSelection.Companion.select
import com.lambda.interaction.material.StackSelection.Companion.selectStack
import com.lambda.interaction.material.container.ContainerManager.containerWithMaterial
import com.lambda.interaction.material.container.MaterialContainer
-import com.lambda.interaction.request.breaking.BreakConfig
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.interaction.request.placing.PlaceConfig
import com.lambda.interaction.request.rotating.Rotation.Companion.rotation
import com.lambda.interaction.request.rotating.Rotation.Companion.rotationTo
-import com.lambda.interaction.request.rotating.RotationConfig
import com.lambda.interaction.request.rotating.RotationManager
import com.lambda.interaction.request.rotating.RotationRequest
import com.lambda.interaction.request.rotating.visibilty.PlaceDirection
@@ -52,8 +48,6 @@ import com.lambda.interaction.request.rotating.visibilty.VisibilityChecker.scanS
import com.lambda.interaction.request.rotating.visibilty.lookAt
import com.lambda.interaction.request.rotating.visibilty.lookAtBlock
import com.lambda.interaction.request.rotating.visibilty.lookInDirection
-import com.lambda.module.modules.client.TaskFlowModule
-import com.lambda.threading.runSafe
import com.lambda.util.BlockUtils
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta
@@ -104,30 +98,27 @@ import net.minecraft.util.shape.VoxelShapes
import kotlin.math.pow
object BuildSimulator {
- fun Blueprint.simulate(
- eye: Vec3d,
- interactionConfig: InteractionConfig = TaskFlowModule.interaction,
- rotation: RotationConfig = TaskFlowModule.rotation,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- build: BuildConfig = TaskFlowModule.build,
- ): Set = runSafe {
+ context(context: AutomatedSafeContext)
+ fun Blueprint.simulate(eye: Vec3d): Set =
runBlocking(Dispatchers.Default) {
structure.entries
.map { (pos, target) ->
async {
val preProcessing = target.getProcessingInfo(pos) ?: return@async emptySet()
- checkRequirements(pos, target, build).let { results ->
- if (results.isNotEmpty()) return@async results
- }
- checkPostProcessResults(pos, eye, preProcessing, target, interactionConfig, build.placing, rotation, inventory).let { results ->
- if (results.isNotEmpty()) return@async results
- }
- checkPlaceResults(pos, eye, preProcessing, target, build.placing, interactionConfig, rotation, inventory).let { results ->
- if (results.isNotEmpty()) return@async results
- }
- checkBreakResults(pos, eye, preProcessing, build.breaking, interactionConfig, rotation, inventory, build).let { results ->
- if (results.isNotEmpty()) return@async results
+ with(context) {
+ checkRequirements(pos, target).let { results ->
+ if (results.isNotEmpty()) return@async results
+ }
+ checkPostProcessResults(pos, eye, preProcessing, target).let { results ->
+ if (results.isNotEmpty()) return@async results
+ }
+ checkPlaceResults(pos, eye, preProcessing, target).let { results ->
+ if (results.isNotEmpty()) return@async results
+ }
+ checkBreakResults(pos, eye, preProcessing).let { results ->
+ if (results.isNotEmpty()) return@async results
+ }
}
warn("Nothing matched $pos $target")
@@ -138,13 +129,8 @@ object BuildSimulator {
.flatMap { it }
.toSet()
}
- } ?: emptySet()
- private fun SafeContext.checkRequirements(
- pos: BlockPos,
- target: TargetState,
- build: BuildConfig
- ): Set {
+ private fun AutomatedSafeContext.checkRequirements(pos: BlockPos, target: TargetState): Set {
val acc = mutableSetOf()
/* the chunk is not loaded */
@@ -162,7 +148,7 @@ object BuildSimulator {
}
/* block should be ignored */
- if (state.block in build.breaking.ignoredBlocks && target.type == TargetState.Type.AIR) {
+ if (state.block in breakConfig.ignoredBlocks && target.type == TargetState.Type.AIR) {
acc.add(BuildResult.Ignored(pos))
return acc
}
@@ -194,15 +180,11 @@ object BuildSimulator {
return acc
}
- private fun SafeContext.checkPostProcessResults(
+ private fun AutomatedSafeContext.checkPostProcessResults(
pos: BlockPos,
eye: Vec3d,
preProcessing: PreProcessingInfo,
- targetState: TargetState,
- interactionConfig: InteractionConfig,
- place: PlaceConfig,
- rotation: RotationConfig,
- inventory: InventoryConfig
+ targetState: TargetState
): Set {
if (targetState !is TargetState.State) return emptySet()
@@ -213,12 +195,12 @@ object BuildSimulator {
return acc
val interactBlock: (BlockState, Set?, Item?, Boolean) -> Unit =
- interactBlock@{ expectedState, sides, item, placing ->
+ interactBlock@ { expectedState, sides, item, placing ->
val boxes = state.getOutlineShape(world, pos).boundingBoxes.map { it.offset(pos) }
val validHits = mutableListOf()
val blockedHits = mutableSetOf()
val misses = mutableSetOf()
- val airPlace = placing && place.airPlace.isEnabled
+ val airPlace = placing && placeConfig.airPlace.isEnabled
boxes.forEach { box ->
val refinedSides = if (interactionConfig.checkSideVisibility) {
@@ -293,7 +275,7 @@ object BuildSimulator {
val rotationTarget = lookAt(checkedHit.targetRotation, 0.001)
val context = InteractionContext(
checkedResult.blockResult ?: return@interactBlock,
- RotationRequest(rotationTarget, rotation),
+ RotationRequest(rotationTarget, this),
player.inventory.selectedSlot,
state,
expectedState
@@ -303,7 +285,7 @@ object BuildSimulator {
val hotbarCandidates = selectContainer {
matches(stackSelection) and ofAnyType(MaterialContainer.Rank.HOTBAR)
}.let { predicate ->
- stackSelection.containerWithMaterial(inventory, predicate)
+ stackSelection.containerWithMaterial( predicate)
}
if (hotbarCandidates.isEmpty()) {
@@ -312,8 +294,7 @@ object BuildSimulator {
pos,
context,
stackSelection,
- player.mainHandStack,
- inventory
+ player.mainHandStack
)
)
return@interactBlock
@@ -365,11 +346,7 @@ object BuildSimulator {
pos,
eye,
preProcessing,
- targetState,
- place,
- interactionConfig,
- rotation,
- inventory
+ targetState
).let { placeResults ->
acc.addAll(placeResults)
}
@@ -384,15 +361,11 @@ object BuildSimulator {
return acc
}
- private fun SafeContext.checkPlaceResults(
+ private fun AutomatedSafeContext.checkPlaceResults(
pos: BlockPos,
eye: Vec3d,
preProcessing: PreProcessingInfo,
- targetState: TargetState,
- place: PlaceConfig,
- interactionConfig: InteractionConfig,
- rotation: RotationConfig,
- inventory: InventoryConfig
+ targetState: TargetState
): Set {
val acc = mutableSetOf()
val currentState = blockState(pos)
@@ -411,13 +384,13 @@ object BuildSimulator {
if (!currentState.isReplaceable && !statePromoting) return acc
preProcessing.sides.forEach { neighbor ->
- val hitPos = if (!place.airPlace.isEnabled && (currentState.isAir || statePromoting))
+ val hitPos = if (!placeConfig.airPlace.isEnabled && (currentState.isAir || statePromoting))
pos.offset(neighbor) else pos
val hitSide = neighbor.opposite
if (!world.worldBorder.contains(hitPos)) return@forEach
val voxelShape = blockState(hitPos).getOutlineShape(world, hitPos).let { outlineShape ->
- if (!outlineShape.isEmpty || !place.airPlace.isEnabled) outlineShape
+ if (!outlineShape.isEmpty || !placeConfig.airPlace.isEnabled) outlineShape
else VoxelShapes.fullCube()
}
if (voxelShape.isEmpty) return@forEach
@@ -448,10 +421,10 @@ object BuildSimulator {
val hit = if (interactionConfig.strictRayCast) {
val rayCast = newRotation.rayCast(interactionConfig.interactReach, eye)
when {
- rayCast != null && (!place.airPlace.isEnabled || eye distSq rayCast.pos <= distSquared) ->
+ rayCast != null && (!placeConfig.airPlace.isEnabled || eye distSq rayCast.pos <= distSquared) ->
rayCast.blockResult
- place.airPlace.isEnabled -> {
+ placeConfig.airPlace.isEnabled -> {
val hitVec = newRotation.castBox(box, interactionConfig.interactReach, eye)
BlockHitResult(hitVec, hitSide, hitPos, false)
}
@@ -481,7 +454,7 @@ object BuildSimulator {
}
interactionConfig.pointSelection.select(validHits)?.let { checkedHit ->
- val optimalStack = nextTargetState.getStack(world, pos, inventory)
+ val optimalStack = nextTargetState.getStack(world, pos, this)
// ToDo: For each hand and sneak or not?
val fakePlayer = copyPlayer(player).apply {
@@ -551,7 +524,7 @@ object BuildSimulator {
}
val currentDirIsValid = simulatePlaceState()?.let { basePlaceResult ->
- if (!place.rotateForPlace) {
+ if (!placeConfig.rotateForPlace) {
acc.add(basePlaceResult)
return@forEach
}
@@ -559,7 +532,7 @@ object BuildSimulator {
} != false
run rotate@{
- if (!place.axisRotate) {
+ if (!placeConfig.axisRotate) {
fakePlayer.rotation = checkedHit.targetRotation
simulatePlaceState()?.let { rotatedPlaceResult ->
acc.add(rotatedPlaceResult)
@@ -601,32 +574,32 @@ object BuildSimulator {
val hitBlock = blockState(blockHit.blockPos).block
val shouldSneak = hitBlock::class in BlockUtils.interactionBlocks
- val rotationRequest = if (place.axisRotate) {
+ val rotationRequest = if (placeConfig.axisRotate) {
lookInDirection(PlaceDirection.fromRotation(rot))
} else lookAt(rot, 0.001)
val placeContext = PlaceContext(
blockHit,
- RotationRequest(rotationRequest, rotation),
+ RotationRequest(rotationRequest, this),
player.inventory.selectedSlot,
context.blockPos,
blockState(context.blockPos),
resultState,
shouldSneak,
false,
- currentDirIsValid
+ currentDirIsValid,
+ this
)
val selection = optimalStack.item.select()
val containerSelection = selectContainer { ofAnyType(MaterialContainer.Rank.HOTBAR) }
- val container = selection.containerWithMaterial(inventory, containerSelection).firstOrNull() ?: run {
+ val container = selection.containerWithMaterial(containerSelection).firstOrNull() ?: run {
acc.add(
BuildResult.WrongItemSelection(
pos,
placeContext,
optimalStack.item.select(),
- player.mainHandStack,
- inventory
+ player.mainHandStack
)
)
return acc
@@ -645,27 +618,22 @@ object BuildSimulator {
return acc
}
- private fun SafeContext.checkBreakResults(
+ private fun AutomatedSafeContext.checkBreakResults(
pos: BlockPos,
eye: Vec3d,
- preProcessing: PreProcessingInfo,
- breaking: BreakConfig,
- interactionConfig: InteractionConfig,
- rotation: RotationConfig,
- inventory: InventoryConfig,
- build: BuildConfig
+ preProcessing: PreProcessingInfo
): Set {
val acc = mutableSetOf()
val state = blockState(pos)
/* is a block that will be destroyed by breaking adjacent blocks */
- if (!breaking.breakWeakBlocks && state.block.hardness == 0f && !state.isAir && state.isNotEmpty) {
+ if (!breakConfig.breakWeakBlocks && state.block.hardness == 0f && !state.isAir && state.isNotEmpty) {
acc.add(BuildResult.Ignored(pos))
return acc
}
/* player is standing on top of the block */
- if (breaking.avoidSupporting) player.supportingBlockPos.orElse(null)?.let { support ->
+ if (breakConfig.avoidSupporting) player.supportingBlockPos.orElse(null)?.let { support ->
if (support != pos) return@let
acc.add(BreakResult.PlayerOnTop(pos, state))
return acc
@@ -673,13 +641,13 @@ object BuildSimulator {
/* liquid needs to be submerged first to be broken */
if (!state.fluidState.isEmpty && state.isReplaceable) {
- val submerge = checkPlaceResults(pos, eye, preProcessing, TargetState.Solid, build.placing, interactionConfig, rotation, inventory)
+ val submerge = checkPlaceResults(pos, eye, preProcessing, TargetState.Solid)
acc.add(BreakResult.Submerge(pos, state, submerge))
acc.addAll(submerge)
return acc
}
- if (breaking.avoidLiquids) {
+ if (breakConfig.avoidLiquids) {
val affectedBlocks = hashSetOf(pos)
val checkQueue = hashSetOf(pos)
@@ -744,7 +712,7 @@ object BuildSimulator {
}
affectedFluids.forEach { (liquidPos, liquidState) ->
- val submerge = checkPlaceResults(liquidPos, eye, preProcessing, TargetState.Solid, build.placing, interactionConfig, rotation, inventory)
+ val submerge = checkPlaceResults(liquidPos, eye, preProcessing, TargetState.Solid)
acc.add(BreakResult.Submerge(liquidPos, liquidState, submerge))
acc.addAll(submerge)
}
@@ -771,16 +739,16 @@ object BuildSimulator {
if (boxes.any { it.contains(eye) }) {
currentCast?.blockResult?.let { blockHit ->
val rotationRequest = RotationRequest(
- lookAtBlock(pos, config = interactionConfig), rotation
+ lookAtBlock(pos), this
)
val breakContext = BreakContext(
blockHit,
rotationRequest,
player.inventory.selectedSlot,
StackSelection.EVERYTHING.select(),
- instantBreakable(state, pos, breaking.breakThreshold),
+ instantBreakable(state, pos, breakConfig.breakThreshold),
state,
- breaking.sorter
+ breakConfig.sorter
)
acc.add(BreakResult.Break(pos, breakContext))
return acc
@@ -827,8 +795,8 @@ object BuildSimulator {
val bestHit = interactionConfig.pointSelection.select(validHits) ?: return acc
val blockHit = bestHit.hit.blockResult ?: return acc
val target = lookAt(bestHit.targetRotation, 0.001)
- val rotationRequest = RotationRequest(target, rotation)
- val instant = instantBreakable(state, pos, breaking.breakThreshold)
+ val rotationRequest = RotationRequest(target, this)
+ val instant = instantBreakable(state, pos, breakConfig.breakThreshold)
val breakContext = BreakContext(
blockHit,
@@ -837,7 +805,7 @@ object BuildSimulator {
StackSelection.EVERYTHING.select(),
instant,
state,
- breaking.sorter
+ breakConfig.sorter
)
if (gamemode.isCreative) {
@@ -852,23 +820,23 @@ object BuildSimulator {
state.calcItemBlockBreakingDelta(player, world, pos, it)
}
) {
- isTool() and if (breaking.suitableToolsOnly) {
+ isTool() and if (breakConfig.suitableToolsOnly) {
isSuitableForBreaking(state)
- } else any() and if (breaking.forceSilkTouch) {
+ } else any() and if (breakConfig.forceSilkTouch) {
hasEnchantment(Enchantments.SILK_TOUCH)
- } else any() and if (breaking.forceFortunePickaxe) {
+ } else any() and if (breakConfig.forceFortunePickaxe) {
hasEnchantment(Enchantments.FORTUNE)
- } else any() and if (!breaking.useWoodenTools) {
+ } else any() and if (!breakConfig.useWoodenTools) {
hasTag(WOODEN_TOOL_MATERIALS).not()
- } else any() and if (!breaking.useStoneTools) {
+ } else any() and if (!breakConfig.useStoneTools) {
hasTag(STONE_TOOL_MATERIALS).not()
- } else any() and if (!breaking.useIronTools) {
+ } else any() and if (!breakConfig.useIronTools) {
hasTag(IRON_TOOL_MATERIALS).not()
- } else any() and if (!breaking.useDiamondTools) {
+ } else any() and if (!breakConfig.useDiamondTools) {
hasTag(DIAMOND_TOOL_MATERIALS).not()
- } else any() and if (!breaking.useGoldTools) {
+ } else any() and if (!breakConfig.useGoldTools) {
hasTag(GOLD_TOOL_MATERIALS).not()
- } else any() and if (!breaking.useNetheriteTools) {
+ } else any() and if (!breakConfig.useNetheriteTools) {
hasTag(NETHERITE_TOOL_MATERIALS).not()
} else any()
}
@@ -877,9 +845,9 @@ object BuildSimulator {
ofAnyType(MaterialContainer.Rank.HOTBAR)
}
- val swapCandidates = stackSelection.containerWithMaterial(inventory, silentSwapSelection)
+ val swapCandidates = stackSelection.containerWithMaterial(silentSwapSelection)
if (swapCandidates.isEmpty()) {
- acc.add(BuildResult.WrongItemSelection(pos, breakContext, stackSelection, player.mainHandStack, inventory))
+ acc.add(BuildResult.WrongItemSelection(pos, breakContext, stackSelection, player.mainHandStack))
return acc
}
@@ -908,8 +876,8 @@ object BuildSimulator {
instantBreak = instantBreakable(
state,
pos,
- if (breaking.swapMode.isEnabled()) swapStack else player.mainHandStack,
- breaking.breakThreshold
+ if (breakConfig.swapMode.isEnabled()) swapStack else player.mainHandStack,
+ breakConfig.breakThreshold
)
}
acc.add(BreakResult.Break(pos, breakContext))
diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt
index 5bf40b099..1fda4fbf8 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt
@@ -17,18 +17,14 @@
package com.lambda.interaction.construction.simulation
-import com.lambda.config.groups.BuildConfig
-import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.graphics.renderer.esp.ShapeBuilder
import com.lambda.interaction.construction.blueprint.Blueprint
import com.lambda.interaction.construction.result.BuildResult
import com.lambda.interaction.construction.result.Drawable
import com.lambda.interaction.construction.simulation.BuildSimulator.simulate
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.interaction.request.rotating.RotationConfig
-import com.lambda.module.modules.client.TaskFlowModule
-import com.lambda.threading.runSafe
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.world.FastVector
import com.lambda.util.world.toBlockPos
@@ -42,11 +38,8 @@ import java.awt.Color
data class Simulation(
val blueprint: Blueprint,
- val interactionConfig: InteractionConfig = TaskFlowModule.interaction,
- val rotation: RotationConfig = TaskFlowModule.rotation,
- val inventory: InventoryConfig = TaskFlowModule.inventory,
- val build: BuildConfig = TaskFlowModule.build,
-) {
+ private val automated: Automated
+) : Automated by automated {
private val cache: MutableMap> = mutableMapOf()
private fun FastVector.toView(): Vec3d = toVec3d().add(0.5, ClientPlayerEntity.DEFAULT_EYE_HEIGHT.toDouble(), 0.5)
@@ -56,15 +49,14 @@ data class Simulation(
val view = pos.toView()
val isOutOfBounds = blueprint.isOutOfBounds(view)
val isTooFar = blueprint.getClosestPointTo(view).distanceTo(view) > 10.0
- runSafe {
+ return runSafeAutomated {
if (isOutOfBounds && isTooFar) return@getOrPut emptySet()
val blockPos = pos.toBlockPos()
val isWalkable = blockState(blockPos.down()).isSideSolidFullSquare(world, blockPos, Direction.UP)
if (!isWalkable) return@getOrPut emptySet()
if (!playerFitsIn(blockPos)) return@getOrPut emptySet()
- }
-
- blueprint.simulate(view, interactionConfig, rotation, inventory, build)
+ blueprint.simulate(view)
+ } ?: emptySet()
}
fun goodPositions() = cache
@@ -84,11 +76,7 @@ data class Simulation(
companion object {
fun Vec3d.playerBox(): Box = Box(x - 0.3, y, z - 0.3, x + 0.3, y + 1.8, z + 0.3).contract(1.0E-6)
- fun Blueprint.simulation(
- interact: InteractionConfig = TaskFlowModule.interaction,
- rotation: RotationConfig = TaskFlowModule.rotation,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- build: BuildConfig = TaskFlowModule.build,
- ) = Simulation(this, interact, rotation, inventory, build)
+ context(c: Automated)
+ fun Blueprint.simulation(automated: Automated = c) = Simulation(this, automated)
}
}
diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt
index 7144bb436..25eab2808 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt
@@ -17,7 +17,7 @@
package com.lambda.interaction.construction.verify
-import com.lambda.interaction.request.inventory.InventoryConfig
+import com.lambda.context.Automated
import net.minecraft.block.BlockState
import net.minecraft.client.world.ClientWorld
import net.minecraft.item.ItemStack
@@ -32,6 +32,6 @@ interface StateMatcher {
ignoredProperties: Collection> = emptySet()
): Boolean
- fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack
+ fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated): ItemStack
fun isEmpty(): Boolean
}
diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt
index 8d1fe9a53..af52771d9 100644
--- a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt
+++ b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt
@@ -17,9 +17,8 @@
package com.lambda.interaction.construction.verify
+import com.lambda.context.Automated
import com.lambda.interaction.material.container.ContainerManager.findDisposable
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.util.BlockUtils.isEmpty
import com.lambda.util.BlockUtils.matches
import com.lambda.util.StringUtils.capitalize
@@ -48,7 +47,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
ignoredProperties: Collection>
) = state.isEmpty
- override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack =
+ override fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated): ItemStack =
ItemStack.EMPTY
override fun isEmpty() = true
@@ -64,7 +63,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
ignoredProperties: Collection>
) = state.isAir
- override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack =
+ override fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated): ItemStack =
ItemStack.EMPTY
override fun isEmpty() = true
@@ -81,10 +80,12 @@ sealed class TargetState(val type: Type) : StateMatcher {
) =
state.isSolidBlock(world, pos)
- override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig) =
- findDisposable(inventory)?.stacks?.firstOrNull {
- it.item.block in TaskFlowModule.inventory.disposables
- } ?: ItemStack(Items.NETHERRACK)
+ override fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated) =
+ with(automated) {
+ findDisposable()?.stacks?.firstOrNull {
+ it.item.block in inventoryConfig.disposables
+ } ?: ItemStack(Items.NETHERRACK)
+ }
override fun isEmpty() = false
}
@@ -101,10 +102,12 @@ sealed class TargetState(val type: Type) : StateMatcher {
world.getBlockState(pos.offset(direction)).isSolidBlock(world, pos.offset(direction))
|| state.isSolidBlock(world, pos)
- override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig) =
- findDisposable()?.stacks?.firstOrNull {
- it.item.block in TaskFlowModule.inventory.disposables
- } ?: ItemStack(Items.NETHERRACK)
+ override fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated) =
+ with(automated) {
+ findDisposable()?.stacks?.firstOrNull {
+ it.item.block in inventoryConfig.disposables
+ } ?: ItemStack(Items.NETHERRACK)
+ }
override fun isEmpty() = false
}
@@ -120,7 +123,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
) =
state.matches(blockState, ignoredProperties)
- override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack =
+ override fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated): ItemStack =
blockState.block.getPickStack(world, pos, blockState, true)
override fun isEmpty() = blockState.isEmpty
@@ -137,7 +140,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
) =
state.block == block
- override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack =
+ override fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated): ItemStack =
block.getPickStack(world, pos, block.defaultState, true)
override fun isEmpty() = block.defaultState.isEmpty
@@ -157,7 +160,7 @@ sealed class TargetState(val type: Type) : StateMatcher {
) =
state.block == block
- override fun getStack(world: ClientWorld, pos: BlockPos, inventory: InventoryConfig): ItemStack =
+ override fun getStack(world: ClientWorld, pos: BlockPos, automated: Automated): ItemStack =
itemStack
override fun isEmpty() = false
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/ContainerManager.kt b/src/main/kotlin/com/lambda/interaction/material/container/ContainerManager.kt
index c022bc7da..598858fb8 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/ContainerManager.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/ContainerManager.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.material.container
+import com.lambda.context.Automated
import com.lambda.core.Loadable
import com.lambda.event.events.InventoryEvent
import com.lambda.event.events.PlayerEvent
@@ -26,8 +27,6 @@ import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.StackSelection.Companion.select
import com.lambda.interaction.material.container.containers.ChestContainer
import com.lambda.interaction.material.container.containers.EnderChestContainer
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.util.BlockUtils.blockEntity
import com.lambda.util.Communication.info
import com.lambda.util.extension.containerStacks
@@ -88,43 +87,43 @@ object ContainerManager : Loadable {
fun container() = container.flatMap { setOf(it) + it.shulkerContainer }.sorted()
- fun StackSelection.transfer(destination: MaterialContainer, inventory: InventoryConfig = TaskFlowModule.inventory) =
- findContainerWithMaterial(inventory)?.transfer(this, destination)
+ context(automated: Automated)
+ fun StackSelection.transfer(destination: MaterialContainer) =
+ findContainerWithMaterial()?.transfer(this, destination)
fun findContainer(
block: (MaterialContainer) -> Boolean,
): MaterialContainer? = container().find(block)
- fun StackSelection.findContainerWithMaterial(
- inventory: InventoryConfig
- ): MaterialContainer? =
- containerWithMaterial(inventory).firstOrNull()
+ context(automated: Automated)
+ fun StackSelection.findContainerWithMaterial(): MaterialContainer? =
+ containerWithMaterial().firstOrNull()
- fun findContainerWithSpace(
- selection: StackSelection,
- ): MaterialContainer? =
+ context(automated: Automated)
+ fun findContainerWithSpace(selection: StackSelection): MaterialContainer? =
containerWithSpace(selection).firstOrNull()
+ context(automated: Automated)
fun StackSelection.containerWithMaterial(
- inventory: InventoryConfig = TaskFlowModule.inventory,
- containerSelection: ContainerSelection = inventory.containerSelection,
+ containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection,
): List =
container()
.filter { it.materialAvailable(this) >= count }
.filter { containerSelection.matches(it) }
- .sortedWith(inventory.providerPriority.materialComparator(this))
+ .sortedWith(automated.inventoryConfig.providerPriority.materialComparator(this))
+ context(automated: Automated)
fun containerWithSpace(
selection: StackSelection,
- inventory: InventoryConfig = TaskFlowModule.inventory,
): List =
container()
.filter { it.spaceAvailable(selection) >= selection.count }
- .filter { inventory.containerSelection.matches(it) }
- .sortedWith(inventory.providerPriority.spaceComparator(selection))
+ .filter { automated.inventoryConfig.containerSelection.matches(it) }
+ .sortedWith(automated.inventoryConfig.providerPriority.spaceComparator(selection))
- fun findDisposable(inventory: InventoryConfig = TaskFlowModule.inventory) = container().find { container ->
- inventory.disposables.any { container.materialAvailable(it.asItem().select()) > 0 }
+ context(automated: Automated)
+ fun findDisposable() = container().find { container ->
+ automated.inventoryConfig.disposables.any { container.materialAvailable(it.asItem().select()) > 0 }
}
class NoContainerFound(selection: StackSelection) : Exception("No container found matching $selection")
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/MaterialContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/MaterialContainer.kt
index f8f3e4170..39de8dfb2 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/MaterialContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/MaterialContainer.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.material.container
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
@@ -24,7 +25,6 @@ import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.ContainerManager.findContainerWithMaterial
import com.lambda.interaction.material.container.containers.ShulkerBoxContainer
import com.lambda.interaction.material.transfer.TransferResult
-import com.lambda.interaction.request.inventory.InventoryConfig
import com.lambda.task.Task
import com.lambda.util.Communication.logError
import com.lambda.util.Nameable
@@ -45,7 +45,7 @@ import net.minecraft.text.Text
// ToDo: Make jsonable to persistently store them
abstract class MaterialContainer(
- val rank: Rank,
+ val rank: Rank
) : Nameable, Comparable {
abstract var stacks: List
abstract val description: Text
@@ -83,7 +83,7 @@ abstract class MaterialContainer(
ShulkerBoxContainer(
stack.shulkerBoxContents,
containedIn = this@MaterialContainer,
- shulkerStack = stack,
+ shulkerStack = stack
)
}.toSet()
@@ -97,11 +97,14 @@ abstract class MaterialContainer(
}
}
- class AwaitItemTask(override val name: String, val selection: StackSelection, inventory: InventoryConfig) :
- Task() {
+ class AwaitItemTask(
+ override val name: String,
+ val selection: StackSelection,
+ automated: Automated
+ ) : Task(), Automated by automated {
init {
listen {
- if (selection.findContainerWithMaterial(inventory) != null) {
+ if (selection.findContainerWithMaterial() != null) {
success()
}
}
@@ -116,12 +119,14 @@ abstract class MaterialContainer(
* Withdraws items from the container to the player's inventory.
*/
@Task.Ta5kBuilder
+ context(automated: Automated)
open fun withdraw(selection: StackSelection): Task<*>? = null
/**
* Deposits items from the player's inventory into the container.
*/
@Task.Ta5kBuilder
+ context(automated: Automated)
open fun deposit(selection: StackSelection): Task<*>? = null
open fun matchingStacks(selection: StackSelection) =
@@ -133,6 +138,7 @@ abstract class MaterialContainer(
open fun spaceAvailable(selection: StackSelection) =
matchingStacks(selection).spaceLeft + stacks.empty * selection.stackSize
+ context(automated: Automated)
fun transfer(selection: StackSelection, destination: MaterialContainer): TransferResult {
val amount = materialAvailable(selection)
if (amount < selection.count) {
@@ -148,7 +154,7 @@ abstract class MaterialContainer(
// selection.selector = { true }
// selection.count = transferAmount
- return TransferResult.ContainerTransfer(selection, from = this, to = destination)
+ return TransferResult.ContainerTransfer(selection, from = this, to = destination, automated)
}
enum class Rank {
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt
index 0c6eec195..dff04c8ad 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.material.container.containers
+import com.lambda.context.Automated
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.interaction.material.transfer.SlotTransfer.Companion.deposit
@@ -27,13 +28,12 @@ import com.lambda.util.text.buildText
import com.lambda.util.text.highlighted
import com.lambda.util.text.literal
import net.minecraft.item.ItemStack
-import net.minecraft.screen.ScreenHandler
import net.minecraft.util.math.BlockPos
data class ChestContainer(
override var stacks: List,
val blockPos: BlockPos,
- val containedInStash: StashContainer? = null,
+ val containedInStash: StashContainer? = null
) : MaterialContainer(Rank.CHEST) {
override val description =
buildText {
@@ -57,20 +57,19 @@ data class ChestContainer(
// }
// }
+ context(automated: Automated)
override fun withdraw(selection: StackSelection) =
- OpenContainer(blockPos)
+ OpenContainer(blockPos, automated)
.then {
info("Withdrawing $selection from ${it.type}")
withdraw(it, selection)
}
+ context(automated: Automated)
override fun deposit(selection: StackSelection) =
- OpenContainer(blockPos)
+ OpenContainer(blockPos, automated)
.then {
info("Depositing $selection to ${it.type}")
deposit(it, selection)
}
-
- class ChestBlockedException : Exception("The chest is blocked by another block or a cat")
- class UnexpectedScreen(screenHandler: ScreenHandler) : Exception("Unexpected screen. Got ${screenHandler.type}")
}
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/CreativeContainer.kt
index c145f80af..44ffbcf1f 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/containers/CreativeContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/containers/CreativeContainer.kt
@@ -18,6 +18,7 @@
package com.lambda.interaction.material.container.containers
import com.lambda.Lambda.mc
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
@@ -61,6 +62,7 @@ data object CreativeContainer : MaterialContainer(Rank.CREATIVE) {
}
}
+ context(automated: Automated)
override fun deposit(selection: StackSelection) = CreativeDeposit(selection)
class CreativeWithdrawal @Ta5kBuilder constructor(val selection: StackSelection) : Task() {
@@ -88,6 +90,7 @@ data object CreativeContainer : MaterialContainer(Rank.CREATIVE) {
}
// Withdraws items from the creative menu to the player's main hand
+ context(automated: Automated)
override fun withdraw(selection: StackSelection) = CreativeWithdrawal(selection)
class NotInCreativeModeException : IllegalStateException("Insufficient permission: not in creative mode")
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt
index 0e8ef3807..34802d3d2 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.material.container.containers
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
@@ -56,6 +57,7 @@ object EnderChestContainer : MaterialContainer(Rank.ENDER_CHEST) {
}
}
+ context(automated: Automated)
override fun withdraw(selection: StackSelection) = EnderchestWithdrawal(selection)
class EnderchestDeposit @Ta5kBuilder constructor(selection: StackSelection) : Task() {
@@ -67,5 +69,6 @@ object EnderChestContainer : MaterialContainer(Rank.ENDER_CHEST) {
}
}
+ context(automated: Automated)
override fun deposit(selection: StackSelection) = EnderchestDeposit(selection)
}
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/HotbarContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/HotbarContainer.kt
index d4b9885df..73b4ea8a1 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/containers/HotbarContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/containers/HotbarContainer.kt
@@ -18,6 +18,7 @@
package com.lambda.interaction.material.container.containers
import com.lambda.Lambda.mc
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.material.ContainerTask
import com.lambda.interaction.material.StackSelection
@@ -35,7 +36,10 @@ object HotbarContainer : MaterialContainer(Rank.HOTBAR) {
override val description = buildText { literal("Hotbar") }
- class HotbarDeposit @Ta5kBuilder constructor(val selection: StackSelection) : ContainerTask() {
+ class HotbarDeposit @Ta5kBuilder constructor(
+ val selection: StackSelection,
+ automated: Automated
+ ) : ContainerTask(), Automated by automated {
override val name: String get() = "Depositing $selection into hotbar"
override fun SafeContext.onStart() {
@@ -46,5 +50,6 @@ object HotbarContainer : MaterialContainer(Rank.HOTBAR) {
}
}
- override fun deposit(selection: StackSelection) = HotbarDeposit(selection)
+ context(automated: Automated)
+ override fun deposit(selection: StackSelection) = HotbarDeposit(selection, automated)
}
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt
index 2dd92fff6..6f8734776 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt
@@ -18,6 +18,7 @@
package com.lambda.interaction.material.container.containers
import com.lambda.Lambda.mc
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.material.ContainerTask
import com.lambda.interaction.material.StackSelection
@@ -74,5 +75,6 @@ object MainHandContainer : MaterialContainer(Rank.MAIN_HAND) {
}
}
+ context(automated: Automated)
override fun deposit(selection: StackSelection) = HandDeposit(selection, Hand.MAIN_HAND)
}
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/OffHandContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/OffHandContainer.kt
index b087e7474..05efb0182 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/containers/OffHandContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/containers/OffHandContainer.kt
@@ -18,6 +18,7 @@
package com.lambda.interaction.material.container.containers
import com.lambda.Lambda.mc
+import com.lambda.context.Automated
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.util.text.buildText
@@ -32,5 +33,6 @@ object OffHandContainer : MaterialContainer(Rank.OFF_HAND) {
override val description = buildText { literal("OffHand") }
+ context(automated: Automated)
override fun deposit(selection: StackSelection) = MainHandContainer.HandDeposit(selection, Hand.OFF_HAND)
}
diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt
index 1e71c839d..af5202296 100644
--- a/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.material.container.containers
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
@@ -50,12 +51,13 @@ data class ShulkerBoxContainer(
class ShulkerWithdraw(
private val selection: StackSelection,
private val shulkerStack: ItemStack,
- ) : Task() {
+ automated: Automated
+ ) : Task(), Automated by automated {
override val name = "Withdraw $selection from ${shulkerStack.name.string}"
override fun SafeContext.onStart() {
- PlaceContainer(shulkerStack).then { placePos ->
- OpenContainer(placePos).then { screen ->
+ PlaceContainer(shulkerStack, this@ShulkerWithdraw).then { placePos ->
+ OpenContainer(placePos, this@ShulkerWithdraw).then { screen ->
withdraw(screen, selection).then {
breakAndCollectBlock(placePos).finally {
success()
@@ -66,17 +68,19 @@ data class ShulkerBoxContainer(
}
}
- override fun withdraw(selection: StackSelection) = ShulkerWithdraw(selection, shulkerStack)
+ context(automated: Automated)
+ override fun withdraw(selection: StackSelection) = ShulkerWithdraw(selection, shulkerStack, automated)
class ShulkerDeposit(
private val selection: StackSelection,
private val shulkerStack: ItemStack,
- ) : Task() {
+ automated: Automated
+ ) : Task(), Automated by automated {
override val name = "Deposit $selection into ${shulkerStack.name.string}"
override fun SafeContext.onStart() {
- PlaceContainer(shulkerStack).then { placePos ->
- OpenContainer(placePos).then { screen ->
+ PlaceContainer(shulkerStack, this@ShulkerDeposit).then { placePos ->
+ OpenContainer(placePos, this@ShulkerDeposit).then { screen ->
deposit(screen, selection).then {
breakAndCollectBlock(placePos).finally {
success()
@@ -87,5 +91,6 @@ data class ShulkerBoxContainer(
}
}
- override fun deposit(selection: StackSelection) = ShulkerDeposit(selection, shulkerStack)
+ context(automated: Automated)
+ override fun deposit(selection: StackSelection) = ShulkerDeposit(selection, shulkerStack, automated)
}
diff --git a/src/main/kotlin/com/lambda/interaction/material/transfer/SlotTransfer.kt b/src/main/kotlin/com/lambda/interaction/material/transfer/SlotTransfer.kt
index c2b816af5..634dcb223 100644
--- a/src/main/kotlin/com/lambda/interaction/material/transfer/SlotTransfer.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/transfer/SlotTransfer.kt
@@ -17,13 +17,12 @@
package com.lambda.interaction.material.transfer
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.transfer.TransactionExecutor.Companion.transfer
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.task.Task
import com.lambda.util.extension.containerSlots
import com.lambda.util.extension.inventorySlots
@@ -37,8 +36,8 @@ class SlotTransfer @Ta5kBuilder constructor(
val from: List,
val to: List,
private val closeScreen: Boolean = true,
- private val config: InventoryConfig = TaskFlowModule.inventory,
-) : Task() {
+ automated: Automated
+) : Task(), Automated by automated {
private var selectedFrom = listOf()
private var selectedTo = listOf()
override val name: String
@@ -66,7 +65,7 @@ class SlotTransfer @Ta5kBuilder constructor(
}
selectedFrom = selection.filterSlots(from)
- selectedTo = to.filter { it.stack.isEmpty } + to.filter { it.stack.item.block in config.disposables }
+ selectedTo = to.filter { it.stack.isEmpty } + to.filter { it.stack.item.block in inventoryConfig.disposables }
val nextFrom = selectedFrom.firstOrNull() ?: return@listen
val nextTo = selectedTo.firstOrNull() ?: return@listen
@@ -83,20 +82,22 @@ class SlotTransfer @Ta5kBuilder constructor(
companion object {
@Ta5kBuilder
- fun moveItems(
+ fun Automated.moveItems(
screen: ScreenHandler,
selection: StackSelection,
from: List,
to: List,
closeScreen: Boolean = true,
- ) = SlotTransfer(screen, selection, from, to, closeScreen)
+ ) = SlotTransfer(screen, selection, from, to, closeScreen, this)
@Ta5kBuilder
+ context(automated: Automated)
fun withdraw(screen: ScreenHandler, selection: StackSelection, closeScreen: Boolean = true) =
- moveItems(screen, selection, screen.containerSlots, screen.inventorySlots, closeScreen)
+ automated.moveItems(screen, selection, screen.containerSlots, screen.inventorySlots, closeScreen)
@Ta5kBuilder
+ context(automated: Automated)
fun deposit(screen: ScreenHandler, selection: StackSelection, closeScreen: Boolean = true) =
- moveItems(screen, selection, screen.inventorySlots, screen.containerSlots, closeScreen)
+ automated.moveItems(screen, selection, screen.inventorySlots, screen.containerSlots, closeScreen)
}
}
diff --git a/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt b/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt
index 34dd88e3d..0bc68f3fc 100644
--- a/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt
+++ b/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.material.transfer
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
@@ -27,7 +28,8 @@ abstract class TransferResult : Task() {
val selection: StackSelection,
val from: MaterialContainer,
val to: MaterialContainer,
- ) : TransferResult() {
+ val automated: Automated
+ ) : TransferResult(), Automated by automated {
override val name = "Container Transfer of [$selection] from [${from.name}] to [${to.name}]"
override fun SafeContext.onStart() {
diff --git a/src/main/kotlin/com/lambda/interaction/request/PostActionHandler.kt b/src/main/kotlin/com/lambda/interaction/request/PostActionHandler.kt
index 154474219..232b3e863 100644
--- a/src/main/kotlin/com/lambda/interaction/request/PostActionHandler.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/PostActionHandler.kt
@@ -49,7 +49,7 @@ abstract class PostActionHandler {
}
fun setPendingConfigs(build: BuildConfig) {
- BrokenBlockHandler.pendingActions.setSizeLimit(build.breaking.maxPendingBreaks)
+ BrokenBlockHandler.pendingActions.setSizeLimit(build.breakConfig.maxPendingBreaks)
BrokenBlockHandler.pendingActions.setDecayTime(build.interactionTimeout * 50L)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lambda/interaction/request/Request.kt b/src/main/kotlin/com/lambda/interaction/request/Request.kt
index e3998af79..5e319ae6c 100644
--- a/src/main/kotlin/com/lambda/interaction/request/Request.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/Request.kt
@@ -17,9 +17,10 @@
package com.lambda.interaction.request
-abstract class Request {
+import com.lambda.context.Automated
+
+abstract class Request : Automated {
abstract val requestID: Int
- abstract val config: RequestConfig
var fresh = true
abstract val done: Boolean
diff --git a/src/main/kotlin/com/lambda/interaction/request/RequestHandler.kt b/src/main/kotlin/com/lambda/interaction/request/RequestHandler.kt
index f23c77bba..43d5da13a 100644
--- a/src/main/kotlin/com/lambda/interaction/request/RequestHandler.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/RequestHandler.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.request
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.core.Loadable
import com.lambda.event.Event
@@ -99,7 +100,7 @@ abstract class RequestHandler(
*/
fun request(request: R, queueIfClosed: Boolean = true): R {
if (!acceptingRequests) {
- val canOverrideQueued = queuedRequest?.run { config === request.config } != false
+ val canOverrideQueued = queuedRequest?.let { it as Automated === request as Automated } != false
if (queueIfClosed && canOverrideQueued) {
queuedRequest = request
}
diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakInfo.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakInfo.kt
index 8e62f324d..e114fae4d 100644
--- a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakInfo.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakInfo.kt
@@ -42,7 +42,7 @@ data class BreakInfo(
var request: BreakRequest
) : ActionInfo, LogContext {
// Delegates
- val breakConfig get() = request.build.breaking
+ val breakConfig get() = request.buildConfig.breakConfig
override val pendingInteractionsList get() = request.pendingInteractions
// Pre Processing
diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt
index 1861ca702..a9e0e9316 100644
--- a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt
@@ -18,6 +18,7 @@
package com.lambda.interaction.request.breaking
import com.lambda.context.SafeContext
+import com.lambda.context.breakConfig
import com.lambda.event.Event
import com.lambda.event.EventFlow.post
import com.lambda.event.events.ConnectionEvent
@@ -72,6 +73,7 @@ import com.lambda.interaction.request.placing.PlaceManager
import com.lambda.interaction.request.rotating.RotationRequest
import com.lambda.module.hud.ManagerDebugLoggers.breakManagerLogger
import com.lambda.threading.runSafe
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta
import com.lambda.util.BlockUtils.isEmpty
@@ -393,21 +395,19 @@ object BreakManager : RequestHandler(
}
}
- val breakConfig = request.config
-
breaks = newBreaks
.sortedByDescending { it.instantBreak }
.take(
min(
- breakConfig.maxPendingBreaks - pendingBreakCount,
- request.build.maxPendingInteractions - request.pendingInteractions.size
+ request.breakConfig.maxPendingBreaks - pendingBreakCount,
+ request.buildConfig.maxPendingInteractions - request.pendingInteractions.size
).coerceAtLeast(0)
)
.toMutableList()
logger.debug("${breaks.size} unprocessed breaks")
- maxBreaksThisTick = breakConfig.breaksPerTick
+ maxBreaksThisTick = request.breakConfig.breaksPerTick
}
/**
@@ -444,9 +444,9 @@ object BreakManager : RequestHandler(
hotbarRequest = with(info) {
HotbarRequest(
context.hotbarIndex,
- request.hotbar,
- request.hotbar.keepTicks.coerceAtLeast(minKeepTicks),
- request.hotbar.swapPause.coerceAtLeast(serverSwapTicks - 1)
+ request,
+ request.hotbarConfig.keepTicks.coerceAtLeast(minKeepTicks),
+ request.hotbarConfig.swapPause.coerceAtLeast(serverSwapTicks - 1)
).submit(false)
}
logger.debug("Submitted hotbar request", hotbarRequest)
@@ -510,27 +510,27 @@ object BreakManager : RequestHandler(
}
primaryBreak = breakInfo
- setPendingConfigs(request.build)
+ setPendingConfigs(request.buildConfig)
logger.success("Initialized break info", breakInfo)
return primaryBreak
}
private fun SafeContext.simulateAbandoned() {
// Cancelled but double breaking so requires break manager to continue the simulation
- abandonedBreak?.let { abandonedInfo ->
- with (abandonedInfo.request) {
- abandonedInfo.context.blockPos
- .toStructure(TargetState.Empty)
- .toBlueprint()
- .simulate(player.eyePos, interact, rotation, inventory, build)
- .asSequence()
- .filterIsInstance()
- .filter { canAccept(it.context) }
- .sorted()
- .let { sim ->
- abandonedInfo.updateInfo(sim.firstOrNull()?.context ?: return)
- }
- }
+ val abandonedInfo = abandonedBreak ?: return
+
+ abandonedInfo.request.runSafeAutomated {
+ abandonedInfo.context.blockPos
+ .toStructure(TargetState.Empty)
+ .toBlueprint()
+ .simulate(player.eyePos)
+ .asSequence()
+ .filterIsInstance()
+ .filter { canAccept(it.context) }
+ .sorted()
+ .let { sim ->
+ abandonedInfo.updateInfo(sim.firstOrNull()?.context ?: return)
+ }
}
}
diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakRequest.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakRequest.kt
index 4c07843c6..3fedc91ec 100644
--- a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakRequest.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakRequest.kt
@@ -17,17 +17,12 @@
package com.lambda.interaction.request.breaking
-import com.lambda.config.groups.BuildConfig
-import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.Automated
import com.lambda.interaction.construction.context.BreakContext
import com.lambda.interaction.construction.context.BuildContext
import com.lambda.interaction.request.LogContext
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
import com.lambda.interaction.request.Request
-import com.lambda.interaction.request.hotbar.HotbarConfig
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.interaction.request.rotating.RotationConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.threading.runSafe
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.BlockUtils.isEmpty
@@ -37,15 +32,10 @@ import net.minecraft.util.math.BlockPos
data class BreakRequest(
val contexts: Collection,
val pendingInteractions: MutableCollection,
- val build: BuildConfig = TaskFlowModule.build,
- val hotbar: HotbarConfig = TaskFlowModule.hotbar,
- val rotation: RotationConfig = TaskFlowModule.rotation,
- val inventory: InventoryConfig = TaskFlowModule.inventory,
- val interact: InteractionConfig = TaskFlowModule.interaction
-) : Request(), LogContext {
+ private val automated: Automated
+) : Request(), LogContext, Automated by automated {
override val requestID = ++requestCount
- override val config = build.breaking
var onStart: ((BlockPos) -> Unit)? = null
var onUpdate: ((BlockPos) -> Unit)? = null
var onStop: ((BlockPos) -> Unit)? = null
@@ -83,13 +73,9 @@ data class BreakRequest(
class RequestBuilder(
contexts: Collection,
pendingInteractions: MutableCollection,
- rotation: RotationConfig,
- hotbar: HotbarConfig,
- interact: InteractionConfig,
- inventory: InventoryConfig,
- build: BuildConfig
+ automated: Automated
) {
- val request = BreakRequest(contexts, pendingInteractions, build, hotbar, rotation, inventory, interact)
+ val request = BreakRequest(contexts, pendingInteractions, automated)
@BreakRequestBuilder
fun onStart(callback: (BlockPos) -> Unit) {
@@ -134,15 +120,10 @@ data class BreakRequest(
var requestCount = 0
@BreakRequestBuilder
- fun breakRequest(
+ fun Automated.breakRequest(
contexts: Collection,
pendingInteractions: MutableCollection,
- rotation: RotationConfig = TaskFlowModule.rotation,
- hotbar: HotbarConfig = TaskFlowModule.hotbar,
- interact: InteractionConfig = TaskFlowModule.interaction,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- build: BuildConfig = TaskFlowModule.build,
builder: RequestBuilder.() -> Unit
- ) = RequestBuilder(contexts, pendingInteractions, rotation, hotbar, interact, inventory, build).apply(builder).build()
+ ) = RequestBuilder(contexts, pendingInteractions, this).apply(builder).build()
}
}
diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/BrokenBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/BrokenBlockHandler.kt
index 859195d6b..9fda8c1ff 100644
--- a/src/main/kotlin/com/lambda/interaction/request/breaking/BrokenBlockHandler.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/breaking/BrokenBlockHandler.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.request.breaking
+import com.lambda.context.AutomationConfig
import com.lambda.context.SafeContext
import com.lambda.event.events.EntityEvent
import com.lambda.event.events.WorldEvent
@@ -27,7 +28,6 @@ import com.lambda.interaction.request.breaking.BreakConfig.BreakConfirmationMode
import com.lambda.interaction.request.breaking.BreakManager.lastPosStarted
import com.lambda.interaction.request.breaking.BreakManager.matchesBlockItem
import com.lambda.interaction.request.breaking.RebreakHandler.rebreak
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.threading.runSafe
import com.lambda.util.BlockUtils.emptyState
import com.lambda.util.BlockUtils.fluidState
@@ -49,7 +49,7 @@ import net.minecraft.util.math.ChunkSectionPos
*/
object BrokenBlockHandler : PostActionHandler() {
override val pendingActions = LimitedDecayQueue(
- TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
+ AutomationConfig.buildConfig.maxPendingInteractions, AutomationConfig.buildConfig.interactionTimeout * 50L
) { info ->
runSafe {
val pos = info.context.blockPos
@@ -61,7 +61,7 @@ object BrokenBlockHandler : PostActionHandler() {
val message = "${info.type} ${info::class.simpleName} at ${info.context.blockPos.toShortString()} timed out with cached state ${info.context.cachedState}"
BreakManager.logger.error(message)
warn(message)
- } else if (!TaskFlowModule.ignoreItemDropWarnings) {
+ } else if (!AutomationConfig.ignoreItemDropWarnings) {
val message = "${info.type} ${info::class.simpleName}'s item drop at ${info.context.blockPos.toShortString()} timed out"
BreakManager.logger.warn(message)
warn(message)
diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/SwapInfo.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/SwapInfo.kt
index 14e55a634..00e788672 100644
--- a/src/main/kotlin/com/lambda/interaction/request/breaking/SwapInfo.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/breaking/SwapInfo.kt
@@ -17,21 +17,23 @@
package com.lambda.interaction.request.breaking
+import com.lambda.context.Automated
+import com.lambda.context.AutomationConfig
+import com.lambda.context.breakConfig
import com.lambda.interaction.request.LogContext
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
import com.lambda.interaction.request.breaking.BreakInfo.BreakType.Primary
import com.lambda.interaction.request.breaking.BreakInfo.BreakType.Secondary
import com.lambda.interaction.request.breaking.BreakManager.calcBreakDelta
-import com.lambda.module.modules.client.TaskFlowModule
import net.minecraft.client.network.ClientPlayerEntity
import net.minecraft.world.BlockView
data class SwapInfo(
private val type: BreakInfo.BreakType,
- private val breakConfig: BreakConfig = TaskFlowModule.build.breaking,
+ private val automated: Automated,
val swap: Boolean = false,
val longSwap: Boolean = false
-) : LogContext {
+) : LogContext, Automated by automated {
override fun getLogContextBuilder(): LogContextBuilder.() -> Unit = {
group("Swap Info") {
value("Type", type)
@@ -40,7 +42,7 @@ data class SwapInfo(
}
companion object {
- val EMPTY = SwapInfo(Primary)
+ val EMPTY = SwapInfo(Primary, AutomationConfig)
fun getSwapInfo(
info: BreakInfo,
@@ -59,9 +61,9 @@ data class SwapInfo(
val swapAtEnd = run {
val swapTickProgress = if (type == Primary)
- breakDelta * (breakTicks + request.config.serverSwapTicks - 1).coerceAtLeast(1)
+ breakDelta * (breakTicks + request.breakConfig.serverSwapTicks - 1).coerceAtLeast(1)
else {
- val serverSwapTicks = request.hotbar.swapPause.coerceAtLeast(3)
+ val serverSwapTicks = request.hotbarConfig.swapPause.coerceAtLeast(3)
breakDelta * (breakTicks + serverSwapTicks - 1).coerceAtLeast(1)
}
swapTickProgress >= threshold
@@ -77,7 +79,7 @@ data class SwapInfo(
return SwapInfo(
info.type,
- request.config,
+ request,
swap,
breakConfig.serverSwapTicks > 0 || (info.type == Secondary && swapAtEnd)
)
diff --git a/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarManager.kt b/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarManager.kt
index b1b14446e..340700682 100644
--- a/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarManager.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarManager.kt
@@ -76,10 +76,10 @@ object HotbarManager : RequestHandler(
override fun SafeContext.handleRequest(request: HotbarRequest) {
logger.debug("Handling request:", request)
- maxSwapsThisTick = request.swapsPerTick
- swapDelay = swapDelay.coerceAtMost(request.swapDelay)
+ maxSwapsThisTick = request.hotbarConfig.swapsPerTick
+ swapDelay = swapDelay.coerceAtMost(request.hotbarConfig.swapDelay)
- if (tickStage !in request.sequenceStageMask) return
+ if (tickStage !in request.hotbarConfig.sequenceStageMask) return
val sameButLonger = activeRequest?.let { active ->
request.slot == active.slot && request.keepTicks >= active.keepTicks
@@ -97,7 +97,7 @@ object HotbarManager : RequestHandler(
}
swapsThisTick++
- swapDelay = request.swapDelay
+ swapDelay = request.hotbarConfig.swapDelay
return@swap
}
@@ -116,7 +116,7 @@ object HotbarManager : RequestHandler(
private fun SafeContext.checkResetSwap() {
activeRequest?.let { active ->
val canStopSwap = swapsThisTick < maxSwapsThisTick
- if (active.keepTicks <= 0 && tickStage in active.sequenceStageMask && canStopSwap) {
+ if (active.keepTicks <= 0 && tickStage in active.hotbarConfig.sequenceStageMask && canStopSwap) {
logger.debug("Clearing request and syncing slot", activeRequest)
activeRequest = null
interaction.syncSelectedSlot()
diff --git a/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarRequest.kt b/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarRequest.kt
index e17cc6e7f..05faaa042 100644
--- a/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarRequest.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/hotbar/HotbarRequest.kt
@@ -17,16 +17,17 @@
package com.lambda.interaction.request.hotbar
+import com.lambda.context.Automated
import com.lambda.interaction.request.LogContext
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
import com.lambda.interaction.request.Request
class HotbarRequest(
val slot: Int,
- override val config: HotbarConfig,
- override var keepTicks: Int = config.keepTicks,
- override var swapPause: Int = config.swapPause
-) : Request(), HotbarConfig by config, LogContext {
+ automated: Automated,
+ var keepTicks: Int = automated.hotbarConfig.keepTicks,
+ var swapPause: Int = automated.hotbarConfig.swapPause
+) : Request(), LogContext, Automated by automated {
override val requestID = ++requestCount
var activeRequestAge = 0
diff --git a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractRequest.kt b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractRequest.kt
index cf8b6796f..dbb74e138 100644
--- a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractRequest.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractRequest.kt
@@ -18,26 +18,21 @@
package com.lambda.interaction.request.interacting
import com.lambda.Lambda.mc
-import com.lambda.config.groups.BuildConfig
+import com.lambda.context.Automated
import com.lambda.interaction.construction.context.BuildContext
import com.lambda.interaction.construction.context.InteractionContext
import com.lambda.interaction.request.LogContext
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
import com.lambda.interaction.request.Request
-import com.lambda.interaction.request.hotbar.HotbarConfig
-import com.lambda.interaction.request.rotating.RotationConfig
import com.lambda.util.BlockUtils.matches
import net.minecraft.util.math.BlockPos
data class InteractRequest(
val contexts: Collection,
- val onInteract: ((BlockPos) -> Unit)?,
val pendingInteractionsList: MutableCollection,
- override val config: InteractConfig,
- val build: BuildConfig,
- val hotbar: HotbarConfig,
- val rotation: RotationConfig
-) : Request(), InteractConfig by config, LogContext {
+ private val automated: Automated,
+ val onInteract: ((BlockPos) -> Unit)?
+) : Request(), LogContext, Automated by automated {
override val requestID = ++requestCount
override val done: Boolean
diff --git a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractedBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractedBlockHandler.kt
index 5f75da479..09cb5200e 100644
--- a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractedBlockHandler.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractedBlockHandler.kt
@@ -19,11 +19,11 @@ package com.lambda.interaction.request.interacting
import com.lambda.Lambda.mc
import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.AutomationConfig
import com.lambda.event.events.WorldEvent
import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.interaction.construction.processing.ProcessorRegistry
import com.lambda.interaction.request.PostActionHandler
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.util.BlockUtils.matches
import com.lambda.util.Communication.info
import com.lambda.util.Communication.warn
@@ -31,7 +31,8 @@ import com.lambda.util.collections.LimitedDecayQueue
object InteractedBlockHandler : PostActionHandler() {
override val pendingActions = LimitedDecayQueue(
- TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
+ AutomationConfig.buildConfig.maxPendingInteractions,
+ AutomationConfig.buildConfig.interactionTimeout * 50L
) {
info("${it::class.simpleName} at ${it.context.blockPos.toShortString()} timed out")
if (it.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.AwaitThenInteract) {
diff --git a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionInfo.kt b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionInfo.kt
index 9c84fae7b..5c46aa5bc 100644
--- a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionInfo.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionInfo.kt
@@ -17,6 +17,8 @@
package com.lambda.interaction.request.interacting
+import com.lambda.context.Automated
+import com.lambda.context.interactConfig
import com.lambda.interaction.construction.context.BuildContext
import com.lambda.interaction.construction.context.InteractionContext
import com.lambda.interaction.request.ActionInfo
@@ -26,8 +28,8 @@ import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
data class InteractionInfo(
override val context: InteractionContext,
override val pendingInteractionsList: MutableCollection,
- private val config: InteractConfig
-) : ActionInfo, InteractConfig by config, LogContext {
+ private val automated: Automated
+) : ActionInfo, InteractConfig by automated.interactConfig, LogContext {
override fun getLogContextBuilder(): LogContextBuilder.() -> Unit = {
group("Interaction Info") {
text(context.getLogContextBuilder())
diff --git a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionManager.kt b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionManager.kt
index da2910aec..67d78fd7a 100644
--- a/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionManager.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/interacting/InteractionManager.kt
@@ -19,6 +19,7 @@ package com.lambda.interaction.request.interacting
import com.lambda.config.groups.InteractionConfig
import com.lambda.context.SafeContext
+import com.lambda.context.interactConfig
import com.lambda.event.EventFlow.post
import com.lambda.event.events.MovementEvent
import com.lambda.event.events.TickEvent
@@ -38,6 +39,7 @@ import com.lambda.interaction.request.interacting.InteractedBlockHandler.startPe
import com.lambda.interaction.request.interacting.InteractionManager.processRequest
import com.lambda.interaction.request.placing.PlaceManager
import com.lambda.module.hud.ManagerDebugLoggers.interactionManagerLogger
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.player.MovementUtils.sneaking
import com.lambda.util.player.swingHand
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket
@@ -97,7 +99,7 @@ object InteractionManager : RequestHandler(
if (interactionsThisTick > 0) activeThisTick = true
}
- fun SafeContext.processRequest(request: InteractRequest) {
+ fun SafeContext.processRequest(request: InteractRequest) = request.runSafeAutomated {
if (BreakManager.activeThisTick || PlaceManager.activeThisTick) return
logger.debug("Processing request", request)
@@ -115,20 +117,20 @@ object InteractionManager : RequestHandler(
logger.warning("Dependencies failed for interaction", ctx, request)
return
}
- if (tickStage !in request.interactStageMask) return
+ if (tickStage !in interactConfig.interactStageMask) return
- if (request.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.None) {
+ if (interactConfig.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.None) {
InteractionInfo(ctx, request.pendingInteractionsList, request).startPending()
}
- if (request.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.AwaitThenInteract) {
+ if (interactConfig.interactConfirmationMode != InteractionConfig.InteractConfirmationMode.AwaitThenInteract) {
interaction.interactBlock(player, Hand.MAIN_HAND, ctx.result)
} else {
interaction.sendSequencedPacket(world) { sequence ->
PlayerInteractBlockC2SPacket(Hand.MAIN_HAND, ctx.result, sequence)
}
}
- if (request.swingHand) {
- swingHand(request.interactSwingType, Hand.MAIN_HAND)
+ if (interactConfig.swingHand) {
+ swingHand(interactConfig.interactSwingType, Hand.MAIN_HAND)
}
request.onInteract?.invoke(ctx.blockPos)
interactionsThisTick++
@@ -139,16 +141,16 @@ object InteractionManager : RequestHandler(
private fun populateFrom(request: InteractRequest) {
logger.debug("Populating from request", request)
- setPendingConfigs(request.build)
+ setPendingConfigs(request.buildConfig)
potentialInteractions = request.contexts
.distinctBy { it.blockPos }
.filter { !isPosBlocked(it.blockPos) }
- .take((request.build.maxPendingInteractions - pendingActions.size).coerceAtLeast(0))
+ .take((request.buildConfig.maxPendingInteractions - pendingActions.size).coerceAtLeast(0))
.toMutableList()
logger.debug("${potentialInteractions.size} potential interactions")
- maxInteractionsThisTick = request.build.interactionsPerTick
+ maxInteractionsThisTick = request.buildConfig.interactionsPerTick
}
override fun preEvent() = UpdateManagerEvent.Interact.post()
diff --git a/src/main/kotlin/com/lambda/interaction/request/inventory/InventoryRequest.kt b/src/main/kotlin/com/lambda/interaction/request/inventory/InventoryRequest.kt
index a8589b1e2..b80d78746 100644
--- a/src/main/kotlin/com/lambda/interaction/request/inventory/InventoryRequest.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/inventory/InventoryRequest.kt
@@ -17,13 +17,14 @@
package com.lambda.interaction.request.inventory
+import com.lambda.context.Automated
import com.lambda.interaction.request.LogContext
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
import com.lambda.interaction.request.Request
class InventoryRequest(
- override val config: InventoryConfig
-) : Request(), InventoryConfig by config, LogContext {
+ automated: Automated
+) : Request(), LogContext, Automated by automated {
override val requestID = ++requestCount
override val done: Boolean
diff --git a/src/main/kotlin/com/lambda/interaction/request/placing/PlaceManager.kt b/src/main/kotlin/com/lambda/interaction/request/placing/PlaceManager.kt
index 1370b840e..ba24b062a 100644
--- a/src/main/kotlin/com/lambda/interaction/request/placing/PlaceManager.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/placing/PlaceManager.kt
@@ -18,6 +18,7 @@
package com.lambda.interaction.request.placing
import com.lambda.context.SafeContext
+import com.lambda.context.placeConfig
import com.lambda.event.Event
import com.lambda.event.EventFlow.post
import com.lambda.event.events.MovementEvent
@@ -160,7 +161,7 @@ object PlaceManager : RequestHandler(
return
}
if (!validSneak(player)) return
- if (tickStage !in request.placeStageMask) return
+ if (tickStage !in request.placeConfig.placeStageMask) return
val actionResult = placeBlock(ctx, request, Hand.MAIN_HAND)
if (!actionResult.isAccepted) {
@@ -186,20 +187,20 @@ object PlaceManager : RequestHandler(
*/
private fun populateFrom(request: PlaceRequest) {
logger.debug("Populating from request", request)
- setPendingConfigs(request.build)
+ setPendingConfigs(request.buildConfig)
potentialPlacements = request.contexts
.distinctBy { it.blockPos }
.filter { !isPosBlocked(it.blockPos) }
.take(
min(
- request.maxPendingPlacements - pendingActions.size,
- request.build.maxPendingInteractions - request.pendingInteractions.size
+ request.placeConfig.maxPendingPlacements - pendingActions.size,
+ request.buildConfig.maxPendingInteractions - request.pendingInteractions.size
).coerceAtLeast(0)
)
.toMutableList()
logger.debug("${potentialPlacements.size} potential placements")
- maxPlacementsThisTick = request.placementsPerTick
+ maxPlacementsThisTick = request.placeConfig.placementsPerTick
}
/**
@@ -218,7 +219,7 @@ object PlaceManager : RequestHandler(
logger.error("Player is in spectator mode", placeContext, request)
return ActionResult.PASS
}
- return interactBlockInternal(placeContext, request, request.build.placing, hand, hitResult)
+ return interactBlockInternal(placeContext, request, request.buildConfig.placeConfig, hand, hitResult)
}
/**
diff --git a/src/main/kotlin/com/lambda/interaction/request/placing/PlaceRequest.kt b/src/main/kotlin/com/lambda/interaction/request/placing/PlaceRequest.kt
index f38ecfcf3..a88c95a0d 100644
--- a/src/main/kotlin/com/lambda/interaction/request/placing/PlaceRequest.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/placing/PlaceRequest.kt
@@ -17,14 +17,12 @@
package com.lambda.interaction.request.placing
-import com.lambda.config.groups.BuildConfig
+import com.lambda.context.Automated
import com.lambda.interaction.construction.context.BuildContext
import com.lambda.interaction.construction.context.PlaceContext
import com.lambda.interaction.request.LogContext
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
import com.lambda.interaction.request.Request
-import com.lambda.interaction.request.hotbar.HotbarConfig
-import com.lambda.interaction.request.rotating.RotationConfig
import com.lambda.threading.runSafe
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.BlockUtils.matches
@@ -33,15 +31,11 @@ import net.minecraft.util.math.BlockPos
data class PlaceRequest(
val contexts: Collection,
val pendingInteractions: MutableCollection,
- val build: BuildConfig,
- val hotbar: HotbarConfig,
- val rotation: RotationConfig,
+ private val automated: Automated,
val onPlace: ((BlockPos) -> Unit)? = null
-) : Request(), PlaceConfig by build.placing, LogContext {
+) : Request(), LogContext, Automated by automated {
override val requestID = ++requestCount
- override val config = build.placing
-
override val done: Boolean
get() = runSafe {
contexts.all { it.expectedState.matches(blockState(it.blockPos)) }
diff --git a/src/main/kotlin/com/lambda/interaction/request/placing/PlacedBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/request/placing/PlacedBlockHandler.kt
index 8defed63b..d752f24c5 100644
--- a/src/main/kotlin/com/lambda/interaction/request/placing/PlacedBlockHandler.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/placing/PlacedBlockHandler.kt
@@ -17,12 +17,12 @@
package com.lambda.interaction.request.placing
+import com.lambda.context.AutomationConfig
import com.lambda.event.events.WorldEvent
import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.interaction.construction.processing.ProcessorRegistry
import com.lambda.interaction.request.PostActionHandler
import com.lambda.interaction.request.placing.PlaceManager.placeSound
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.threading.runSafe
import com.lambda.util.BlockUtils.matches
import com.lambda.util.Communication.info
@@ -31,7 +31,8 @@ import com.lambda.util.collections.LimitedDecayQueue
object PlacedBlockHandler : PostActionHandler() {
override val pendingActions = LimitedDecayQueue(
- TaskFlowModule.build.maxPendingInteractions, TaskFlowModule.build.interactionTimeout * 50L
+ AutomationConfig.buildConfig.maxPendingInteractions,
+ AutomationConfig.buildConfig.interactionTimeout * 50L
) {
info("${it::class.simpleName} at ${it.context.blockPos.toShortString()} timed out")
if (it.placeConfig.placeConfirmationMode != PlaceConfig.PlaceConfirmationMode.AwaitThenPlace) {
diff --git a/src/main/kotlin/com/lambda/interaction/request/rotating/RotationManager.kt b/src/main/kotlin/com/lambda/interaction/request/rotating/RotationManager.kt
index a695e4133..1898eaec9 100644
--- a/src/main/kotlin/com/lambda/interaction/request/rotating/RotationManager.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/rotating/RotationManager.kt
@@ -166,7 +166,7 @@ object RotationManager : RequestHandler(
@JvmStatic
fun handleBaritoneRotation(yaw: Float) {
runSafe {
- baritoneRequest = lookAt(Rotation(yaw, player.pitch)).requestBy(BaritoneManager.rotation)
+ baritoneRequest = lookAt(Rotation(yaw, player.pitch)).requestBy(BaritoneManager)
}
}
diff --git a/src/main/kotlin/com/lambda/interaction/request/rotating/RotationRequest.kt b/src/main/kotlin/com/lambda/interaction/request/rotating/RotationRequest.kt
index c38bfcd11..dc977e8b8 100644
--- a/src/main/kotlin/com/lambda/interaction/request/rotating/RotationRequest.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/rotating/RotationRequest.kt
@@ -17,6 +17,7 @@
package com.lambda.interaction.request.rotating
+import com.lambda.context.Automated
import com.lambda.interaction.request.LogContext
import com.lambda.interaction.request.LogContext.Companion.LogContextBuilder
import com.lambda.interaction.request.Request
@@ -25,13 +26,13 @@ import com.lambda.threading.runSafe
data class RotationRequest(
val target: RotationTarget,
- override val config: RotationConfig,
- override val rotationMode: RotationMode = config.rotationMode,
- override val turnSpeed: Double = config.turnSpeed,
- override var keepTicks: Int = config.keepTicks,
- override var decayTicks: Int = config.decayTicks,
+ private val automated: Automated,
+ val rotationMode: RotationMode = automated.rotationConfig.rotationMode,
+ val turnSpeed: Double = automated.rotationConfig.turnSpeed,
+ var keepTicks: Int = automated.rotationConfig.keepTicks,
+ var decayTicks: Int = automated.rotationConfig.decayTicks,
val speedMultiplier: Double = 1.0
-) : Request(), RotationConfig by config, LogContext {
+) : Request(), LogContext, Automated by automated {
override val requestID = ++requestCount
var age = 0
diff --git a/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTarget.kt b/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTarget.kt
index 74ff1c42a..71359b35b 100644
--- a/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTarget.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTarget.kt
@@ -17,10 +17,10 @@
package com.lambda.interaction.request.rotating.visibilty
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.request.rotating.Rotation
import com.lambda.interaction.request.rotating.Rotation.Companion.dist
-import com.lambda.interaction.request.rotating.RotationConfig
import com.lambda.interaction.request.rotating.RotationManager
import com.lambda.interaction.request.rotating.RotationRequest
import com.lambda.threading.runSafe
@@ -52,6 +52,6 @@ data class RotationTarget(
* @param config The rotation configuration.
* @return [RotationRequest] containing this [RotationTarget].
*/
- fun requestBy(config: RotationConfig, queueIfClosed: Boolean = true) =
- RotationRequest(this, config).submit(queueIfClosed)
+ fun requestBy(automated: Automated, queueIfClosed: Boolean = true) =
+ RotationRequest(this, automated).submit(queueIfClosed)
}
diff --git a/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTargets.kt b/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTargets.kt
index 62c934a5e..85d23063a 100644
--- a/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTargets.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/RotationTargets.kt
@@ -17,7 +17,7 @@
package com.lambda.interaction.request.rotating.visibilty
-import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.construction.verify.SurfaceScan
import com.lambda.interaction.request.rotating.Rotation
@@ -25,7 +25,7 @@ import com.lambda.interaction.request.rotating.Rotation.Companion.dist
import com.lambda.interaction.request.rotating.RotationManager
import com.lambda.interaction.request.rotating.visibilty.VisibilityChecker.ALL_SIDES
import com.lambda.interaction.request.rotating.visibilty.VisibilityChecker.findRotation
-import com.lambda.module.modules.client.TaskFlowModule
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.extension.rotation
import com.lambda.util.world.raycast.InteractionMask
import net.minecraft.entity.LivingEntity
@@ -81,13 +81,10 @@ fun lookAtHit(hit: RequestedHit, rotation: SafeContext.() -> Rotation?) =
* @return A [RotationTarget] instance.
*/
@RotationDsl
-fun lookAtHit(
- hit: HitResult,
- config: InteractionConfig = TaskFlowModule.interaction,
-): RotationTarget? {
+fun Automated.lookAtHit(hit: HitResult): RotationTarget? {
return when (hit) {
- is BlockHitResult -> lookAtBlock(hit.blockPos, setOf(hit.side), SurfaceScan.DEFAULT, config)
- is EntityHitResult -> lookAtEntity(hit.entity as? LivingEntity ?: return null, config)
+ is BlockHitResult -> lookAtBlock(hit.blockPos, setOf(hit.side), SurfaceScan.DEFAULT)
+ is EntityHitResult -> lookAtEntity(hit.entity as? LivingEntity ?: return null)
else -> null
}
}
@@ -100,22 +97,20 @@ fun lookAtHit(
* @return A [RotationTarget] instance.
*/
@RotationDsl
-fun lookAtEntity(
- entity: LivingEntity,
- config: InteractionConfig = TaskFlowModule.interaction
-): RotationTarget {
- val requestedHit = entityHit(entity, config.attackReach)
+fun Automated.lookAtEntity(entity: LivingEntity): RotationTarget {
+ val requestedHit = entityHit(entity, interactionConfig.attackReach)
return RotationTarget(requestedHit) {
- findRotation(
- requestedHit.getBoundingBoxes(),
- config.attackReach,
- player.eyePos,
- ALL_SIDES,
- SurfaceScan.DEFAULT,
- InteractionMask.Entity,
- config
- ) { requestedHit.verifyHit(hit) }?.targetRotation
+ runSafeAutomated {
+ findRotation(
+ requestedHit.getBoundingBoxes(),
+ interactionConfig.attackReach,
+ player.eyePos,
+ ALL_SIDES,
+ SurfaceScan.DEFAULT,
+ InteractionMask.Entity
+ ) { requestedHit.verifyHit(hit) }?.targetRotation
+ }
}
}
@@ -128,23 +123,23 @@ fun lookAtEntity(
* @return A [RotationTarget] instance.
*/
@RotationDsl
-fun lookAtBlock(
+fun Automated.lookAtBlock(
pos: BlockPos,
sides: Set = ALL_SIDES,
- surfaceScan: SurfaceScan = SurfaceScan.DEFAULT,
- config: InteractionConfig = TaskFlowModule.interaction,
+ surfaceScan: SurfaceScan = SurfaceScan.DEFAULT
): RotationTarget {
- val requestedHit = blockHit(pos, sides, config.interactReach)
+ val requestedHit = blockHit(pos, sides, interactionConfig.interactReach)
return RotationTarget(requestedHit) {
- findRotation(
- requestedHit.getBoundingBoxes(),
- config.interactReach,
- player.eyePos,
- sides,
- surfaceScan,
- InteractionMask.Block,
- config
- ) { requestedHit.verifyHit(hit) }?.targetRotation
+ runSafeAutomated {
+ findRotation(
+ requestedHit.getBoundingBoxes(),
+ interactionConfig.interactReach,
+ player.eyePos,
+ sides,
+ surfaceScan,
+ InteractionMask.Block
+ ) { requestedHit.verifyHit(hit) }?.targetRotation
+ }
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/VisibilityChecker.kt b/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/VisibilityChecker.kt
index b9bb6f315..7aa527061 100644
--- a/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/VisibilityChecker.kt
+++ b/src/main/kotlin/com/lambda/interaction/request/rotating/visibilty/VisibilityChecker.kt
@@ -18,13 +18,14 @@
package com.lambda.interaction.request.rotating.visibilty
import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.AutomatedSafeContext
+import com.lambda.context.AutomationConfig
import com.lambda.context.SafeContext
import com.lambda.interaction.construction.verify.ScanMode
import com.lambda.interaction.construction.verify.SurfaceScan
import com.lambda.interaction.request.rotating.Rotation
import com.lambda.interaction.request.rotating.Rotation.Companion.rotationTo
import com.lambda.interaction.request.rotating.RotationManager
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.util.extension.component6
import com.lambda.util.math.distSq
import com.lambda.util.world.raycast.InteractionMask
@@ -55,14 +56,13 @@ object VisibilityChecker {
*
* @return A [CheckedHit] if a valid rotation was found; otherwise, null.
*/
- fun SafeContext.findRotation(
+ fun AutomatedSafeContext.findRotation(
boxes: List,
reach: Double,
eye: Vec3d,
sides: Set,
scan: SurfaceScan,
targetType: InteractionMask,
- interaction: InteractionConfig,
verify: CheckedHit.() -> Boolean
): CheckedHit? {
val currentRotation = RotationManager.activeRotation
@@ -73,8 +73,8 @@ object VisibilityChecker {
}
}
- return interaction.pointSelection.select(
- collectHitsFor(boxes, reach, eye, sides, scan, targetType, interaction, verify)
+ return interactionConfig.pointSelection.select(
+ collectHitsFor(boxes, reach, eye, sides, scan, targetType, verify)
)
}
@@ -91,27 +91,26 @@ object VisibilityChecker {
*
* @return A collection of [CheckedHit] with valid angles found
*/
- fun SafeContext.collectHitsFor(
+ fun AutomatedSafeContext.collectHitsFor(
boxes: List,
reach: Double,
eye: Vec3d = player.eyePos,
sides: Set = ALL_SIDES,
scan: SurfaceScan = SurfaceScan.DEFAULT,
targetType: InteractionMask,
- interaction: InteractionConfig,
verify: CheckedHit.() -> Boolean,
) = mutableListOf().apply {
- val reachSq = interaction.scanReach.pow(2)
+ val reachSq = interactionConfig.scanReach.pow(2)
boxes.forEach { box ->
- val visible = visibleSides(box, eye, interaction.checkSideVisibility)
+ val visible = visibleSides(box, eye, interactionConfig.checkSideVisibility)
- scanSurfaces(box, visible.intersect(sides), interaction.resolution, scan) { _, vec ->
+ scanSurfaces(box, visible.intersect(sides), interactionConfig.resolution, scan) { _, vec ->
if (eye distSq vec > reachSq) return@scanSurfaces
val newRotation = eye.rotationTo(vec)
- val mask = if (interaction.strictRayCast) InteractionMask.Both else targetType
+ val mask = if (interactionConfig.strictRayCast) InteractionMask.Both else targetType
val hit = newRotation.rayCast(reach, eye, mask = mask) ?: return@scanSurfaces
val checked = CheckedHit(hit, newRotation, reach)
@@ -172,7 +171,7 @@ object VisibilityChecker {
check: (Direction, Vec3d) -> Unit,
) {
sides.forEach { side ->
- val (minX, minY, minZ, maxX, maxY, maxZ) = box.contract(TaskFlowModule.shrinkFactor).bounds(side)
+ val (minX, minY, minZ, maxX, maxY, maxZ) = box.contract(AutomationConfig.shrinkFactor).bounds(side)
// Determine the bounds to scan based on the axis and mode. Skip if no part of the face is in the desired bounds
val (startX, endX) = if (scan.axis == Direction.Axis.X && maxX != minX) {
diff --git a/src/main/kotlin/com/lambda/module/Module.kt b/src/main/kotlin/com/lambda/module/Module.kt
index 276999dfe..2a6f42003 100644
--- a/src/main/kotlin/com/lambda/module/Module.kt
+++ b/src/main/kotlin/com/lambda/module/Module.kt
@@ -23,6 +23,8 @@ import com.lambda.config.AbstractSetting
import com.lambda.config.Configurable
import com.lambda.config.Configuration
import com.lambda.config.configurations.ModuleConfig
+import com.lambda.context.Automated
+import com.lambda.context.AutomationConfig
import com.lambda.context.SafeContext
import com.lambda.event.Muteable
import com.lambda.event.events.ClientEvent
@@ -114,7 +116,7 @@ abstract class Module(
enabledByDefault: Boolean = false,
defaultKeybind: KeyCode = KeyCode.UNBOUND,
autoDisable: Boolean = false
-) : Nameable, Muteable, Configurable(ModuleConfig) {
+) : Nameable, Muteable, Configurable(ModuleConfig), Automated by AutomationConfig {
private val isEnabledSetting = setting("Enabled", enabledByDefault) { false }
val keybindSetting = setting("Keybind", defaultKeybind) { false }
val disableOnReleaseSetting = setting("Disable On Release", false) { false }
diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt
index 04a9df62b..7dac4f9d3 100644
--- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt
+++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt
@@ -55,7 +55,7 @@ object AutoTotem : Module(
private val minPlayerDistance by setting("Player Distance", 64, 32..128, 4, "Set the distance to detect players to swap") { players }.group(Group.General)
private val friends by setting("Friends", false, "Exclude friends from triggering player-based swaps") { players }.group(Group.General)
- private val inventory = InventorySettings(this, Group.Inventory)
+ override val inventoryConfig = InventorySettings(this, Group.Inventory)
init {
listen {
@@ -63,7 +63,7 @@ object AutoTotem : Module(
if (!player.isHolding(Items.TOTEM_OF_UNDYING)) {
Items.TOTEM_OF_UNDYING.select()
- .transfer(OffHandContainer, inventory)
+ .transfer(OffHandContainer)
?.finally { if (log) info("Swapped the off-hand item with a totem") }
?.run()
}
diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt
index de2df0f37..2224efc94 100644
--- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt
+++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt
@@ -117,7 +117,7 @@ object CrystalAura : Module(
private val targeting = Targeting.Combat(this, Group.Targeting, 10.0)
/* Rotation */
- private val rotation = RotationSettings(this, Group.Rotation)
+ override val rotationConfig = RotationSettings(this, Group.Rotation)
private val blueprint = mutableMapOf()
private var activeOpportunity: Opportunity? = null
@@ -483,7 +483,7 @@ object CrystalAura : Module(
* Places the crystal on [blockPos]
*/
fun place() = runSafe {
- if (rotation.rotate && !lookAt(placeRotation).requestBy(rotation).done)
+ if (rotationConfig.rotate && !lookAt(placeRotation).requestBy(this@CrystalAura).done)
return@runSafe
val selection = selectStack { isItem(Items.END_CRYSTAL) }
@@ -515,7 +515,7 @@ object CrystalAura : Module(
* @return Whether the delay passed, null if the interaction failed or no crystal found
*/
fun explode() {
- if (rotation.rotate && !lookAt(placeRotation).requestBy(rotation).done) return
+ if (rotationConfig.rotate && !lookAt(placeRotation).requestBy(this@CrystalAura).done) return
explodeTimer.runSafeIfPassed(explodeDelay.milliseconds) {
crystal?.let { crystal ->
diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt
index edbca7442..6cd95c95f 100644
--- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt
+++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt
@@ -17,7 +17,7 @@
package com.lambda.module.modules.combat
-import com.lambda.config.groups.InteractSettings
+import com.lambda.config.groups.BuildSettings
import com.lambda.config.groups.InteractionSettings
import com.lambda.config.groups.RotationSettings
import com.lambda.config.groups.Targeting
@@ -42,8 +42,6 @@ import com.lambda.util.player.SlotUtils.hotbarAndStorage
import com.lambda.util.world.raycast.InteractionMask
import com.lambda.util.world.raycast.RayCastUtils.entityResult
import net.minecraft.entity.LivingEntity
-import net.minecraft.entity.attribute.EntityAttributes
-import net.minecraft.registry.tag.ItemTags
import net.minecraft.util.Hand
import net.minecraft.util.math.Vec3d
@@ -53,20 +51,20 @@ object KillAura : Module(
tag = ModuleTag.COMBAT,
) {
// Interact
- private val interactionSettings = InteractionSettings(this, Group.Interaction, InteractionMask.Entity)
- private val interactSettings = InteractSettings(this, listOf(Group.Interact))
- private val swap by setting("Swap", true, "Swap to the item with the highest damage").group(Group.Interact)
- private val attackMode by setting("Attack Mode", AttackMode.Cooldown).group(Group.Interact)
- private val cooldownOffset by setting("Cooldown Offset", 0, -5..5, 1) { attackMode == AttackMode.Cooldown }.group(Group.Interact)
- private val hitDelay1 by setting("Hit Delay 1", 2.0, 0.0..20.0, 1.0) { attackMode == AttackMode.Delay }.group(Group.Interact)
- private val hitDelay2 by setting("Hit Delay 2", 6.0, 0.0..20.0, 1.0) { attackMode == AttackMode.Delay }.group(Group.Interact)
+ override val interactionConfig = InteractionSettings(this, Group.Interaction, InteractionMask.Entity)
+ override val buildConfig = BuildSettings(this, Group.Build)
+ private val swap by setting("Swap", true, "Swap to the item with the highest damage").group(Group.Build)
+ private val attackMode by setting("Attack Mode", AttackMode.Cooldown).group(Group.Build)
+ private val cooldownOffset by setting("Cooldown Offset", 0, -5..5, 1) { attackMode == AttackMode.Cooldown }.group(Group.Build)
+ private val hitDelay1 by setting("Hit Delay 1", 2.0, 0.0..20.0, 1.0) { attackMode == AttackMode.Delay }.group(Group.Build)
+ private val hitDelay2 by setting("Hit Delay 2", 6.0, 0.0..20.0, 1.0) { attackMode == AttackMode.Delay }.group(Group.Build)
// Targeting
private val targeting = Targeting.Combat(this, Group.Targeting)
// Aiming
private val rotate by setting("Rotate", true).group(Group.Aiming)
- private val rotation = RotationSettings(this, Group.Aiming) { rotate }
+ override val rotationConfig = RotationSettings(this, Group.Aiming) { rotate }
val target: LivingEntity?
get() = targeting.target()
@@ -84,7 +82,7 @@ object KillAura : Module(
enum class Group(override val displayName: String) : NamedEnum {
Interaction("Interaction"),
- Interact("Interact"),
+ Build("Build"),
Targeting("Targeting"),
Aiming("Aiming")
}
@@ -111,7 +109,7 @@ object KillAura : Module(
}
// Wait until the rotation has a hit result on the entity
- if (lookAtEntity(entity).requestBy(rotation).done) runAttack(entity)
+ if (lookAtEntity(entity).requestBy(this@KillAura).done) runAttack(entity)
}
}
@@ -130,18 +128,18 @@ object KillAura : Module(
if (rotate) {
val angle = RotationManager.activeRotation
- if (interactionSettings.strictRayCast) {
- val cast = angle.rayCast(interactionSettings.attackReach)
+ if (interactionConfig.strictRayCast) {
+ val cast = angle.rayCast(interactionConfig.attackReach)
if (cast?.entityResult?.entity != target) return
}
// Perform a raycast without checking the environment
- angle.castBox(target.boundingBox, interactionSettings.attackReach) ?: return
+ angle.castBox(target.boundingBox, interactionConfig.attackReach) ?: return
}
// Attack
interaction.attackEntity(player, target)
- if (interactSettings.swingHand) player.swingHand(Hand.MAIN_HAND)
+ if (buildConfig.interactConfig.swingHand) player.swingHand(Hand.MAIN_HAND)
lastAttackTime = System.currentTimeMillis()
hitDelay = (hitDelay1..hitDelay2).random() * 50
diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt
index c2e7145e7..79c479932 100644
--- a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt
+++ b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt
@@ -23,17 +23,13 @@ import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.interaction.request.rotating.visibilty.lookAtHit
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
-import com.lambda.util.Communication.info
-import com.lambda.util.combat.DamageUtils.fallDamage
-import com.lambda.util.combat.DamageUtils.isFallDeadly
import net.minecraft.util.hit.HitResult
-import net.minecraft.util.math.Vec3d
object RotationTest : Module(
name = "RotationTest",
tag = ModuleTag.DEBUG,
) {
- var rotation = RotationSettings(this)
+ override val rotationConfig = RotationSettings(this)
var hitPos: HitResult? = null
init {
@@ -42,7 +38,7 @@ object RotationTest : Module(
}
listen {
- hitPos?.let { lookAtHit(it)?.requestBy(rotation) }
+ hitPos?.let { lookAtHit(it)?.requestBy(this@RotationTest) }
}
}
}
diff --git a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt
index 80215d153..4a610fe00 100644
--- a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt
+++ b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt
@@ -36,11 +36,11 @@ object SilentSwap : Module(
Hotbar("Hotbar")
}
- private val hotbar = HotbarSettings(this, Group.Hotbar)
+ override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
init {
listen {
- if (!submit(HotbarRequest(0, hotbar)).done) {
+ if (!submit(HotbarRequest(0, this@SilentSwap)).done) {
it.cancel()
return@listen
}
diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt
index 69bb6b243..06565bed3 100644
--- a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt
+++ b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt
@@ -62,7 +62,7 @@ object Speed : Module(
private val ncpAutoJump by setting("Auto Jump", false).group(Mode.NCP_STRAFE)
private val ncpTimerBoost by setting("Timer Boost", 1.08, 1.0..1.1, 0.01).group(Mode.NCP_STRAFE)
- private val rotationConfig = RotationConfig.Instant(RotationMode.Sync)
+ override val rotationConfig = RotationConfig.Instant(RotationMode.Sync)
// NCP state variables
const val NCP_BASE_SPEED = 0.2873
@@ -122,7 +122,7 @@ object Speed : Module(
lookAt(
Rotation(targetYaw, player.pitch.toDouble())
- ).requestBy(rotationConfig)
+ ).requestBy(this@Speed)
}
onEnable {
diff --git a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt
index d7dce379d..0c408d4ea 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt
@@ -73,7 +73,7 @@ object AntiAim : Module(
private val yawSpeed by setting("Yaw Speed", 30, 1..90, 1, "Yaw rotation degrees per tick", "°") { yaw != YawMode.None }.group(Group.General)
private val pitchSpeed by setting("Pitch Speed", 30, 1..90, 1, "Pitch rotation degrees per tick", "°") { pitch != PitchMode.None }.group(Group.General)
- private val rotation = RotationSettings(this, Group.Rotation)
+ override val rotationConfig = RotationSettings(this, Group.Rotation)
private var currentYaw = 0.0f
private var currentPitch = 0.0f
@@ -164,7 +164,7 @@ object AntiAim : Module(
listen(priority = Int.MIN_VALUE) {
if (currentYaw == wrap(player.yaw) && currentPitch == player.pitch) return@listen
- submit(RotationRequest(lookAt(Rotation(currentYaw, currentPitch)), rotation), false)
+ submit(RotationRequest(lookAt(Rotation(currentYaw, currentPitch)), this@AntiAim), false)
}
}
diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt
index 722947623..7114de5ec 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt
@@ -27,6 +27,7 @@ import com.lambda.module.tag.ModuleTag
import com.lambda.task.RootTask.run
import com.lambda.task.tasks.EatTask
import com.lambda.task.tasks.EatTask.Companion.eat
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.NamedEnum
object AutoEat : Module(
@@ -39,16 +40,16 @@ object AutoEat : Module(
Inventory("Inventory")
}
- private val eat = EatSettings(this, Group.Eating)
- private val inventory = InventorySettings(this, Group.Inventory)
+ override val eatConfig = EatSettings(this, Group.Eating)
+ override val inventoryConfig = InventorySettings(this, Group.Inventory)
private var eatTask: EatTask? = null
init {
listen {
- val reason = reasonEating(eat)
+ val reason = runSafeAutomated { reasonEating() }
if (eatTask != null || !reason.shouldEat()) return@listen
- val task = eat(eat, inventory)
+ val task = eat()
task.finally { eatTask = null }
task.run()
eatTask = task
diff --git a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt
index 2c7cf84fc..f4271d6bc 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt
@@ -28,7 +28,6 @@ import com.lambda.interaction.request.rotating.Rotation.Companion.rotation
import com.lambda.interaction.request.rotating.RotationRequest
import com.lambda.interaction.request.rotating.visibilty.lookAt
import com.lambda.module.Module
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.module.tag.ModuleTag
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.NamedEnum
@@ -45,7 +44,7 @@ object FastBreak : Module(
Build("Build")
}
- private val buildConfig = BuildSettings(this, Group.Build)
+ override val buildConfig = BuildSettings(this, Group.Build)
private val pendingInteractions = ConcurrentLinkedQueue()
@@ -61,15 +60,15 @@ object FastBreak : Module(
val breakContext = BreakContext(
hitResult,
- RotationRequest(lookAt(player.rotation), TaskFlowModule.rotation),
+ RotationRequest(lookAt(player.rotation), this@FastBreak),
player.inventory.selectedSlot,
player.mainHandStack.select(),
- state.calcBlockBreakingDelta(player, world, pos) >= buildConfig.breaking.breakThreshold,
+ state.calcBlockBreakingDelta(player, world, pos) >= buildConfig.breakConfig.breakThreshold,
state,
- buildConfig.breaking.sorter
+ buildConfig.breakConfig.sorter
)
- BreakRequest(setOf(breakContext), pendingInteractions, buildConfig).submit()
+ BreakRequest(setOf(breakContext), pendingInteractions, this@FastBreak).submit()
}
}
}
diff --git a/src/main/kotlin/com/lambda/module/modules/player/Freecam.kt b/src/main/kotlin/com/lambda/module/modules/player/Freecam.kt
index b6b9c6f5c..a0a73c212 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/Freecam.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/Freecam.kt
@@ -18,7 +18,6 @@
package com.lambda.module.modules.player
import com.lambda.Lambda.mc
-import com.lambda.event.events.ConnectionEvent
import com.lambda.event.events.MovementEvent
import com.lambda.event.events.PlayerEvent
import com.lambda.event.events.RenderEvent
@@ -58,7 +57,7 @@ object Freecam : Module(
private val reach by setting("Reach", 10.0, 1.0..100.0, 1.0, "Freecam reach distance")
private val rotateToTarget by setting("Rotate to target", true)
- private val rotationConfig = RotationConfig.Instant(RotationMode.Lock)
+ override val rotationConfig = RotationConfig.Instant(RotationMode.Lock)
private var lastPerspective = Perspective.FIRST_PERSON
private var prevPosition: Vec3d = Vec3d.ZERO
@@ -101,7 +100,7 @@ object Freecam : Module(
if (!rotateToTarget) return@listen
mc.crosshairTarget?.let {
- lookAtHit(it)?.requestBy(rotationConfig)
+ lookAtHit(it)?.requestBy(this@Freecam)
}
}
diff --git a/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt b/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt
index 38f3cf27c..2c746fccc 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt
@@ -69,12 +69,12 @@ object HighwayTools : Module(
private val distance by setting("Distance", -1, -1..1000000, 1, "Distance to build the highway/tunnel (negative for infinite)").group(Group.Structure)
private val sliceSize by setting("Slice Size", 3, 1..5, 1, "Number of slices to build at once").group(Group.Structure)
- private val build = BuildSettings(this, Group.Build)
- private val rotation = RotationSettings(this, Group.Rotation)
- private val interact = InteractionSettings(this, Group.Interaction, InteractionMask.Block)
- private val inventory = InventorySettings(this, Group.Inventory)
- private val hotbar = HotbarSettings(this, Group.Hotbar)
- private val eat = EatSettings(this, Group.Eat)
+ override val buildConfig = BuildSettings(this, Group.Build)
+ override val rotationConfig = RotationSettings(this, Group.Rotation)
+ override val interactionConfig = InteractionSettings(this, Group.Interaction, InteractionMask.Block)
+ override val inventoryConfig = InventorySettings(this, Group.Inventory)
+ override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
+ override val eatConfig = EatSettings(this, Group.Eat)
private var octant = EightWayDirection.NORTH
private var distanceMoved = 0
@@ -141,16 +141,8 @@ object HighwayTools : Module(
disable()
emptyStructure()
}
- }.build(
- collectDrops = build.collectDrops,
- build = build,
- rotation = rotation,
- interact = interact,
- inventory = inventory,
- hotbar = hotbar,
- eat = eat,
- lifeMaintenance = true,
- ).run()
+ }.build(collectDrops = buildConfig.collectDrops, lifeMaintenance = true)
+ .run()
}
private fun generateSlice(): Structure {
diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt
index ff2841811..a653a957b 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt
@@ -50,7 +50,7 @@ object InventoryMove : Module(
) {
private val arrowKeys by setting("Arrow Keys", false, "Allows rotating the players camera using the arrow keys")
private val speed by setting("Rotation Speed", 5, 1..20, 1, unit = "°/tick") { arrowKeys }
- private val rotationConfig = RotationConfig.Instant(RotationMode.Lock)
+ override val rotationConfig = RotationConfig.Instant(RotationMode.Lock)
@JvmStatic
val shouldMove get() = isEnabled && !mc.currentScreen.hasInputOrNull
@@ -78,7 +78,7 @@ object InventoryMove : Module(
lookAt(
Rotation(player.yaw + yaw, (player.pitch + pitch).coerceIn(-90f, 90f))
- ).requestBy(rotationConfig)
+ ).requestBy(this@InventoryMove)
}
}
diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt
index 5dfbc2129..a110f7be4 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt
@@ -46,7 +46,7 @@ object InventoryTweaks : Module(
private val instantShulker by setting("Instant Shulker", true, description = "Right-click shulker boxes in your inventory to instantly place them and open them.").group(Group.General)
private val instantEChest by setting("Instant Ender-Chest", true, description = "Right-click ender chests in your inventory to instantly place them and open them.").group(Group.General)
- private val inventory = InventorySettings(this, Group.Inventory)
+ override val inventoryConfig = InventorySettings(this, Group.Inventory)
private var placedPos: BlockPos? = null
private var placeAndOpen: Task<*>? = null
private var lastBreak: Task<*>? = null
@@ -59,9 +59,9 @@ object InventoryTweaks : Module(
if (!(instantShulker && stack.item in shulkerBoxes) && !(instantEChest && stack.item == Items.ENDER_CHEST)) return@listen
it.cancel()
lastOpenScreen = null
- placeAndOpen = PlaceContainer(stack, inventory = inventory).then { placePos ->
+ placeAndOpen = PlaceContainer(stack, this@InventoryTweaks).then { placePos ->
placedPos = placePos
- OpenContainer(placePos).finally { screenHandler ->
+ OpenContainer(placePos, this@InventoryTweaks).finally { screenHandler ->
lastOpenScreen = screenHandler
}
}.run()
diff --git a/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt b/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt
index 6da8e7459..7823377d8 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt
@@ -17,11 +17,12 @@
package com.lambda.module.modules.player
+import com.lambda.context.AutomationConfig
+import com.lambda.context.breakConfig
import com.lambda.interaction.BaritoneManager
import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint
import com.lambda.interaction.construction.verify.TargetState
import com.lambda.module.Module
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.module.tag.ModuleTag
import com.lambda.task.RootTask.run
import com.lambda.task.Task
@@ -53,7 +54,7 @@ object Nuker : Module(
.map { it.blockPos }
.filter { !world.isAir(it) }
.filter { !flatten || it.y >= player.blockPos.y }
- .filter { !instantOnly || blockState(it).getHardness(world, it) <= TaskFlowModule.build.breaking.breakThreshold }
+ .filter { !instantOnly || blockState(it).getHardness(world, it) <= AutomationConfig.breakConfig.breakThreshold }
.filter { pos ->
if (!baritoneSelection) true
else BaritoneManager.primary.selectionManager.selections.any {
diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt
index 05b2c9fa6..776f03eb8 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt
@@ -23,6 +23,7 @@ import com.lambda.config.groups.InteractionSettings
import com.lambda.config.groups.InventorySettings
import com.lambda.config.groups.RotationSettings
import com.lambda.context.SafeContext
+import com.lambda.context.breakConfig
import com.lambda.event.events.PlayerEvent
import com.lambda.event.events.TickEvent
import com.lambda.event.events.onStaticRender
@@ -36,6 +37,7 @@ import com.lambda.interaction.construction.verify.TargetState
import com.lambda.interaction.request.breaking.BreakRequest.Companion.breakRequest
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.Describable
import com.lambda.util.NamedEnum
@@ -70,12 +72,11 @@ object PacketMine : Module(
.onValueChange { _, to -> if (!to) queuePositions.clear() }
private val queueOrder by setting("Queue Order", QueueOrder.Standard, "Which end of the queue to break blocks from") { queue }.group(Group.General)
- private val build = BuildSettings(this, Group.Build)
- private val breakConfig = build.breaking
- private val rotation = RotationSettings(this, Group.Rotation)
- private val interact = InteractionSettings(this, Group.Interaction, InteractionMask.Block)
- private val inventory = InventorySettings(this, Group.Inventory)
- private val hotbar = HotbarSettings(this, Group.Hotbar)
+ override val buildConfig = BuildSettings(this, Group.Build)
+ override val rotationConfig = RotationSettings(this, Group.Rotation)
+ override val interactionConfig = InteractionSettings(this, Group.Interaction, InteractionMask.Block)
+ override val inventoryConfig = InventorySettings(this, Group.Inventory)
+ override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
private val renderQueue by setting("Render Queue", true, "Adds renders to signify what block positions are queued").group(Group.Render)
private val renderSize by setting("Render Size", 0.3f, 0.01f..1f, 0.01f, "The scale of the queue renders") { renderQueue }.group(Group.Render)
@@ -192,9 +193,7 @@ object PacketMine : Module(
if (!reBreaking) {
queuePositions.retainAllPositions(breakContexts)
}
- breakRequest(
- breakContexts, pendingInteractions, rotation, hotbar, interact, inventory, build,
- ) {
+ breakRequest(breakContexts, pendingInteractions) {
onStart { onProgress(it) }
onUpdate { onProgress(it) }
onStop { removeBreak(it); breaks++ }
@@ -212,16 +211,18 @@ object PacketMine : Module(
}
private fun SafeContext.breakContexts(positions: Collection) =
- positions
- .asSequence()
- .filterNotNull()
- .associateWith { TargetState.State(blockState(it).fluidState.blockState) }
- .toBlueprint()
- .simulate(player.eyePos, interact, rotation, inventory, build)
- .asSequence()
- .filterIsInstance()
- .map { it.context }
- .toCollection(mutableListOf())
+ runSafeAutomated {
+ positions
+ .asSequence()
+ .filterNotNull()
+ .associateWith { TargetState.State(blockState(it).fluidState.blockState) }
+ .toBlueprint()
+ .simulate(player.eyePos)
+ .asSequence()
+ .filterIsInstance()
+ .map { it.context }
+ .toCollection(mutableListOf())
+ }
private fun addBreak(pos: BlockPos) {
if (breakConfig.doubleBreak && breakPositions[0] != null) {
diff --git a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt
index 906e85994..6242231fe 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt
@@ -71,8 +71,6 @@ import net.minecraft.util.math.Vec3d
import java.io.File
import java.lang.reflect.Type
import java.time.format.DateTimeFormatter
-import kotlin.collections.removeFirstOrNull
-import kotlin.collections.take
import kotlin.io.path.pathString
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
@@ -100,7 +98,7 @@ object Replay : Module(
private val deviationThreshold by setting("Deviation threshold", 0.1, 0.1..5.0, 0.1, description = "The threshold for the deviation to cancel the replay.") { cancelOnDeviation }
private val lockCamera by setting("Lock Camera", true)
- private val rotationConfig = object : RotationConfig.Instant(RotationMode.Sync) {
+ override val rotationConfig = object : RotationConfig.Instant(RotationMode.Sync) {
override val rotationMode = if (lockCamera) RotationMode.Lock else RotationMode.Sync
}
@@ -187,7 +185,7 @@ object Replay : Module(
State.PLAYING -> {
buffer?.rotation?.removeFirstOrNull()?.let { rot ->
- lookAt(rot).requestBy(rotationConfig)
+ lookAt(rot).requestBy(this@Replay)
}
}
diff --git a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt
index 2d59eac94..b4447e1e6 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt
@@ -45,8 +45,7 @@ object RotationLock : Module(
private val pitchStep by setting("Pitch Step", 45.0, 1.0..90.0, 1.0) { pitchMode == RotationMode.Snap }.group(Group.General)
private val customPitch by setting("Custom Pitch", 0.0, -90.0..90.0, 1.0) { pitchMode == RotationMode.Custom }.group(Group.General)
- @JvmStatic val rotationSettings = RotationSettings(this, Group.Rotation)
- private var rotationRequest: RotationRequest? = null
+ override val rotationConfig = RotationSettings(this, Group.Rotation)
init {
listen {
@@ -67,7 +66,7 @@ object RotationLock : Module(
RotationMode.None -> player.pitch.toDouble()
}
- RotationRequest(lookAt(Rotation(yaw, pitch), 0.001), rotationSettings).submit()
+ RotationRequest(lookAt(Rotation(yaw, pitch), 0.001), this@RotationLock).submit()
}
}
diff --git a/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt
index 9b6544e37..f026caa7d 100644
--- a/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt
+++ b/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt
@@ -35,6 +35,7 @@ import com.lambda.interaction.request.Request.Companion.submit
import com.lambda.interaction.request.placing.PlaceRequest
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.BlockUtils.blockPos
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.KeyCode
@@ -63,11 +64,11 @@ object Scaffold : Module(
private val onlyBelow by setting("Only Below", true, "Restricts bridging to only below the player to avoid place spam if it's impossible to reach the supporting position") { bridgeRange > 0 }.group(Group.General)
private val descend by setting("Descend", KeyCode.UNBOUND, "Lower the place position by one to allow the player to lower y level").group(Group.General)
private val descendAmount by setting("Descend Amount", 1, 1..5, 1, "The amount to lower the place position by when descending", unit = " blocks") { descend != KeyCode.UNBOUND }.group(Group.General)
- private val buildConfig = BuildSettings(this, Group.Build)
- private val rotationConfig = RotationSettings(this, Group.Rotation)
- private val interactionConfig = InteractionSettings(this, Group.Interaction, InteractionMask.Block)
- private val hotbarConfig = HotbarSettings(this, Group.Hotbar)
- private val inventoryConfig = InventorySettings(this, Group.Inventory)
+ override val buildConfig = BuildSettings(this, Group.Build)
+ override val rotationConfig = RotationSettings(this, Group.Rotation)
+ override val interactionConfig = InteractionSettings(this, Group.Interaction, InteractionMask.Block)
+ override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
+ override val inventoryConfig = InventorySettings(this, Group.Inventory)
private val pendingActions = ConcurrentLinkedQueue()
@@ -78,21 +79,21 @@ object Scaffold : Module(
if (alreadySupported) return@listen
val offset = if (isKeyPressed(descend.code)) descendAmount else 0
val beneath = playerSupport.down(offset)
- scaffoldPositions(beneath)
- .associateWith { TargetState.Solid }
- .toBlueprint()
- .simulate(player.eyePos, interactionConfig, rotationConfig, inventoryConfig, buildConfig)
- .filterIsInstance()
- .minByOrNull { it.blockPos distSq beneath }
- ?.let { result ->
- submit(PlaceRequest(
- setOf(result.context),
- pendingActions,
- buildConfig,
- hotbarConfig,
- rotationConfig
- ))
- }
+ runSafeAutomated {
+ scaffoldPositions(beneath)
+ .associateWith { TargetState.Solid }
+ .toBlueprint()
+ .simulate(player.eyePos)
+ .filterIsInstance()
+ .minByOrNull { it.blockPos distSq beneath }
+ ?.let { result ->
+ submit(PlaceRequest(
+ setOf(result.context),
+ pendingActions,
+ this@Scaffold
+ ))
+ }
+ }
}
listen {
@@ -103,7 +104,7 @@ object Scaffold : Module(
private fun SafeContext.scaffoldPositions(beneath: BlockPos): List {
if (!blockState(beneath).isReplaceable) return emptyList()
- if (buildConfig.placing.airPlace.isEnabled) return listOf(beneath)
+ if (buildConfig.placeConfig.airPlace.isEnabled) return listOf(beneath)
return BlockPos.iterateOutwards(beneath, bridgeRange, bridgeRange, bridgeRange)
.asSequence()
diff --git a/src/main/kotlin/com/lambda/network/CapeManager.kt b/src/main/kotlin/com/lambda/network/CapeManager.kt
index e12b9ef53..2a0ea7200 100644
--- a/src/main/kotlin/com/lambda/network/CapeManager.kt
+++ b/src/main/kotlin/com/lambda/network/CapeManager.kt
@@ -23,7 +23,6 @@ import com.lambda.context.SafeContext
import com.lambda.core.Loadable
import com.lambda.event.events.WorldEvent
import com.lambda.event.listener.SafeListener.Companion.listen
-import com.lambda.graphics.texture.TextureUtils
import com.lambda.network.api.v1.endpoints.getCape
import com.lambda.network.api.v1.endpoints.getCapes
import com.lambda.network.api.v1.endpoints.setCape
diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt
index dc2497a3f..983c5ec24 100644
--- a/src/main/kotlin/com/lambda/task/Task.kt
+++ b/src/main/kotlin/com/lambda/task/Task.kt
@@ -18,12 +18,12 @@
package com.lambda.task
import com.lambda.Lambda.LOG
+import com.lambda.context.AutomationConfig
import com.lambda.context.SafeContext
import com.lambda.event.EventFlow.unsubscribe
import com.lambda.event.Muteable
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.threading.runSafe
import com.lambda.util.Communication.logError
import com.lambda.util.Nameable
@@ -127,7 +127,7 @@ abstract class Task : Nameable, Muteable {
fun success(result: Result) {
unsubscribe()
state = State.COMPLETED
- if (!TaskFlowModule.showAllEntries) parent?.subTasks?.remove(this)
+ if (!AutomationConfig.showAllEntries) parent?.subTasks?.remove(this)
runSafe {
executeNextTask(result)
}
diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterial.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireMaterial.kt
index 6914b2dd9..399ea9ece 100644
--- a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterial.kt
+++ b/src/main/kotlin/com/lambda/task/tasks/AcquireMaterial.kt
@@ -17,23 +17,23 @@
package com.lambda.task.tasks
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.ContainerManager
import com.lambda.interaction.material.container.ContainerManager.findContainerWithMaterial
import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.task.Task
class AcquireMaterial @Ta5kBuilder constructor(
val selection: StackSelection,
- val inventory: InventoryConfig
-) : Task() {
+ automated: Automated
+) : Task(), Automated by automated {
override val name: String
get() = "Acquiring $selection"
override fun SafeContext.onStart() {
- selection.findContainerWithMaterial(inventory)
+ selection.findContainerWithMaterial()
?.withdraw(selection)
?.finally {
success(selection)
@@ -43,7 +43,7 @@ class AcquireMaterial @Ta5kBuilder constructor(
companion object {
@Ta5kBuilder
- fun acquire(selection: () -> StackSelection) =
- AcquireMaterial(selection(), TaskFlowModule.inventory)
+ fun Automated.acquire(selection: () -> StackSelection) =
+ AcquireMaterial(selection(), this)
}
}
diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt
index 0a5303702..46033ba3c 100644
--- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt
+++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt
@@ -19,10 +19,9 @@ package com.lambda.task.tasks
import baritone.api.pathing.goals.GoalBlock
import com.lambda.Lambda.LOG
-import com.lambda.config.groups.BuildConfig
-import com.lambda.config.groups.EatConfig
import com.lambda.config.groups.EatConfig.Companion.reasonEating
-import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.Automated
+import com.lambda.context.AutomationConfig
import com.lambda.context.SafeContext
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
@@ -46,14 +45,11 @@ import com.lambda.interaction.construction.simulation.Simulation.Companion.simul
import com.lambda.interaction.construction.verify.TargetState
import com.lambda.interaction.material.transfer.TransactionExecutor.Companion.transfer
import com.lambda.interaction.request.breaking.BreakRequest.Companion.breakRequest
-import com.lambda.interaction.request.hotbar.HotbarConfig
import com.lambda.interaction.request.interacting.InteractRequest
-import com.lambda.interaction.request.inventory.InventoryConfig
import com.lambda.interaction.request.placing.PlaceRequest
-import com.lambda.interaction.request.rotating.RotationConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.task.Task
import com.lambda.task.tasks.EatTask.Companion.eat
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.Formatting.string
import com.lambda.util.extension.Structure
import com.lambda.util.extension.inventorySlots
@@ -67,21 +63,14 @@ class BuildTask private constructor(
private val blueprint: Blueprint,
private val finishOnDone: Boolean,
private val collectDrops: Boolean,
- private val build: BuildConfig,
- private val rotation: RotationConfig,
- private val interactionConfig: InteractionConfig,
- private val inventory: InventoryConfig,
- private val hotbar: HotbarConfig,
- private val eat: EatConfig,
private val lifeMaintenance: Boolean,
-) : Task() {
+ automated: Automated
+) : Task(), Automated by automated {
override val name: String get() = "Building $blueprint with ${(breaks / (age / 20.0 + 0.001)).string} b/s ${(placements / (age / 20.0 + 0.001)).string} p/s"
private val pendingInteractions = ConcurrentLinkedQueue()
- private val emptyPendingInteractionSlots
- get() = (build.maxPendingInteractions - pendingInteractions.size).coerceAtLeast(0)
private val atMaxPendingInteractions
- get() = pendingInteractions.size >= build.maxPendingInteractions
+ get() = pendingInteractions.size >= buildConfig.maxPendingInteractions
private var placements = 0
private var breaks = 0
@@ -100,8 +89,8 @@ class BuildTask private constructor(
init {
listen {
when {
- lifeMaintenance && eatTask == null && reasonEating(eat).shouldEat() -> {
- eatTask = eat(eat)
+ lifeMaintenance && eatTask == null && runSafeAutomated { reasonEating() }.shouldEat() -> {
+ eatTask = eat()
eatTask?.finally {
eatTask = null
}?.execute(this@BuildTask)
@@ -116,9 +105,9 @@ class BuildTask private constructor(
if (collectDrops()) return@listen
- val results = blueprint.simulate(player.eyePos, interactionConfig, rotation, inventory, build)
+ val results = runSafeAutomated { blueprint.simulate(player.eyePos) }
- TaskFlowModule.drawables = results
+ AutomationConfig.drawables = results
.filterIsInstance()
.plus(pendingInteractions.toList())
@@ -142,14 +131,14 @@ class BuildTask private constructor(
is BuildResult.NotVisible,
is PlaceResult.NoIntegrity -> {
- if (!build.pathing) return@listen
- val sim = blueprint.simulation(interactionConfig, rotation, inventory, build)
+ if (!buildConfig.pathing) return@listen
+ val sim = blueprint.simulation()
val goal = BuildGoal(sim, player.blockPos)
BaritoneManager.setGoalAndPath(goal)
}
is Navigable -> {
- if (build.pathing) BaritoneManager.setGoalAndPath(bestResult.goal)
+ if (buildConfig.pathing) BaritoneManager.setGoalAndPath(bestResult.goal)
}
is BuildResult.Contextual -> {
@@ -160,9 +149,7 @@ class BuildTask private constructor(
.filterIsInstance()
.map { it.context }
- breakRequest(
- breakResults, pendingInteractions, rotation, hotbar, interactionConfig, inventory, build,
- ) {
+ breakRequest(breakResults, pendingInteractions) {
onStop { breaks++ }
onItemDrop?.let { onItemDrop ->
onItemDrop { onItemDrop(it) }
@@ -175,14 +162,23 @@ class BuildTask private constructor(
.filterIsInstance()
.map { it.context }
- PlaceRequest(placeResults, pendingInteractions, build, hotbar, rotation) { placements++ }.submit()
+ PlaceRequest(
+ placeResults,
+ pendingInteractions,
+ this@BuildTask
+ ) { placements++ }.submit()
}
is InteractResult.Interact -> {
val interactResults = resultsNotBlocked
.filterIsInstance()
.map { it.context }
- InteractRequest(interactResults, null, pendingInteractions, build.interacting, build, hotbar, rotation).submit()
+ InteractRequest(
+ interactResults,
+ pendingInteractions,
+ this@BuildTask,
+ null
+ ).submit()
}
}
}
@@ -217,7 +213,7 @@ class BuildTask private constructor(
if (player.hotbarAndStorage.none { it.isEmpty }) {
val stackToThrow = player.currentScreenHandler.inventorySlots.firstOrNull {
- it.stack.item.block in TaskFlowModule.inventory.disposables
+ it.stack.item.block in inventoryConfig.disposables
} ?: run {
failure("No item in inventory to throw but inventory is full and cant pick up item drop")
return@let true
@@ -240,77 +236,49 @@ class BuildTask private constructor(
companion object {
@Ta5kBuilder
- fun build(
+ fun Automated.build(
finishOnDone: Boolean = true,
- collectDrops: Boolean = TaskFlowModule.build.collectDrops,
- build: BuildConfig = TaskFlowModule.build,
- rotation: RotationConfig = TaskFlowModule.rotation,
- interact: InteractionConfig = TaskFlowModule.interaction,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- hotbar: HotbarConfig = TaskFlowModule.hotbar,
- eat: EatConfig = TaskFlowModule.eat,
+ collectDrops: Boolean = AutomationConfig.buildConfig.collectDrops,
lifeMaintenance: Boolean = false,
- blueprint: () -> Blueprint,
- ) = BuildTask(blueprint(), finishOnDone, collectDrops, build, rotation, interact, inventory, hotbar, eat, lifeMaintenance)
+ blueprint: () -> Blueprint
+ ) = BuildTask(blueprint(), finishOnDone, collectDrops, lifeMaintenance, this)
@Ta5kBuilder
+ context(automated: Automated)
fun Structure.build(
finishOnDone: Boolean = true,
- collectDrops: Boolean = TaskFlowModule.build.collectDrops,
- build: BuildConfig = TaskFlowModule.build,
- rotation: RotationConfig = TaskFlowModule.rotation,
- interact: InteractionConfig = TaskFlowModule.interaction,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- hotbar: HotbarConfig = TaskFlowModule.hotbar,
- eat: EatConfig = TaskFlowModule.eat,
- lifeMaintenance: Boolean = false,
- ) = BuildTask(toBlueprint(), finishOnDone, collectDrops, build, rotation, interact, inventory, hotbar, eat, lifeMaintenance)
+ collectDrops: Boolean = AutomationConfig.buildConfig.collectDrops,
+ lifeMaintenance: Boolean = false
+ ) = BuildTask(toBlueprint(), finishOnDone, collectDrops, lifeMaintenance, automated)
@Ta5kBuilder
+ context(automated: Automated)
fun Blueprint.build(
finishOnDone: Boolean = true,
- collectDrops: Boolean = TaskFlowModule.build.collectDrops,
- build: BuildConfig = TaskFlowModule.build,
- rotation: RotationConfig = TaskFlowModule.rotation,
- interact: InteractionConfig = TaskFlowModule.interaction,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- hotbar: HotbarConfig = TaskFlowModule.hotbar,
- eat: EatConfig = TaskFlowModule.eat,
- lifeMaintenance: Boolean = false,
- ) = BuildTask(this, finishOnDone, collectDrops, build, rotation, interact, inventory, hotbar, eat, lifeMaintenance)
+ collectDrops: Boolean = AutomationConfig.buildConfig.collectDrops,
+ lifeMaintenance: Boolean = false
+ ) = BuildTask(this, finishOnDone, collectDrops, lifeMaintenance, automated)
@Ta5kBuilder
- fun breakAndCollectBlock(
+ fun Automated.breakAndCollectBlock(
blockPos: BlockPos,
finishOnDone: Boolean = true,
collectDrops: Boolean = true,
- build: BuildConfig = TaskFlowModule.build,
- rotation: RotationConfig = TaskFlowModule.rotation,
- interact: InteractionConfig = TaskFlowModule.interaction,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- hotbar: HotbarConfig = TaskFlowModule.hotbar,
- eat: EatConfig = TaskFlowModule.eat,
- lifeMaintenance: Boolean = false,
+ lifeMaintenance: Boolean = false
) = BuildTask(
blockPos.toStructure(TargetState.Air).toBlueprint(),
- finishOnDone, collectDrops, build, rotation, interact, inventory, hotbar, eat, lifeMaintenance
+ finishOnDone, collectDrops, lifeMaintenance, this
)
@Ta5kBuilder
- fun breakBlock(
+ fun Automated.breakBlock(
blockPos: BlockPos,
finishOnDone: Boolean = true,
- collectDrops: Boolean = TaskFlowModule.build.collectDrops,
- build: BuildConfig = TaskFlowModule.build,
- rotation: RotationConfig = TaskFlowModule.rotation,
- interact: InteractionConfig = TaskFlowModule.interaction,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- hotbar: HotbarConfig = TaskFlowModule.hotbar,
- eat: EatConfig = TaskFlowModule.eat,
- lifeMaintenance: Boolean = false,
+ collectDrops: Boolean = AutomationConfig.buildConfig.collectDrops,
+ lifeMaintenance: Boolean = false
) = BuildTask(
blockPos.toStructure(TargetState.Air).toBlueprint(),
- finishOnDone, collectDrops, build, rotation, interact, inventory, hotbar, eat, lifeMaintenance
+ finishOnDone, collectDrops, lifeMaintenance, this
)
}
}
diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt
index 51678c7f2..b9e6c4f37 100644
--- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt
+++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt
@@ -19,24 +19,21 @@ package com.lambda.task.tasks
import com.lambda.config.groups.EatConfig
import com.lambda.config.groups.EatConfig.Companion.reasonEating
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
-import com.lambda.interaction.material.StackSelection.Companion.selectStack
import com.lambda.interaction.material.container.ContainerManager.transfer
import com.lambda.interaction.material.container.containers.MainHandContainer
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.task.Task
-import com.lambda.util.item.ItemUtils.nutrition
+import com.lambda.threading.runSafeAutomated
import net.minecraft.item.ItemStack
import net.minecraft.util.ActionResult
import net.minecraft.util.Hand
class EatTask @Ta5kBuilder constructor(
- val config: EatConfig,
- val inventory: InventoryConfig
-) : Task() {
+ automated: Automated
+) : Task(), Automated by automated {
override val name: String
get() = reason.message(eatStack ?: ItemStack.EMPTY)
@@ -45,12 +42,12 @@ class EatTask @Ta5kBuilder constructor(
private var holdingUse = false
override fun SafeContext.onStart() {
- reason = reasonEating(config)
+ reason = runSafeAutomated { reasonEating() }
}
init {
listen {
- if (holdingUse && !reason.shouldKeepEating(config, eatStack)) {
+ if (holdingUse && !reason.shouldKeepEating(eatStack)) {
mc.options.useKey.isPressed = false
holdingUse = false
interaction.stopUsingItem(player)
@@ -66,13 +63,13 @@ class EatTask @Ta5kBuilder constructor(
return@listen
}
- val foodFinder = reason.selector(config)
+ val foodFinder = reason.selector()
if (!foodFinder.matches(player.mainHandStack)) {
if (holdingUse) {
mc.options.useKey.isPressed = false
holdingUse = false
}
- foodFinder.transfer(MainHandContainer, inventory)
+ foodFinder.transfer(MainHandContainer)
?.execute(this@EatTask) ?: failure("No food found")
return@listen
}
@@ -89,9 +86,7 @@ class EatTask @Ta5kBuilder constructor(
companion object {
@Ta5kBuilder
- fun eat(
- config: EatConfig = TaskFlowModule.eat,
- inventory: InventoryConfig = TaskFlowModule.inventory,
- ) = EatTask(config, inventory)
+ context(automated: Automated)
+ fun eat() = EatTask(automated)
}
}
diff --git a/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt b/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt
index d1b2b4522..8428a05c6 100644
--- a/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt
+++ b/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt
@@ -17,14 +17,12 @@
package com.lambda.task.tasks
-import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.Automated
+import com.lambda.context.interactConfig
import com.lambda.event.events.InventoryEvent
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
-import com.lambda.interaction.request.interacting.InteractConfig
-import com.lambda.interaction.request.rotating.RotationConfig
import com.lambda.interaction.request.rotating.visibilty.lookAtBlock
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.task.Task
import com.lambda.util.world.raycast.RayCastUtils.blockResult
import net.minecraft.screen.ScreenHandler
@@ -34,12 +32,10 @@ import net.minecraft.util.math.Direction
class OpenContainer @Ta5kBuilder constructor(
private val blockPos: BlockPos,
+ private val automated: Automated,
private val waitForSlotLoad: Boolean = true,
- private val rotation: RotationConfig = TaskFlowModule.rotation,
- private val interact: InteractConfig = TaskFlowModule.build.interacting,
- private val interactionConfig: InteractionConfig = TaskFlowModule.interaction,
- private val sides: Set = Direction.entries.toSet(),
-) : Task() {
+ private val sides: Set = Direction.entries.toSet()
+) : Task(), Automated by automated {
override val name get() = "${containerState.description(inScope)} at ${blockPos.toShortString()}"
private var screenHandler: ScreenHandler? = null
@@ -84,8 +80,8 @@ class OpenContainer @Ta5kBuilder constructor(
listen {
if (containerState != State.SCOPING) return@listen
- val target = lookAtBlock(blockPos, sides, config = interactionConfig)
- if (interact.rotate && !target.requestBy(rotation).done) return@listen
+ val target = lookAtBlock(blockPos, sides)
+ if (interactConfig.rotate && !target.requestBy(this@OpenContainer).done) return@listen
val hitResult = target.hit?.hitIfValid()?.blockResult ?: return@listen
interaction.interactBlock(player, Hand.MAIN_HAND, hitResult)
diff --git a/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt b/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt
index 9d06ba957..a8b59dbf7 100644
--- a/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt
+++ b/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt
@@ -17,24 +17,19 @@
package com.lambda.task.tasks
-import com.lambda.config.groups.BuildConfig
-import com.lambda.config.groups.InteractionConfig
+import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint
-import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint
import com.lambda.interaction.construction.result.BuildResult
import com.lambda.interaction.construction.result.PlaceResult
import com.lambda.interaction.construction.simulation.BuildSimulator.simulate
import com.lambda.interaction.construction.verify.TargetState
import com.lambda.interaction.request.ManagerUtils
-import com.lambda.interaction.request.inventory.InventoryConfig
-import com.lambda.interaction.request.rotating.RotationConfig
-import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.task.Task
import com.lambda.task.tasks.BuildTask.Companion.build
+import com.lambda.threading.runSafeAutomated
import com.lambda.util.BlockUtils.blockPos
-import com.lambda.util.BlockUtils.blockState
import com.lambda.util.item.ItemUtils.shulkerBoxes
import com.lambda.util.math.distSq
import net.minecraft.block.ChestBlock
@@ -46,24 +41,23 @@ import net.minecraft.util.math.Direction
class PlaceContainer @Ta5kBuilder constructor(
val stack: ItemStack,
- val build: BuildConfig = TaskFlowModule.build,
- val rotation: RotationConfig = TaskFlowModule.rotation,
- val interact: InteractionConfig = TaskFlowModule.interaction,
- val inventory: InventoryConfig = TaskFlowModule.inventory
-) : Task() {
+ automated: Automated
+) : Task(), Automated by automated {
private val startStack: ItemStack = stack.copy()
override val name: String get() = "Placing container ${startStack.name.string}"
override fun SafeContext.onStart() {
- val results = BlockPos.iterateOutwards(player.blockPos, 4, 3, 4)
- .map { it.blockPos }
- .asSequence()
- .filter { !ManagerUtils.isPosBlocked(it) }
- .flatMap {
- it.toStructure(TargetState.Stack(startStack))
- .toBlueprint()
- .simulate(player.eyePos)
- }
+ val results = runSafeAutomated {
+ BlockPos.iterateOutwards(player.blockPos, 4, 3, 4)
+ .map { it.blockPos }
+ .asSequence()
+ .filter { !ManagerUtils.isPosBlocked(it) }
+ .flatMap {
+ it.toStructure(TargetState.Stack(startStack))
+ .toBlueprint()
+ .simulate(player.eyePos)
+ }
+ }
val options = results.filterIsInstance().filter {
canBeOpened(startStack, it.blockPos, it.context.result.side)
@@ -81,16 +75,9 @@ class PlaceContainer @Ta5kBuilder constructor(
containerPosition
.toStructure(TargetState.Stack(startStack))
.toBlueprint()
- .build(
- finishOnDone = true,
- collectDrops = false,
- build = build,
- rotation = rotation,
- interact = interact,
- inventory = inventory
- ).finally {
- success(containerPosition)
- }.execute(this@PlaceContainer)
+ .build(finishOnDone = true, collectDrops = false)
+ .finally { success(containerPosition) }
+ .execute(this@PlaceContainer)
}
private fun SafeContext.canBeOpened(
diff --git a/src/main/kotlin/com/lambda/threading/Threading.kt b/src/main/kotlin/com/lambda/threading/Threading.kt
index 7c8e1dfcc..3d266b766 100644
--- a/src/main/kotlin/com/lambda/threading/Threading.kt
+++ b/src/main/kotlin/com/lambda/threading/Threading.kt
@@ -18,7 +18,9 @@
package com.lambda.threading
import com.lambda.Lambda.mc
-import com.lambda.context.ClientContext
+import com.lambda.context.Automated
+import com.lambda.context.AutomatedSafeContext
+import com.lambda.context.AutomationConfig
import com.lambda.context.SafeContext
import com.lambda.event.EventFlow
import com.mojang.blaze3d.systems.RenderSystem.isOnRenderThread
@@ -41,8 +43,33 @@ import java.util.concurrent.CompletableFuture
* @param block The block of code to be executed within the safe context.
* @return The result of the block execution if the context is safe, null otherwise.
*/
-inline fun runSafe(block: SafeContext.() -> T) =
- ClientContext().toSafe()?.run(block)
+inline fun runSafe(block: SafeContext.() -> T): T? =
+ SafeContext.create()?.run(block)
+
+@JvmName("runSafeAutomated0")
+context(safeContext: SafeContext)
+inline fun Automated.runSafeAutomated(automated: Automated = this, block: AutomatedSafeContext.() -> T): T =
+ AutomatedSafeContext(safeContext, automated).run(block)
+
+@JvmName("runSafeAutomated1")
+context(automated: Automated)
+inline fun SafeContext.runSafeAutomated(block: AutomatedSafeContext.() -> T): T =
+ AutomatedSafeContext(this, automated).run(block)
+
+@JvmName("runSafeAutomated2")
+context(automated: Automated)
+inline fun runSafeAutomated(block: AutomatedSafeContext.() -> T): T? =
+ SafeContext.create()?.runSafeAutomated(block)
+
+@JvmName("runSafeAutomated3")
+context(safeContext: SafeContext, c: Automated)
+inline fun runSafeAutomated(automated: Automated = c, block: AutomatedSafeContext.() -> T): T =
+ AutomatedSafeContext(safeContext, automated).run(block)
+
+@JvmName("runSafeAutomated4")
+inline fun runSafeAutomated(block: AutomatedSafeContext.() -> T): T? {
+ return AutomatedSafeContext(SafeContext.create() ?: return null, AutomationConfig).run(block)
+}
/**
* This function is used to execute a block of code on a new thread running asynchronously to the game thread.