From 5e32fe9026c37e3ace0d4814efc66bfa9a84f7c0 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:55:21 -0400 Subject: [PATCH 01/16] suspend lambda for concurrent --- common/src/main/kotlin/com/lambda/threading/Threading.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/threading/Threading.kt b/common/src/main/kotlin/com/lambda/threading/Threading.kt index 403bb66bd..39beeb06f 100644 --- a/common/src/main/kotlin/com/lambda/threading/Threading.kt +++ b/common/src/main/kotlin/com/lambda/threading/Threading.kt @@ -60,7 +60,7 @@ inline fun taskContext(crossinline block: suspend () -> Unit) = * * @param block The block of code to be executed within the safe context. */ -inline fun runSafeConcurrent(crossinline block: SafeContext.() -> Unit) { +inline fun runSafeConcurrent(crossinline block: suspend SafeContext.() -> Unit) { EventFlow.lambdaScope.launch { runSafe { block() } } @@ -122,4 +122,4 @@ inline fun runSafeGameConcurrent(crossinline block: SafeContext.() -> Unit) { * @param block The task to be executed on the game's main thread within a safe context. */ suspend inline fun runGameBlocking(noinline block: SafeContext.() -> T) = - CompletableFuture.supplyAsync({ runSafe { block() } }, mc).await() ?: throw IllegalStateException("Unsafe") \ No newline at end of file + CompletableFuture.supplyAsync({ runSafe { block() } }, mc).await() ?: throw IllegalStateException("Unsafe") From f0562680bec0382822410ee5158b05ac7ecb022f Mon Sep 17 00:00:00 2001 From: Constructor Date: Tue, 11 Jun 2024 22:56:05 +0200 Subject: [PATCH 02/16] Instant shulker opener --- .../lambda/mixin/MinecraftClientMixin.java | 4 +- .../ClientPlayInteractionManagerMixin.java | 10 +++ .../lambda/event/events/InteractionEvent.kt | 12 +++ .../lambda/event/events/ScreenHandlerEvent.kt | 5 +- .../construction/simulation/BuildSimulator.kt | 2 +- .../construction/verify/TargetState.kt | 6 +- .../interaction/material/ContainerManager.kt | 4 +- .../material/container/ChestContainer.kt | 4 +- .../material/container/ShulkerBoxContainer.kt | 15 ++-- .../module/modules/player/InventoryTweaks.kt | 85 +++++++++++++++++++ .../src/main/kotlin/com/lambda/task/Task.kt | 6 +- .../com/lambda/task/tasks/BuildStructure.kt | 11 ++- .../lambda/task/tasks/ContainerTransfer.kt | 4 +- .../com/lambda/task/tasks/InventoryTask.kt | 15 ++-- .../com/lambda/task/tasks/OpenContainer.kt | 14 +-- .../com/lambda/task/tasks/PlaceContainer.kt | 42 +++++++-- .../main/kotlin/com/lambda/util/BlockUtils.kt | 2 +- 17 files changed, 193 insertions(+), 48 deletions(-) create mode 100644 common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt diff --git a/common/src/main/java/com/lambda/mixin/MinecraftClientMixin.java b/common/src/main/java/com/lambda/mixin/MinecraftClientMixin.java index 3d2e07027..0200a6e41 100644 --- a/common/src/main/java/com/lambda/mixin/MinecraftClientMixin.java +++ b/common/src/main/java/com/lambda/mixin/MinecraftClientMixin.java @@ -51,7 +51,7 @@ private void onStartup(CallbackInfo ci) { private void onScreenOpen(@Nullable Screen screen, CallbackInfo ci) { if (screen == null) return; if (screen instanceof ScreenHandlerProvider handledScreen) { - EventFlow.post(new ScreenHandlerEvent.Open<>(handledScreen.getScreenHandler())); + EventFlow.post(new ScreenHandlerEvent.Open(handledScreen.getScreenHandler())); } EventFlow.post(new ScreenEvent.Open<>(screen)); @@ -61,7 +61,7 @@ private void onScreenOpen(@Nullable Screen screen, CallbackInfo ci) { private void onScreenRemove(@Nullable Screen screen, CallbackInfo ci) { if (currentScreen == null) return; if (currentScreen instanceof ScreenHandlerProvider handledScreen) { - EventFlow.post(new ScreenHandlerEvent.Close<>(handledScreen.getScreenHandler())); + EventFlow.post(new ScreenHandlerEvent.Close(handledScreen.getScreenHandler())); } EventFlow.post(new ScreenEvent.Close<>(currentScreen)); diff --git a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java index 03da40258..f485cb9f4 100644 --- a/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java @@ -5,6 +5,8 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.screen.slot.SlotActionType; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; @@ -13,6 +15,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(ClientPlayerInteractionManager.class) @@ -27,4 +30,11 @@ public void interactBlockHead(final ClientPlayerEntity player, final Hand hand, if (client.world == null) return; EventFlow.post(new InteractionEvent.Block(client.world, hitResult)); } + + @Inject(method = "clickSlot", at = @At("HEAD"), cancellable = true) + public void clickSlotHead(int syncId, int slotId, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci) { + if (syncId != player.currentScreenHandler.syncId) return; + var click = new InteractionEvent.SlotClick(syncId, slotId, button, actionType, player.currentScreenHandler); + if (EventFlow.post(click).isCanceled()) ci.cancel(); + } } diff --git a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt index 8fce4adc7..9fe2e019e 100644 --- a/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/InteractionEvent.kt @@ -1,7 +1,11 @@ package com.lambda.event.events import com.lambda.event.Event +import com.lambda.event.callback.Cancellable +import com.lambda.event.callback.ICancellable import net.minecraft.client.world.ClientWorld +import net.minecraft.screen.ScreenHandler +import net.minecraft.screen.slot.SlotActionType import net.minecraft.util.hit.BlockHitResult sealed class InteractionEvent : Event { @@ -9,4 +13,12 @@ sealed class InteractionEvent : Event { val world: ClientWorld, val blockHitResult: BlockHitResult ) : InteractionEvent() + + data class SlotClick( + val syncId: Int, + val slot: Int, + val button: Int, + val action: SlotActionType, + val screenHandler: ScreenHandler, + ) : ScreenHandlerEvent(), ICancellable by Cancellable() } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt b/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt index 6e6cf8352..3254efbb3 100644 --- a/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt @@ -5,8 +5,9 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.ScreenHandler sealed class ScreenHandlerEvent : Event { - class Open(val screenHandler: H) : ScreenHandlerEvent() - class Close(val screenHandler: H) : ScreenHandlerEvent() + class Open(val screenHandler: ScreenHandler) : ScreenHandlerEvent() + class Close(val screenHandler: ScreenHandler) : ScreenHandlerEvent() + data class Loaded( val revision: Int, val stacks: List, diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt b/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt index 50ffd268e..65382e963 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt @@ -251,7 +251,7 @@ object BuildSimulator { val currentHandStack = player.getStackInHand(Hand.MAIN_HAND) if (target is TargetState.Stack && !target.itemStack.equal(currentHandStack)) { - acc.add(BuildResult.WrongStack(pos, placeContext, target.copy)) + acc.add(BuildResult.WrongStack(pos, placeContext, target.itemStack)) return@forEach } diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index c07398559..c49b66d52 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -42,12 +42,12 @@ sealed class TargetState : StateMatcher { block.getPickStack(world, pos, block.defaultState) } data class Stack(val itemStack: ItemStack) : TargetState() { - val copy: ItemStack = itemStack.copy() + private val block = itemStack.item.block override fun matches(state: BlockState, pos: BlockPos, world: ClientWorld) = - state.block == copy.item.block + state.block == block override fun getStack(world: ClientWorld, pos: BlockPos): ItemStack = - copy + itemStack } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt b/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt index ad4d35bbf..c3ae91d93 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt @@ -40,9 +40,7 @@ object ContainerManager : Loadable { lastInteractedBlockEntity = it.blockHitResult.blockPos.blockEntity(world) } - listener> { event -> - // ToDo: ;-; i hate type erasure. - // The listener will be triggered for any H, not just GenericContainerScreenHandler + listener { event -> if (event.screenHandler !is GenericContainerScreenHandler) return@listener val handler = event.screenHandler diff --git a/common/src/main/kotlin/com/lambda/interaction/material/container/ChestContainer.kt b/common/src/main/kotlin/com/lambda/interaction/material/container/ChestContainer.kt index 222f589f5..c4e4d5b45 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/container/ChestContainer.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/container/ChestContainer.kt @@ -30,7 +30,7 @@ data class ChestContainer( // } override fun withdraw(selection: StackSelection) = - openContainer(blockPos) + openContainer(blockPos) // .withMaxAttempts(3) // .withTimeout(20) .onSuccess { open, screen -> @@ -39,7 +39,7 @@ data class ChestContainer( } override fun deposit(selection: StackSelection) = - openContainer(blockPos) + openContainer(blockPos) // .withMaxAttempts(3) // .withTimeout(20) .onSuccess { open, screen -> diff --git a/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt b/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt index 53ad4d1dc..5f02c5a40 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt @@ -1,6 +1,5 @@ package com.lambda.interaction.material.container -import com.lambda.Lambda.LOG import com.lambda.context.SafeContext import com.lambda.interaction.material.MaterialContainer import com.lambda.interaction.material.StackSelection @@ -11,7 +10,6 @@ import com.lambda.task.tasks.InventoryTask.Companion.withdraw import com.lambda.task.tasks.OpenContainer.Companion.openContainer import com.lambda.task.tasks.PlaceContainer.Companion.placeContainer import net.minecraft.item.ItemStack -import net.minecraft.screen.ShulkerBoxScreenHandler data class ShulkerBoxContainer( override var stacks: List, @@ -27,10 +25,9 @@ data class ShulkerBoxContainer( private val shulkerStack: ItemStack ) : Task() { override fun SafeContext.onStart() { - placeContainer(shulkerStack).thenRun { _, placePos -> - openContainer(placePos).thenRun { _, screen -> - LOG.info("Opened shulker box screen now withdrawing $selection.") - withdraw(screen, selection).thenRun { _, _ -> + placeContainer(shulkerStack).thenRun(this@Withdraw) { _, placePos -> + openContainer(placePos).thenRun(this@Withdraw) { _, screen -> + withdraw(screen, selection).thenRun(this@Withdraw) { _, _ -> breakAndCollectBlock(placePos).onSuccess { _, _ -> success(Unit) } @@ -47,9 +44,9 @@ data class ShulkerBoxContainer( private val shulkerStack: ItemStack ) : Task() { override fun SafeContext.onStart() { - placeContainer(shulkerStack).thenRun { _, placePos -> - openContainer(placePos).thenRun { _, screen -> - deposit(screen, selection).thenRun { _, _ -> + placeContainer(shulkerStack).thenRun(this@Deposit) { _, placePos -> + openContainer(placePos).thenRun(this@Deposit) { _, screen -> + deposit(screen, selection).thenRun(this@Deposit) { _, _ -> breakAndCollectBlock(placePos).onSuccess { _, _ -> success(Unit) } diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt new file mode 100644 index 000000000..95185f7a5 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -0,0 +1,85 @@ +package com.lambda.module.modules.player + +import com.lambda.context.SafeContext +import com.lambda.event.events.InteractionEvent +import com.lambda.event.events.ScreenHandlerEvent +import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag +import com.lambda.task.Task +import com.lambda.task.tasks.BuildStructure.Companion.breakAndCollectBlock +import com.lambda.task.tasks.OpenContainer.Companion.openContainer +import com.lambda.task.tasks.PlaceContainer.Companion.placeContainer +import com.lambda.util.item.ItemUtils.shulkerBoxes +import com.lambda.util.player.SlotUtils.hotbar +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket +import net.minecraft.screen.slot.SlotActionType +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction + +object InventoryTweaks : Module( + name = "InventoryTweaks", + defaultTags = setOf(ModuleTag.PLAYER) +) { + private val shulkerPeak by setting("Shulker Peek", true, description = "Peek into shulker boxes in your inventory") + private var placedPos: BlockPos? = null + private var lastPlace: Task<*>? = null + private var lastBreak: Task<*>? = null + + init { + listener { + if (!shulkerPeak) return@listener + if (it.action != SlotActionType.PICKUP || it.button != 1) return@listener + val stack = it.screenHandler.getSlot(it.slot).stack + if (stack.item !in shulkerBoxes && stack.item != Items.ENDER_CHEST) return@listener + it.cancel() + move(it.slot, stack) + + player.closeScreen() + + lastPlace = placeContainer(stack).thenRun(null) { _, placePos -> + placedPos = placePos + openContainer(placePos) + }.start(null) + } + + listener { + if (!shulkerPeak) return@listener + placedPos?.let { + lastBreak = breakAndCollectBlock(it).start(null) + placedPos = null + } + } + + onDisable { + lastPlace?.cancel() + lastBreak?.cancel() + } + } + + private fun SafeContext.move(index: Int, stack: ItemStack) { + if (stack == player.mainHandStack) { + return + } + + if (stack == player.offHandStack) { + connection.sendPacket( + PlayerActionC2SPacket( + PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, + BlockPos.ORIGIN, + Direction.DOWN, + ), + ) + return + } + + if (stack in player.hotbar) { + player.inventory.selectedSlot = player.hotbar.indexOf(stack) + return + } + + interaction.pickFromInventory(index) + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/Task.kt b/common/src/main/kotlin/com/lambda/task/Task.kt index 3b1be0c76..ae4db8319 100644 --- a/common/src/main/kotlin/com/lambda/task/Task.kt +++ b/common/src/main/kotlin/com/lambda/task/Task.kt @@ -73,7 +73,7 @@ abstract class Task : Nameable { private var executions = 0 private var attempted = 0 private val subTasks = mutableListOf>() - private var state = State.IDLE + protected var state = State.IDLE var age = 0 private val isDeactivated get() = state == State.DEACTIVATED @@ -385,9 +385,9 @@ abstract class Task : Nameable { * @return The current task instance with the updated success action. */ @Ta5kBuilder - fun thenRun(action: SafeContext.(Task, Result) -> Task<*>): Task { + fun thenRun(owner: Task<*>?, action: SafeContext.(Task, Result) -> Task<*>): Task { this.onSuccess = { task, result -> - action(this, task, result).start(task) + action(this, task, result).start(owner) } return this } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt index 539baaf3c..d33d8973b 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt @@ -21,6 +21,8 @@ class BuildStructure @Ta5kBuilder constructor( private val blueprint: Blueprint, private val finishOnDone: Boolean = true, private val pathing: Boolean = TaskFlow.build.pathing, + private val stayInRange: Boolean = true, + private val forceSilkTouch: Boolean = false, val collectDrops: Boolean = TaskFlow.build.collectDrops, private val cancelOnUnsolvable: Boolean = true, ) : Task() { @@ -62,7 +64,7 @@ class BuildStructure @Ta5kBuilder constructor( is Resolvable -> { LOG.info("Resolving: $result") result.resolve.start(this@BuildStructure) - if (pathing) { + if (pathing && stayInRange) { BaritoneUtils.setGoalAndPath(GoalNear(result.blockPos, 2)) } } @@ -81,6 +83,7 @@ class BuildStructure @Ta5kBuilder constructor( private fun SafeContext.checkDone() { if (!finishOnDone) return + BaritoneUtils.cancel() success(Unit) return } @@ -91,12 +94,14 @@ class BuildStructure @Ta5kBuilder constructor( finishOnDone: Boolean = true, collectDrops: Boolean = TaskFlow.build.collectDrops, pathing: Boolean = TaskFlow.build.pathing, + stayInRange: Boolean = true, cancelOnUnsolvable: Boolean = true, blueprint: () -> Blueprint, ) = BuildStructure( blueprint(), finishOnDone, pathing, + stayInRange, collectDrops, cancelOnUnsolvable ) @@ -104,8 +109,12 @@ class BuildStructure @Ta5kBuilder constructor( @Ta5kBuilder fun breakAndCollectBlock( blockPos: BlockPos, + withSilkTouch: Boolean = false, + stayInRange: Boolean = false, ) = BuildStructure( blockPos.toStructure(TargetState.Air).toBlueprint(), + forceSilkTouch = withSilkTouch, + stayInRange = stayInRange, collectDrops = true ) diff --git a/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt b/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt index 6f6391314..db9d39975 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt @@ -11,10 +11,10 @@ class ContainerTransfer( val to: MaterialContainer ) : Task() { override fun SafeContext.onStart() { - from.withdraw(selection).onSuccess { withdraw, _ -> + from.withdraw(selection).thenRun(this@ContainerTransfer) { _, _ -> to.deposit(selection).onSuccess { _, _ -> success(Unit) - }.start(withdraw) + } }.start(this@ContainerTransfer) } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt index 42ab9c0fc..5b034ee1f 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt @@ -14,8 +14,8 @@ import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.Slot import net.minecraft.screen.slot.SlotActionType -class InventoryTask( - val screen: H, +class InventoryTask( + val screen: ScreenHandler, val selection: StackSelection, val from: List, val to: List, @@ -64,19 +64,20 @@ class InventoryTask( companion object { @Ta5kBuilder - inline fun moveItems( - screen: H, + fun moveItems( + screen: ScreenHandler, selection: StackSelection, from: List, to: List, - ) = InventoryTask(screen, selection, from, to) + closeScreen: Boolean = true + ) = InventoryTask(screen, selection, from, to, closeScreen) @Ta5kBuilder - inline fun withdraw(screen: H, selection: StackSelection) = + fun withdraw(screen: ScreenHandler, selection: StackSelection) = moveItems(screen, selection, screen.containerSlots, screen.inventorySlots) @Ta5kBuilder - inline fun deposit(screen: H, selection: StackSelection) = + fun deposit(screen: ScreenHandler, selection: StackSelection) = moveItems(screen, selection, screen.inventorySlots, screen.containerSlots) } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt b/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt index 5ba0651e7..22411456c 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt @@ -14,24 +14,24 @@ import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction -class OpenContainer( +class OpenContainer( private val blockPos: BlockPos, private val waitForSlotLoad: Boolean = true, private val rotationConfig: IRotationConfig = TaskFlow.rotation, private val interactionConfig: InteractionConfig = TaskFlow.interact, private val sides: Set = emptySet(), -) : Task() { - private var screenHandler: H? = null +) : Task() { + private var screenHandler: ScreenHandler? = null private var slotsLoaded = false init { - listener> { + listener { screenHandler = it.screenHandler if (!waitForSlotLoad || slotsLoaded) success(it.screenHandler) } - listener> { + listener { screenHandler = null } @@ -58,9 +58,9 @@ class OpenContainer( companion object { @Ta5kBuilder - inline fun openContainer( + fun openContainer( blockPos: BlockPos, waitForSlotLoad: Boolean = true - ) = OpenContainer(blockPos, waitForSlotLoad) + ) = OpenContainer(blockPos, waitForSlotLoad) } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt index b0fd34c96..5975cfc94 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt @@ -3,16 +3,24 @@ package com.lambda.task.tasks import com.lambda.context.SafeContext import com.lambda.interaction.construction.Blueprint.Companion.toStructure import com.lambda.interaction.construction.StaticBlueprint.Companion.toBlueprint +import com.lambda.interaction.construction.context.PlaceContext import com.lambda.interaction.construction.result.BuildResult import com.lambda.interaction.construction.result.PlaceResult -import com.lambda.interaction.construction.result.Resolvable import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.verify.TargetState import com.lambda.task.Task import com.lambda.task.tasks.BuildStructure.Companion.buildStructure import com.lambda.util.BlockUtils.blockPos +import com.lambda.util.item.ItemUtils.shulkerBoxes +import net.minecraft.block.ChestBlock +import net.minecraft.block.ShulkerBoxBlock +import net.minecraft.block.entity.ShulkerBoxBlockEntity +import net.minecraft.entity.mob.ShulkerEntity import net.minecraft.item.ItemStack +import net.minecraft.item.Items import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Box +import net.minecraft.util.math.Direction class PlaceContainer @Ta5kBuilder constructor( val stack: ItemStack, @@ -30,8 +38,13 @@ class PlaceContainer @Ta5kBuilder constructor( // val res = results.sorted() // res - val succeeds = results.filterIsInstance() - val wrongStacks = results.filterIsInstance() + val succeeds = results.filterIsInstance().filter { + canBeOpened(stack, it.blockPos, it.context.result.side) + } + val wrongStacks = results.filterIsInstance().filter { + val result = (it.context as? PlaceContext)?.result ?: return@filter false + canBeOpened(stack, it.blockPos, result.side) + } (succeeds + wrongStacks).minOrNull()?.let { result -> buildStructure { result.blockPos @@ -45,9 +58,28 @@ class PlaceContainer @Ta5kBuilder constructor( } } + private fun SafeContext.canBeOpened( + itemStack: ItemStack, + blockPos: BlockPos, + direction: Direction, + ) = when (itemStack.item) { + Items.ENDER_CHEST -> { + !ChestBlock.isChestBlocked(world, blockPos) + } + in shulkerBoxes -> { + val box = ShulkerEntity + .calculateBoundingBox(direction, 0.0f, 0.5f) + .offset(blockPos) + .contract(1.0E-6) + world.isSpaceEmpty(box) + } + else -> false + } + companion object { @Ta5kBuilder - fun placeContainer(stack: ItemStack) = - PlaceContainer(stack) + fun placeContainer( + stack: ItemStack, + ) = PlaceContainer(stack) } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/util/BlockUtils.kt b/common/src/main/kotlin/com/lambda/util/BlockUtils.kt index 581e60c7a..36b17f38c 100644 --- a/common/src/main/kotlin/com/lambda/util/BlockUtils.kt +++ b/common/src/main/kotlin/com/lambda/util/BlockUtils.kt @@ -14,7 +14,7 @@ import net.minecraft.util.math.* import kotlin.math.floor object BlockUtils { - private val shulkerBlocks = shulkerBoxes.map { it.block } + val shulkerBlocks = shulkerBoxes.map { it.block } val interactionBlacklist = mutableSetOf( Blocks.CHEST, From c40e9ab263fd888835bd7007c572a1ff7598d07b Mon Sep 17 00:00:00 2001 From: Constructor Date: Wed, 12 Jun 2024 00:52:53 +0200 Subject: [PATCH 03/16] Task command and tweak fixes --- .../lambda/command/commands/TaskCommand.kt | 24 +++++++++++++++++++ .../module/modules/player/InventoryTweaks.kt | 14 +++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt diff --git a/common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt b/common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt new file mode 100644 index 000000000..5ff321449 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt @@ -0,0 +1,24 @@ +package com.lambda.command.commands + +import com.lambda.brigadier.argument.literal +import com.lambda.brigadier.execute +import com.lambda.brigadier.required +import com.lambda.command.LambdaCommand +import com.lambda.task.RootTask +import com.lambda.util.Communication.info +import com.lambda.util.primitives.extension.CommandBuilder + +object TaskCommand : LambdaCommand( + name = "task", + usage = "task ", + description = "Control tasks" +) { + override fun CommandBuilder.create() { + required(literal("cancel")) { + execute { + this@TaskCommand.info("Cancelling all tasks") + RootTask.cancel() + } + } + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index 95185f7a5..cbe0d62e8 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -10,10 +10,15 @@ import com.lambda.task.Task import com.lambda.task.tasks.BuildStructure.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainer.Companion.openContainer import com.lambda.task.tasks.PlaceContainer.Companion.placeContainer +import com.lambda.threading.runConcurrent import com.lambda.util.item.ItemUtils.shulkerBoxes +import com.lambda.util.player.SlotUtils.clickSlot import com.lambda.util.player.SlotUtils.hotbar +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow import net.minecraft.item.ItemStack import net.minecraft.item.Items +import net.minecraft.network.packet.Packet import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket import net.minecraft.screen.slot.SlotActionType import net.minecraft.util.math.BlockPos @@ -23,17 +28,17 @@ object InventoryTweaks : Module( name = "InventoryTweaks", defaultTags = setOf(ModuleTag.PLAYER) ) { - private val shulkerPeak by setting("Shulker Peek", true, description = "Peek into shulker boxes in your inventory") + private val instantShulker by setting("Instant Shulker", true, description = "Right-click shulker boxes in your inventory to instantly place them and open them.") + private val instantEChest by setting("Instant Ender-Chest", true, description = "Right-click ender chests in your inventory to instantly place them and open them.") private var placedPos: BlockPos? = null private var lastPlace: Task<*>? = null private var lastBreak: Task<*>? = null init { listener { - if (!shulkerPeak) return@listener if (it.action != SlotActionType.PICKUP || it.button != 1) return@listener val stack = it.screenHandler.getSlot(it.slot).stack - if (stack.item !in shulkerBoxes && stack.item != Items.ENDER_CHEST) return@listener + if (!(instantShulker && stack.item in shulkerBoxes) && !(instantEChest && stack.item == Items.ENDER_CHEST)) return@listener it.cancel() move(it.slot, stack) @@ -46,7 +51,6 @@ object InventoryTweaks : Module( } listener { - if (!shulkerPeak) return@listener placedPos?.let { lastBreak = breakAndCollectBlock(it).start(null) placedPos = null @@ -80,6 +84,6 @@ object InventoryTweaks : Module( return } - interaction.pickFromInventory(index) + clickSlot(index, player.inventory.selectedSlot, SlotActionType.SWAP) } } \ No newline at end of file From bc0190cb693d93b2968214152c58401b677475f1 Mon Sep 17 00:00:00 2001 From: Constructor Date: Wed, 12 Jun 2024 20:23:30 +0200 Subject: [PATCH 04/16] Fix break on wrong screen close --- .../module/modules/player/InventoryTweaks.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index cbe0d62e8..08f83a273 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -10,16 +10,13 @@ import com.lambda.task.Task import com.lambda.task.tasks.BuildStructure.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainer.Companion.openContainer import com.lambda.task.tasks.PlaceContainer.Companion.placeContainer -import com.lambda.threading.runConcurrent import com.lambda.util.item.ItemUtils.shulkerBoxes import com.lambda.util.player.SlotUtils.clickSlot import com.lambda.util.player.SlotUtils.hotbar -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow import net.minecraft.item.ItemStack import net.minecraft.item.Items -import net.minecraft.network.packet.Packet import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket +import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.SlotActionType import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction @@ -33,6 +30,7 @@ object InventoryTweaks : Module( private var placedPos: BlockPos? = null private var lastPlace: Task<*>? = null private var lastBreak: Task<*>? = null + private var lastOpenScreen: ScreenHandler? = null init { listener { @@ -46,11 +44,15 @@ object InventoryTweaks : Module( lastPlace = placeContainer(stack).thenRun(null) { _, placePos -> placedPos = placePos - openContainer(placePos) + openContainer(placePos).onSuccess { _, screenHandler -> + lastOpenScreen = screenHandler + } }.start(null) } - listener { + listener { event -> + if (event.screenHandler != lastOpenScreen) return@listener + lastOpenScreen = null placedPos?.let { lastBreak = breakAndCollectBlock(it).start(null) placedPos = null From 85b84516812b8b178fe2e177d93bfaaed38253f6 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:26:01 -0400 Subject: [PATCH 05/16] Fix: Collecting air item --- .../com/lambda/mixin/entity/EntityMixin.java | 14 +++++++++++++- .../com/lambda/event/events/WorldEvent.kt | 8 +++++++- .../kotlin/com/lambda/task/tasks/BreakBlock.kt | 18 ++++++------------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/common/src/main/java/com/lambda/mixin/entity/EntityMixin.java b/common/src/main/java/com/lambda/mixin/entity/EntityMixin.java index 88eb86372..e0e900eca 100644 --- a/common/src/main/java/com/lambda/mixin/entity/EntityMixin.java +++ b/common/src/main/java/com/lambda/mixin/entity/EntityMixin.java @@ -1,15 +1,20 @@ package com.lambda.mixin.entity; import com.lambda.Lambda; +import com.lambda.event.EventFlow; +import com.lambda.event.events.WorldEvent; import com.lambda.interaction.RotationManager; import com.lambda.util.math.Vec2d; import net.minecraft.entity.Entity; import net.minecraft.entity.MovementType; +import net.minecraft.entity.data.TrackedData; import net.minecraft.util.math.Vec3d; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(Entity.class) public abstract class EntityMixin { @@ -61,4 +66,11 @@ float fixDirectionPitch2(Entity entity) { return (float) rot.getY(); } -} \ No newline at end of file + + @Inject(method = "onTrackedDataSet(Lnet/minecraft/entity/data/TrackedData;)V", at = @At("TAIL")) + public void onTrackedDataSet(TrackedData data, CallbackInfo ci) { + Entity entity = (Entity) (Object) this; + + EventFlow.post(new WorldEvent.EntityUpdate(entity, data)); + } +} diff --git a/common/src/main/kotlin/com/lambda/event/events/WorldEvent.kt b/common/src/main/kotlin/com/lambda/event/events/WorldEvent.kt index ffb715aed..359c91c6a 100644 --- a/common/src/main/kotlin/com/lambda/event/events/WorldEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/WorldEvent.kt @@ -6,6 +6,7 @@ import com.lambda.event.callback.ICancellable import net.minecraft.block.BlockState import net.minecraft.client.world.ClientWorld import net.minecraft.entity.Entity +import net.minecraft.entity.data.TrackedData import net.minecraft.util.math.BlockPos import net.minecraft.world.chunk.WorldChunk @@ -34,4 +35,9 @@ abstract class WorldEvent : Event { class EntitySpawn( val entity: Entity ) : WorldEvent(), ICancellable by Cancellable() -} \ No newline at end of file + + class EntityUpdate( + val entity: Entity, + val data: TrackedData<*>, + ) : WorldEvent(), ICancellable by Cancellable() +} diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt index 6d91f1906..bd6a88c56 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt @@ -1,24 +1,19 @@ package com.lambda.task.tasks import baritone.api.pathing.goals.GoalBlock +import com.lambda.config.groups.IRotationConfig +import com.lambda.config.groups.InteractionConfig import com.lambda.context.SafeContext import com.lambda.event.events.RotationEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.config.groups.InteractionConfig import com.lambda.interaction.construction.context.BreakContext -import com.lambda.config.groups.IRotationConfig import com.lambda.interaction.visibilty.VisibilityChecker.lookAtBlock import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task -import com.lambda.task.tasks.GoalTask.Companion.moveToBlock -import com.lambda.task.tasks.GoalTask.Companion.moveToBlockUntil -import com.lambda.task.tasks.GoalTask.Companion.moveToGoal -import com.lambda.task.tasks.GoalTask.Companion.moveToGoalUntil import com.lambda.util.BaritoneUtils import com.lambda.util.BlockUtils.blockState -import com.lambda.util.BlockUtils.item import com.lambda.util.item.ItemUtils.defaultDisposables import com.lambda.util.player.SlotUtils.clickSlot import com.lambda.util.player.SlotUtils.hotbarAndStorage @@ -103,12 +98,11 @@ class BreakBlock @Ta5kBuilder constructor( if (finish()) success(null) } - listener { + listener { if (collectDrop - && drop == null && it.entity is ItemEntity - && it.entity.pos.isInRange(blockPos.toCenterPos(), 1.0) -// && it.entity.stack.item == beginState?.block?.item // ToDo: The item entities are all air?? + && it.entity.pos.isInRange(blockPos.toCenterPos(), 0.5) + ) { drop = it.entity } @@ -144,4 +138,4 @@ class BreakBlock @Ta5kBuilder constructor( swingHand ) } -} \ No newline at end of file +} From ab5fb3590662b3df3b40988747bcd7410f3e5aef Mon Sep 17 00:00:00 2001 From: Constructor Date: Sat, 6 Jul 2024 05:50:12 +0200 Subject: [PATCH 06/16] Server synced interactions --- .../mixin/render/ScreenHandlerMixin.java | 3 +- .../com/lambda/config/groups/BuildConfig.kt | 1 - .../com/lambda/config/groups/BuildSettings.kt | 12 ++-- .../lambda/config/groups/InteractionConfig.kt | 10 ++++ .../config/groups/InteractionSettings.kt | 7 +++ .../lambda/event/events/ScreenHandlerEvent.kt | 2 +- .../module/modules/debug/InventoryDebug.kt | 13 +++++ .../src/main/kotlin/com/lambda/task/Task.kt | 4 +- .../com/lambda/task/tasks/BreakBlock.kt | 2 +- .../com/lambda/task/tasks/BuildStructure.kt | 16 ++---- .../com/lambda/task/tasks/InventoryTask.kt | 55 +++++++++++-------- .../com/lambda/task/tasks/OpenContainer.kt | 47 +++++++++++----- .../com/lambda/task/tasks/PlaceBlock.kt | 31 ++++++----- 13 files changed, 129 insertions(+), 74 deletions(-) diff --git a/common/src/main/java/com/lambda/mixin/render/ScreenHandlerMixin.java b/common/src/main/java/com/lambda/mixin/render/ScreenHandlerMixin.java index 9f816cfbb..dacf0050f 100644 --- a/common/src/main/java/com/lambda/mixin/render/ScreenHandlerMixin.java +++ b/common/src/main/java/com/lambda/mixin/render/ScreenHandlerMixin.java @@ -1,7 +1,6 @@ package com.lambda.mixin.render; import com.lambda.event.EventFlow; -import com.lambda.event.events.ScreenEvent; import com.lambda.event.events.ScreenHandlerEvent; import net.minecraft.item.ItemStack; import net.minecraft.screen.ScreenHandler; @@ -16,6 +15,6 @@ public class ScreenHandlerMixin { @Inject(method = "updateSlotStacks", at = @At("TAIL")) private void onUpdateSlotStacksHead(int revision, List stacks, ItemStack cursorStack, CallbackInfo ci) { - EventFlow.post(new ScreenHandlerEvent.Loaded(revision, stacks, cursorStack)); + EventFlow.post(new ScreenHandlerEvent.Update(revision, stacks, cursorStack)); } } diff --git a/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt b/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt index 1ae1fbb6c..3c86835ac 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt @@ -11,5 +11,4 @@ interface BuildConfig { val breaksPerTick: Int val rotateForBreak: Boolean val rotateForPlace: Boolean - val pingTimeout: Boolean } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt b/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt index 3ce4c91f2..485cf0cb1 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt @@ -7,23 +7,23 @@ class BuildSettings( vis: () -> Boolean = { true } ) : BuildConfig { enum class Page { - BREAK, PLACE, GENERAL + GENERAL, BREAK, PLACE } - private val page by c.setting("Build Page", Page.BREAK, "Current page", vis) + private val page by c.setting("Build Page", Page.GENERAL, "Current page", vis) + + override val pathing by c.setting("Pathing", true, "Path to blocks") { vis() && page == Page.GENERAL } override val breakCoolDown by c.setting("Break Cooldown", 0, 0..1000, 1, "Delay between breaking blocks", " ms") { vis() && page == Page.BREAK } override val breakConfirmation by c.setting("Break Confirmation", false, "Wait for block break confirmation") { vis() && page == Page.BREAK } override val breakWeakBlocks by c.setting("Break Weak Blocks", false, "Break blocks that dont have structural integrity (e.g: grass)") { vis() && page == Page.BREAK } override val breaksPerTick by c.setting("Instant Breaks Per Tick", 10, 1..30, 1, "Maximum instant block breaks per tick") { vis() && page == Page.BREAK } override val rotateForBreak by c.setting("Rotate For Break", false, "Rotate towards block while breaking") { vis() && page == Page.BREAK } - override val collectDrops by c.setting("Collect All Drops", false, "Collect all drops when breaking blocks") { vis() && page == Page.BREAK } + override val collectDrops by c.setting("Collect All Drops", false, "Collect all drops when breaking blocks") { vis() && page == Page.BREAK } override val placeCooldown by c.setting("Place Cooldown", 0, 0..1000, 1, "Delay between placing blocks", " ms") { vis() && page == Page.PLACE } + override val placeConfirmation by c.setting("Place Confirmation", true, "Wait for block placement confirmation") { vis() && page == Page.PLACE } override val rotateForPlace by c.setting("Rotate For Place", true, "Rotate towards block while placing") { vis() && page == Page.PLACE } - - override val pathing by c.setting("Pathing", true, "Path to blocks") { vis() && page == Page.GENERAL } - override val pingTimeout by c.setting("Ping Timeout", true, "Timeout on high ping") { vis() && page == Page.GENERAL } } diff --git a/common/src/main/kotlin/com/lambda/config/groups/InteractionConfig.kt b/common/src/main/kotlin/com/lambda/config/groups/InteractionConfig.kt index 919478485..0cd7fcb85 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/InteractionConfig.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/InteractionConfig.kt @@ -1,5 +1,7 @@ package com.lambda.config.groups +import com.lambda.core.PingManager + interface InteractionConfig { /** * Maximum distance to interact. @@ -13,4 +15,12 @@ interface InteractionConfig { val useRayCast: Boolean val swingHand: Boolean + val inScopeThreshold: Int + val pingTimeout: Boolean + + val scopeThreshold: Int get() = if (pingTimeout) { + (PingManager.lastPing / 50L).toInt() + } else { + inScopeThreshold + } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt b/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt index 1ddb53ea6..c7a155d10 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt @@ -1,6 +1,9 @@ package com.lambda.config.groups import com.lambda.config.Configurable +import com.lambda.config.groups.BuildSettings.Page +import com.lambda.core.PingManager +import com.lambda.module.modules.client.TaskFlow import com.lambda.util.world.raycast.RayCastMask class InteractionSettings( @@ -11,4 +14,8 @@ class InteractionSettings( override val useRayCast by c.setting("Raycast", false, "Verify hit vector with ray casting (for very strict ACs)", vis) override val resolution by c.setting("Resolution", 5, 1..20, 1, "How many raycast checks per surface (will be squared)") { vis() && useRayCast } override val swingHand by c.setting("Swing Hand", true, "Swing hand on interactions", vis) + override val pingTimeout by c.setting("Ping Timeout", false, "Timeout on high ping", vis) + override val inScopeThreshold by c.setting("Constant Timeout", 1, 0..20, 1, "How many ticks to wait until target box is in rotation scope"," ticks") { + vis() && !pingTimeout + } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt b/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt index 3254efbb3..0f80e89f0 100644 --- a/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt +++ b/common/src/main/kotlin/com/lambda/event/events/ScreenHandlerEvent.kt @@ -8,7 +8,7 @@ sealed class ScreenHandlerEvent : Event { class Open(val screenHandler: ScreenHandler) : ScreenHandlerEvent() class Close(val screenHandler: ScreenHandler) : ScreenHandlerEvent() - data class Loaded( + data class Update( val revision: Int, val stacks: List, val cursorStack: ItemStack, diff --git a/common/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt b/common/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt index da1b5ee09..ae1b2faf7 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt @@ -2,6 +2,7 @@ package com.lambda.module.modules.debug import com.lambda.Lambda.LOG import com.lambda.event.events.PacketEvent +import com.lambda.event.events.ScreenHandlerEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag @@ -17,6 +18,18 @@ object InventoryDebug : Module( defaultTags = setOf(ModuleTag.DEBUG) ) { init { + listener { + info("Opened screen handler: ${it.screenHandler::class.simpleName}") + } + + listener { + info("Closed screen handler: ${it.screenHandler::class.simpleName}") + } + + listener { + info("Updated screen handler: ${it.revision}, ${it.stacks}, ${it.cursorStack}") + } + listener { when (val packet = it.packet) { is UpdateSelectedSlotS2CPacket, is InventoryS2CPacket -> { diff --git a/common/src/main/kotlin/com/lambda/task/Task.kt b/common/src/main/kotlin/com/lambda/task/Task.kt index 8a42fe916..311801b67 100644 --- a/common/src/main/kotlin/com/lambda/task/Task.kt +++ b/common/src/main/kotlin/com/lambda/task/Task.kt @@ -64,13 +64,13 @@ abstract class Task : Nameable { open var pausable = true - var parent: Task<*>? = null + private var parent: Task<*>? = null private val root: Task<*> get() = parent?.root ?: this private val depth: Int get() = parent?.depth?.plus(1) ?: 0 private var executions = 0 private var attempted = 0 - val subTasks = mutableListOf>() + private val subTasks = mutableListOf>() private var state = State.IDLE var age = 0 diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt index c3e680b02..51083b0b1 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt @@ -81,7 +81,7 @@ class BreakBlock @Ta5kBuilder constructor( } BaritoneUtils.setGoalAndPath(GoalBlock(itemDrop.blockPos)) - } + } ?: BaritoneUtils.cancel() if (finish()) { success(null) diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt index 75e4e859c..af1ad8cf0 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt @@ -32,8 +32,6 @@ class BuildStructure @Ta5kBuilder constructor( private var lastResult: BuildResult? = null private var lastTask: Task<*>? = null - abstract class PathingStrategy - override fun SafeContext.onStart() { (blueprint as? DynamicBlueprint)?.create(this) } @@ -41,9 +39,7 @@ class BuildStructure @Ta5kBuilder constructor( init { listener { previousResults.filterIsInstance().forEach { res -> - with(res) { - buildRenderer() - } + with(res) { buildRenderer() } } } @@ -62,10 +58,10 @@ class BuildStructure @Ta5kBuilder constructor( lastResult?.let { if (it.compareTo(result) == 0) return@listener // if (it.pausesParent && lastTask?.isCompleted != true) return@listener - if (collectDrops && it is BreakResult.Success && lastTask?.isCompleted != true) { + if (/*collectDrops && it is BreakResult.Success && */lastTask?.isCompleted != true) { return@listener } - info("${it.rank.name}${if (it.pausesParent) " pauses" else ""} -> ${result.rank.name} (${lastTask?.identifier})") + LOG.info("${it.rank.name}${if (it.pausesParent) " pauses" else ""} -> ${result.rank.name} (${lastTask?.identifier})") lastTask?.cancel() } @@ -97,9 +93,9 @@ class BuildStructure @Ta5kBuilder constructor( lastResult = result lastTask = result.resolve.start(this@BuildStructure, pauseParent = result.pausesParent) - if (pathing) { - BaritoneUtils.setGoalAndPath(GoalNear(result.blockPos, 3)) - } +// if (pathing) { +// BaritoneUtils.setGoalAndPath(GoalNear(result.blockPos, 3)) +// } } is Navigable -> { if (pathing) BaritoneUtils.setGoalAndPath(result.goal) diff --git a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt index 1b9b3ab11..cbc7806ed 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt @@ -1,16 +1,19 @@ package com.lambda.task.tasks import com.lambda.context.SafeContext +import com.lambda.event.events.ScreenHandlerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.interaction.material.StackSelection import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task +import com.lambda.threading.runConcurrent +import com.lambda.threading.runGameScheduled import com.lambda.util.item.ItemUtils.block -import com.lambda.util.item.ItemUtils.defaultDisposables import com.lambda.util.player.SlotUtils.clickSlot import com.lambda.util.primitives.extension.containerSlots import com.lambda.util.primitives.extension.inventorySlots +import kotlinx.coroutines.delay import net.minecraft.item.ItemStack import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.Slot @@ -18,42 +21,46 @@ import net.minecraft.screen.slot.SlotActionType class InventoryTask( val screen: ScreenHandler, - val selection: StackSelection, + private val selector: StackSelection, val from: List, val to: List, private val closeScreen: Boolean = true -) : Task>() { - private val moved = mutableListOf() - private val selectedFrom = selection.filterSlots(from).filter { it.hasStack() } +) : Task() { + private val selectedFrom get() = selector.filterSlots(from).filter { it.hasStack() } private val selectedTo = to.filter { !it.hasStack() } init { // ToDo: Needs smart code to move as efficient as possible. // Also should handle overflow etc. Should be more generic listener { - selectedFrom.firstOrNull()?.let { from -> - val preMove = from.stack.copy() + selector.filterSlots(from).firstOrNull { it.hasStack() }?.let { from -> +// player.currentScreenHandler +// .inventorySlots +// .firstOrNull { +// it.stack.item.block in TaskFlow.disposables || it.stack.isEmpty +// }?.let { to -> +// clickSlot(from.id, 0, SlotActionType.PICKUP) +// clickSlot(to.id, 0, SlotActionType.PICKUP) +// // ToDo: Handle overflow of cursor +// } -// selectedTo.firstOrNull()?.let { to -> -// clickSlot(from.id, 0, SlotActionType.PICKUP) -// clickSlot(to.id, 0, SlotActionType.PICKUP) -// // ToDo: Handle overflow of cursor -// } - - // ToDo: SWAP triangle - val handler = player.currentScreenHandler - handler.inventorySlots.firstOrNull { - it.stack.item.block in TaskFlow.disposables || it.stack.isEmpty - }?.let { emptySlot -> - clickSlot(emptySlot.id, 0, SlotActionType.SWAP) - clickSlot(from.id, 0, SlotActionType.SWAP) - } - moved.add(preMove) + player.currentScreenHandler + .inventorySlots + .firstOrNull { + it.stack.item.block in TaskFlow.disposables || it.stack.isEmpty + }?.let { emptySlot -> + clickSlot(emptySlot.id, 0, SlotActionType.SWAP) + clickSlot(from.id, 0, SlotActionType.SWAP) + } } ?: finish() } listener { - if (selectedFrom.isEmpty() || moved.sumOf { it.count } >= selection.count) { + val moved = selector.filterSlots(to) + .filter { it.hasStack() } + .sumOf { it.stack.count } >= selector.count + + if (selectedFrom.isEmpty() || moved) { finish() } } @@ -61,7 +68,7 @@ class InventoryTask( private fun SafeContext.finish() { if (closeScreen) player.closeHandledScreen() - success(moved) + success(Unit) } companion object { diff --git a/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt b/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt index 4d3597c13..a5fa9b655 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt @@ -17,26 +17,40 @@ import net.minecraft.util.math.Direction class OpenContainer( private val blockPos: BlockPos, private val waitForSlotLoad: Boolean = true, - private val rotationConfig: IRotationConfig = TaskFlow.rotation, - private val interactionConfig: InteractionConfig = TaskFlow.interact, + private val rotate: Boolean, + private val rotation: IRotationConfig = TaskFlow.rotation, + private val interact: InteractionConfig = TaskFlow.interact, private val sides: Set = emptySet(), ) : Task() { private var screenHandler: ScreenHandler? = null - private var slotsLoaded = false + private var state = State.SCOPING + private var inScope = 0 + + override var timeout = 50 + + enum class State { + SCOPING, OPENING, SLOT_LOADING + } init { listener { + if (state != State.OPENING) return@listener + screenHandler = it.screenHandler + state = State.SLOT_LOADING - if (!waitForSlotLoad || slotsLoaded) success(it.screenHandler) + if (!waitForSlotLoad) success(it.screenHandler) } listener { + if (screenHandler != it.screenHandler) return@listener + + state = State.SCOPING screenHandler = null } - listener { - slotsLoaded = true + listener { + if (state != State.SLOT_LOADING) return@listener screenHandler?.let { success(it) @@ -44,15 +58,21 @@ class OpenContainer( } listener { event -> - if (screenHandler != null) return@listener - event.context = lookAtBlock(blockPos, rotationConfig, interactionConfig, sides) + if (!rotate) return@listener + event.context = lookAtBlock(blockPos, rotation, interact, sides) } listener { - if (screenHandler != null) return@listener + if (!rotate) return@listener + if (state != State.SCOPING) return@listener if (!it.context.isValid) return@listener - val hitResult = it.context.hitResult?.blockResult ?: return@listener - interaction.interactBlock(player, Hand.MAIN_HAND, hitResult) + + if (inScope++ >= interact.scopeThreshold) { + val hitResult = it.context.hitResult?.blockResult ?: return@listener + interaction.interactBlock(player, Hand.MAIN_HAND, hitResult) + + state = State.OPENING + } } } @@ -60,7 +80,8 @@ class OpenContainer( @Ta5kBuilder fun openContainer( blockPos: BlockPos, - waitForSlotLoad: Boolean = true - ) = OpenContainer(blockPos, waitForSlotLoad) + waitForSlotLoad: Boolean = true, + rotate: Boolean = true, + ) = OpenContainer(blockPos, waitForSlotLoad, rotate) } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index 5359feaf8..2902ac68c 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -1,6 +1,8 @@ package com.lambda.task.tasks import com.lambda.Lambda.LOG +import com.lambda.config.groups.IRotationConfig +import com.lambda.config.groups.InteractionConfig import com.lambda.context.SafeContext import com.lambda.core.PingManager import com.lambda.event.events.RotationEvent @@ -15,14 +17,15 @@ import net.minecraft.block.BlockState class PlaceBlock @Ta5kBuilder constructor( private val ctx: PlaceContext, - private val swingHand: Boolean, private val rotate: Boolean, + private val interact: InteractionConfig = TaskFlow.interact, private val waitForConfirmation: Boolean, ) : Task() { private var beginState: BlockState? = null override var cooldown = Int.MAX_VALUE get() = maxOf(TaskFlow.build.placeCooldown, TaskFlow.taskCooldown) override var timeout = 50 + private var state = State.PLACING private var inScope = 0 private val SafeContext.resultingState: BlockState get() = @@ -30,6 +33,10 @@ class PlaceBlock @Ta5kBuilder constructor( private val SafeContext.matches get() = ctx.targetState.matches(ctx.resultingPos.blockState(world), ctx.resultingPos, world) + enum class State { + PLACING, WAITING + } + override fun SafeContext.onStart() { if (matches) { finish() @@ -50,19 +57,13 @@ class PlaceBlock @Ta5kBuilder constructor( if (!rotate) return@listener if (!it.context.isValid) return@listener - if (TaskFlow.build.pingTimeout) { - val threshold = PingManager.lastPing / 50L - if (++inScope >= threshold) { - inScope = 0 - placeBlock() - } - return@listener + if (state == State.PLACING && inScope++ >= interact.scopeThreshold) { + placeBlock() } - - placeBlock() } listener { + if (state != State.WAITING) return@listener if (it.pos != ctx.resultingPos) return@listener if (ctx.targetState.matches(it.state, it.pos, world)) { @@ -79,7 +80,7 @@ class PlaceBlock @Ta5kBuilder constructor( ) if (actionResult.isAccepted) { - if (actionResult.shouldSwingHand() && swingHand) { + if (actionResult.shouldSwingHand() && interact.swingHand) { player.swingHand(ctx.hand) } @@ -87,11 +88,13 @@ class PlaceBlock @Ta5kBuilder constructor( mc.gameRenderer.firstPersonRenderer.resetEquipProgress(ctx.hand) } + state = State.WAITING + if (matches) { if (!waitForConfirmation) finish() } } else { - info("Internal interaction failed with $actionResult") + failure("Internal interaction failed with $actionResult") } } @@ -108,9 +111,9 @@ class PlaceBlock @Ta5kBuilder constructor( @Ta5kBuilder fun placeBlock( ctx: PlaceContext, - swingHand: Boolean = TaskFlow.interact.swingHand, rotate: Boolean = TaskFlow.build.rotateForPlace, waitForConfirmation: Boolean = TaskFlow.build.placeConfirmation, - ) = PlaceBlock(ctx, swingHand, rotate, waitForConfirmation) + interact: InteractionConfig = TaskFlow.interact, + ) = PlaceBlock(ctx, rotate, interact, waitForConfirmation) } } From 5a88932fc0a4796a78e5aeaa1a4d528e2068d0b8 Mon Sep 17 00:00:00 2001 From: Constructor Date: Sat, 6 Jul 2024 06:23:20 +0200 Subject: [PATCH 07/16] Item collection bug fix --- .../com/lambda/config/groups/BuildConfig.kt | 2 - .../com/lambda/config/groups/BuildSettings.kt | 2 - .../com/lambda/task/tasks/BreakBlock.kt | 30 +++---- .../com/lambda/task/tasks/BuildStructure.kt | 6 +- .../kotlin/com/lambda/task/tasks/GoalTask.kt | 79 ------------------- .../com/lambda/task/tasks/PlaceBlock.kt | 11 +-- 6 files changed, 22 insertions(+), 108 deletions(-) delete mode 100644 common/src/main/kotlin/com/lambda/task/tasks/GoalTask.kt diff --git a/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt b/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt index 3c86835ac..e9edf3f23 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/BuildConfig.kt @@ -1,8 +1,6 @@ package com.lambda.config.groups interface BuildConfig { - val breakCoolDown: Int - val placeCooldown: Int val breakConfirmation: Boolean val placeConfirmation: Boolean val collectDrops: Boolean diff --git a/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt b/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt index 485cf0cb1..ab4a6554a 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt @@ -14,14 +14,12 @@ class BuildSettings( override val pathing by c.setting("Pathing", true, "Path to blocks") { vis() && page == Page.GENERAL } - override val breakCoolDown by c.setting("Break Cooldown", 0, 0..1000, 1, "Delay between breaking blocks", " ms") { vis() && page == Page.BREAK } override val breakConfirmation by c.setting("Break Confirmation", false, "Wait for block break confirmation") { vis() && page == Page.BREAK } override val breakWeakBlocks by c.setting("Break Weak Blocks", false, "Break blocks that dont have structural integrity (e.g: grass)") { vis() && page == Page.BREAK } override val breaksPerTick by c.setting("Instant Breaks Per Tick", 10, 1..30, 1, "Maximum instant block breaks per tick") { vis() && page == Page.BREAK } override val rotateForBreak by c.setting("Rotate For Break", false, "Rotate towards block while breaking") { vis() && page == Page.BREAK } override val collectDrops by c.setting("Collect All Drops", false, "Collect all drops when breaking blocks") { vis() && page == Page.BREAK } - override val placeCooldown by c.setting("Place Cooldown", 0, 0..1000, 1, "Delay between placing blocks", " ms") { vis() && page == Page.PLACE } override val placeConfirmation by c.setting("Place Confirmation", true, "Wait for block placement confirmation") { vis() && page == Page.PLACE } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt index 51083b0b1..3b23ea16d 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt @@ -15,7 +15,6 @@ import com.lambda.task.Task import com.lambda.util.BaritoneUtils import com.lambda.util.BlockUtils.blockState import com.lambda.util.item.ItemUtils.block -import com.lambda.util.item.ItemUtils.defaultDisposables import com.lambda.util.player.SlotUtils.clickSlot import com.lambda.util.player.SlotUtils.hotbarAndStorage import com.lambda.util.primitives.extension.inventorySlots @@ -36,19 +35,24 @@ class BreakBlock @Ta5kBuilder constructor( private val swingHand: Boolean, ) : Task() { val blockPos: BlockPos get() = ctx.result.blockPos + private var beginState: BlockState? = null - val SafeContext.state: BlockState get() = blockPos.blockState(world) - override var cooldown = Int.MAX_VALUE - get() = maxOf(TaskFlow.build.breakCoolDown, TaskFlow.taskCooldown) - set(value) = run { field = value } + val SafeContext.blockState: BlockState get() = + blockPos.blockState(world) + private var drop: ItemEntity? = null + private var state = State.BREAKING + + enum class State { + BREAKING, CONFIRMING, COLLECTING + } override fun SafeContext.onStart() { - if (state.isAir && !collectDrop) { + if (blockState.isAir && !collectDrop) { success(null) return } - beginState = state + beginState = blockState } init { @@ -59,6 +63,8 @@ class BreakBlock @Ta5kBuilder constructor( listener { if (!rotate) return@listener + if (state != State.BREAKING) return@listener + if (!it.context.isValid) return@listener val hitResult = it.context.hitResult?.blockResult ?: return@listener @@ -83,14 +89,10 @@ class BreakBlock @Ta5kBuilder constructor( BaritoneUtils.setGoalAndPath(GoalBlock(itemDrop.blockPos)) } ?: BaritoneUtils.cancel() - if (finish()) { - success(null) - return@listener + if (!rotate) { + breakBlock(ctx.result.side) } - if (rotate) return@listener - - breakBlock(ctx.result.side) if (finish()) success(null) } @@ -105,7 +107,7 @@ class BreakBlock @Ta5kBuilder constructor( } } - private fun SafeContext.finish() = state.isAir && !collectDrop + private fun SafeContext.finish() = blockState.isAir && !collectDrop private fun SafeContext.breakBlock(side: Direction) { if (interaction.updateBlockBreakingProgress(blockPos, side)) { diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt index af1ad8cf0..24d4141a1 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt @@ -1,6 +1,5 @@ package com.lambda.task.tasks -import baritone.api.pathing.goals.GoalNear import com.lambda.Lambda.LOG import com.lambda.context.SafeContext import com.lambda.event.events.RenderEvent @@ -16,7 +15,6 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task import com.lambda.util.BaritoneUtils -import com.lambda.util.Communication.info import net.minecraft.util.math.BlockPos class BuildStructure @Ta5kBuilder constructor( @@ -113,9 +111,10 @@ class BuildStructure @Ta5kBuilder constructor( @Ta5kBuilder fun buildStructure( finishOnDone: Boolean = true, - collectDrops: Boolean = TaskFlow.build.collectDrops, pathing: Boolean = TaskFlow.build.pathing, stayInRange: Boolean = true, + forceSilkTouch: Boolean = false, + collectDrops: Boolean = TaskFlow.build.collectDrops, cancelOnUnsolvable: Boolean = true, blueprint: () -> Blueprint, ) = BuildStructure( @@ -123,6 +122,7 @@ class BuildStructure @Ta5kBuilder constructor( finishOnDone, pathing, stayInRange, + forceSilkTouch, collectDrops, cancelOnUnsolvable ) diff --git a/common/src/main/kotlin/com/lambda/task/tasks/GoalTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/GoalTask.kt deleted file mode 100644 index 297648c7e..000000000 --- a/common/src/main/kotlin/com/lambda/task/tasks/GoalTask.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.lambda.task.tasks - -import baritone.api.pathing.goals.Goal -import baritone.api.pathing.goals.GoalBlock -import baritone.api.pathing.goals.GoalNear -import baritone.api.pathing.goals.GoalXZ -import com.lambda.context.SafeContext -import com.lambda.event.events.TickEvent -import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.module.modules.client.TaskFlow -import com.lambda.task.Task -import com.lambda.util.BaritoneUtils -import com.lambda.util.BaritoneUtils.primary -import net.minecraft.util.math.BlockPos - -// ToDo: Custom heuristic goals -class GoalTask( - private val goal: () -> Goal, - private val check: SafeContext.() -> Boolean = { false } -) : Task() { - - init { - listener { - val goal = goal() - - primary.customGoalProcess.goal = goal - primary.customGoalProcess.path() - - if (goal.isInGoal(player.blockPos) || check()) { - primary.customGoalProcess.goal = null - success(Unit) - } - } - } - - companion object { - @Ta5kBuilder - fun moveToGoal(goal: () -> Goal) = - GoalTask(goal) - - @Ta5kBuilder - fun moveToGoalUntil(goal: () -> Goal, check: SafeContext.() -> Boolean) = - GoalTask(goal) - - @Ta5kBuilder - fun moveToGoal(goal: Goal) = - GoalTask({ goal }) - - @Ta5kBuilder - fun moveToGoalUntil(goal: Goal, check: SafeContext.() -> Boolean) = - GoalTask({ goal }, check) - - @Ta5kBuilder - fun moveToBlock(blockPos: BlockPos) = - GoalTask({ GoalBlock(blockPos) }) - - @Ta5kBuilder - fun moveNearBlock(blockPos: BlockPos, range: Int) = - GoalTask({ GoalNear(blockPos, range) }) - - @Ta5kBuilder - fun moveToBlockUntil(blockPos: BlockPos, check: SafeContext.() -> Boolean) = - GoalTask({ GoalBlock(blockPos) }, check) - - @Ta5kBuilder - fun moveToXY(blockPos: BlockPos) = - GoalTask({ GoalXZ(blockPos.x, blockPos.z) }) - - @Ta5kBuilder - fun moveUntilLoaded(blockPos: BlockPos) = - GoalTask({ GoalBlock(blockPos) }) { - world.isPosLoaded(blockPos.x, blockPos.z) - } - - @Ta5kBuilder - fun moveIntoEntityRange(blockPos: BlockPos, range: Int = 3) = - GoalTask({ GoalNear(blockPos, range) }) - } -} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index 2902ac68c..49e94f760 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -1,10 +1,8 @@ package com.lambda.task.tasks import com.lambda.Lambda.LOG -import com.lambda.config.groups.IRotationConfig import com.lambda.config.groups.InteractionConfig import com.lambda.context.SafeContext -import com.lambda.core.PingManager import com.lambda.event.events.RotationEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener @@ -12,7 +10,6 @@ import com.lambda.interaction.construction.context.PlaceContext import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task import com.lambda.util.BlockUtils.blockState -import com.lambda.util.Communication.info import net.minecraft.block.BlockState class PlaceBlock @Ta5kBuilder constructor( @@ -22,8 +19,6 @@ class PlaceBlock @Ta5kBuilder constructor( private val waitForConfirmation: Boolean, ) : Task() { private var beginState: BlockState? = null - override var cooldown = Int.MAX_VALUE - get() = maxOf(TaskFlow.build.placeCooldown, TaskFlow.taskCooldown) override var timeout = 50 private var state = State.PLACING private var inScope = 0 @@ -34,7 +29,7 @@ class PlaceBlock @Ta5kBuilder constructor( ctx.targetState.matches(ctx.resultingPos.blockState(world), ctx.resultingPos, world) enum class State { - PLACING, WAITING + PLACING, CONFIRMING } override fun SafeContext.onStart() { @@ -63,7 +58,7 @@ class PlaceBlock @Ta5kBuilder constructor( } listener { - if (state != State.WAITING) return@listener + if (state != State.CONFIRMING) return@listener if (it.pos != ctx.resultingPos) return@listener if (ctx.targetState.matches(it.state, it.pos, world)) { @@ -88,7 +83,7 @@ class PlaceBlock @Ta5kBuilder constructor( mc.gameRenderer.firstPersonRenderer.resetEquipProgress(ctx.hand) } - state = State.WAITING + state = State.CONFIRMING if (matches) { if (!waitForConfirmation) finish() From df8a271f1ef012931bd8f0c7ad8edffa9f9ea0bf Mon Sep 17 00:00:00 2001 From: Constructor Date: Sun, 7 Jul 2024 01:08:40 +0200 Subject: [PATCH 08/16] Fix support block and state control --- .../construction/result/BuildResult.kt | 6 ++-- .../construction/verify/TargetState.kt | 2 +- .../com/lambda/task/tasks/BreakBlock.kt | 31 ++++++++++++------- .../com/lambda/task/tasks/BuildStructure.kt | 15 +++++---- .../com/lambda/task/tasks/PlaceBlock.kt | 8 +++-- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt b/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt index 7c0113731..278c6de8d 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt @@ -140,12 +140,12 @@ abstract class BuildResult : ComparableResult { val distance: Double ) : Navigable, Drawable, BuildResult() { override val rank = Rank.NOT_VISIBLE - private val color = Color(46, 0, 0, 30) + private val color = Color(46, 0, 0, 80) override val goal = GoalPlace(blockPos) override fun SafeContext.buildRenderer() { - withPos(blockPos, color, side) + withBox(Box(blockPos), color) } override fun compareTo(other: ComparableResult): Int { @@ -174,7 +174,7 @@ abstract class BuildResult : ComparableResult { neededItem.select().transfer(MainHandContainer)?.solve ?: failTask("Item ${neededItem.name.string} not found") override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + withBox(Box(blockPos), color) } override fun compareTo(other: ComparableResult): Int { diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index 67d650858..16abd9ac9 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -25,7 +25,7 @@ sealed class TargetState : StateMatcher { data class Support(val direction: Direction) : TargetState() { override fun matches(state: BlockState, pos: BlockPos, world: ClientWorld) = pos.offset(direction).blockState(world).isSolidBlock(world, pos.offset(direction)) - || pos.blockState(world).isSolidBlock(world, pos) + || state.isSolidBlock(world, pos) override fun getStack(world: ClientWorld, pos: BlockPos) = ItemStack(Items.NETHERRACK) // ToDo: Find any disposable block diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt index 3b23ea16d..06cee03c9 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt @@ -18,7 +18,6 @@ import com.lambda.util.item.ItemUtils.block import com.lambda.util.player.SlotUtils.clickSlot import com.lambda.util.player.SlotUtils.hotbarAndStorage import com.lambda.util.primitives.extension.inventorySlots -import com.lambda.util.world.raycast.RayCastUtils.blockResult import net.minecraft.block.BlockState import net.minecraft.entity.ItemEntity import net.minecraft.screen.slot.SlotActionType @@ -27,8 +26,8 @@ import net.minecraft.util.math.Direction class BreakBlock @Ta5kBuilder constructor( private val ctx: BreakContext, - private val rotationConfig: IRotationConfig, - private val interactionConfig: InteractionConfig, + private val rotation: IRotationConfig, + private val interact: InteractionConfig, private val sides: Set, private val collectDrop: Boolean, private val rotate: Boolean, @@ -42,33 +41,38 @@ class BreakBlock @Ta5kBuilder constructor( private var drop: ItemEntity? = null private var state = State.BREAKING + private var inScope = 0 enum class State { - BREAKING, CONFIRMING, COLLECTING + BREAKING, COLLECTING } override fun SafeContext.onStart() { - if (blockState.isAir && !collectDrop) { + if (done()) { success(null) return } beginState = blockState + + if (!rotate) { + breakBlock(ctx.result.side) + } } init { listener { event -> if (!rotate) return@listener - event.context = lookAtBlock(blockPos, rotationConfig, interactionConfig, sides) + event.context = lookAtBlock(blockPos, rotation, interact, sides) } listener { if (!rotate) return@listener if (state != State.BREAKING) return@listener - if (!it.context.isValid) return@listener - val hitResult = it.context.hitResult?.blockResult ?: return@listener - breakBlock(hitResult.side) + if (inScope++ >= interact.inScopeThreshold) { + breakBlock(ctx.result.side) + } } listener { @@ -93,7 +97,12 @@ class BreakBlock @Ta5kBuilder constructor( breakBlock(ctx.result.side) } - if (finish()) success(null) + if (done()) { + state = State.COLLECTING + if (!collectDrop) { + success(null) + } + } } listener { @@ -107,7 +116,7 @@ class BreakBlock @Ta5kBuilder constructor( } } - private fun SafeContext.finish() = blockState.isAir && !collectDrop + private fun SafeContext.done() = blockState.isAir && !collectDrop private fun SafeContext.breakBlock(side: Direction) { if (interaction.updateBlockBreakingProgress(blockPos, side)) { diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt index 24d4141a1..810b11ded 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt @@ -1,5 +1,6 @@ package com.lambda.task.tasks +import baritone.api.pathing.goals.GoalNear import com.lambda.Lambda.LOG import com.lambda.context.SafeContext import com.lambda.event.events.RenderEvent @@ -54,12 +55,13 @@ class BuildStructure @Ta5kBuilder constructor( val result = results.minOrNull() ?: return@listener lastResult?.let { - if (it.compareTo(result) == 0) return@listener + if (lastTask?.isCompleted == false && result.rank == it.rank) return@listener +// if (lastTask?.isCompleted == true || it.rank.compareTo(result.rank) == 0) return@listener // if (it.pausesParent && lastTask?.isCompleted != true) return@listener - if (/*collectDrops && it is BreakResult.Success && */lastTask?.isCompleted != true) { - return@listener - } - LOG.info("${it.rank.name}${if (it.pausesParent) " pauses" else ""} -> ${result.rank.name} (${lastTask?.identifier})") +// if (/*collectDrops && it is BreakResult.Success && */lastTask?.isCompleted == false && lastTask?.isFailed == false) { +// return@listener +// } + LOG.info("${it.rank.name}${if (it.pausesParent) " (paused)" else ""} -> ${result.rank.name} (${lastTask?.identifier})") lastTask?.cancel() } @@ -90,7 +92,8 @@ class BuildStructure @Ta5kBuilder constructor( } lastResult = result - lastTask = result.resolve.start(this@BuildStructure, pauseParent = result.pausesParent) + lastTask = result.resolve + .start(this@BuildStructure, pauseParent = result.pausesParent) // if (pathing) { // BaritoneUtils.setGoalAndPath(GoalNear(result.blockPos, 3)) // } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index 49e94f760..1fecd3daa 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -19,7 +19,6 @@ class PlaceBlock @Ta5kBuilder constructor( private val waitForConfirmation: Boolean, ) : Task() { private var beginState: BlockState? = null - override var timeout = 50 private var state = State.PLACING private var inScope = 0 @@ -39,7 +38,9 @@ class PlaceBlock @Ta5kBuilder constructor( } beginState = resultingState - if (!rotate) placeBlock() + if (!rotate) { + placeBlock() + } } init { @@ -50,9 +51,10 @@ class PlaceBlock @Ta5kBuilder constructor( listener { if (!rotate) return@listener + if (state != State.PLACING) return@listener if (!it.context.isValid) return@listener - if (state == State.PLACING && inScope++ >= interact.scopeThreshold) { + if (inScope++ >= interact.scopeThreshold) { placeBlock() } } From 592abb81d6acbfd64149f48e2b1a64658ef0c977 Mon Sep 17 00:00:00 2001 From: Constructor Date: Sun, 4 Aug 2024 05:55:05 +0200 Subject: [PATCH 09/16] Transitive architecture simplification --- .../command/commands/TransferCommand.kt | 18 ++------ .../config/groups/InteractionSettings.kt | 2 +- .../construction/context/ComparableContext.kt | 7 --- .../construction/result/BreakResult.kt | 41 +++++++++++------- .../construction/result/BuildResult.kt | 25 ++++++++--- .../construction/result/PlaceResult.kt | 26 ++++++----- .../construction/result/Resolvable.kt | 7 --- .../construction/simulation/BuildSimulator.kt | 8 ++-- .../interaction/material/MaterialContainer.kt | 2 +- .../material/transfer/TransferResult.kt | 23 ++++++---- .../kotlin/com/lambda/module/hud/TaskFlow.kt | 19 ++++++++ .../src/main/kotlin/com/lambda/task/Task.kt | 2 - .../com/lambda/task/tasks/BuildStructure.kt | 43 +++++-------------- .../lambda/task/tasks/ContainerTransfer.kt | 2 +- .../com/lambda/task/tasks/PlaceBlock.kt | 1 + .../com/lambda/task/tasks/PlaceContainer.kt | 5 +-- 16 files changed, 116 insertions(+), 115 deletions(-) delete mode 100644 common/src/main/kotlin/com/lambda/interaction/construction/context/ComparableContext.kt delete mode 100644 common/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt create mode 100644 common/src/main/kotlin/com/lambda/module/hud/TaskFlow.kt diff --git a/common/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/common/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index f134fbb46..075f0bd4e 100644 --- a/common/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/common/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -18,7 +18,7 @@ object TransferCommand : LambdaCommand( usage = "transfer ", description = "Transfer items from anywhere to anywhere", ) { - private var lastTransfer: TransferResult.Success? = null + private var lastTransfer: TransferResult.Transfer? = null override fun CommandBuilder.create() { required(itemStack("stack", registry)) { stack -> @@ -61,10 +61,10 @@ object TransferCommand : LambdaCommand( } ?: return@executeWithResult failure("To container not found") when (val result = fromContainer.transfer(selection, toContainer)) { - is TransferResult.Success -> { + is TransferResult.Transfer -> { info("$result started.") lastTransfer = result - result.solve.onSuccess { _, _ -> + result.onSuccess { _, _ -> info("$lastTransfer completed.") }.start(null) return@executeWithResult success() @@ -86,7 +86,7 @@ object TransferCommand : LambdaCommand( required(literal("cancel")) { executeWithResult { - lastTransfer?.solve?.cancel() ?: run { + lastTransfer?.cancel() ?: run { return@executeWithResult failure("No transfer to cancel") } info("$lastTransfer cancelled") @@ -94,15 +94,5 @@ object TransferCommand : LambdaCommand( success() } } - - required(literal("undo")) { - executeWithResult { - lastTransfer?.undo ?: run { - return@executeWithResult failure("No transfer to undo") - } - info("Undoing $lastTransfer") - success() - } - } } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt b/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt index c7a155d10..fb4180797 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt @@ -15,7 +15,7 @@ class InteractionSettings( override val resolution by c.setting("Resolution", 5, 1..20, 1, "How many raycast checks per surface (will be squared)") { vis() && useRayCast } override val swingHand by c.setting("Swing Hand", true, "Swing hand on interactions", vis) override val pingTimeout by c.setting("Ping Timeout", false, "Timeout on high ping", vis) - override val inScopeThreshold by c.setting("Constant Timeout", 1, 0..20, 1, "How many ticks to wait until target box is in rotation scope"," ticks") { + override val inScopeThreshold by c.setting("Constant Timeout", 1, 0..20, 1, "How many ticks to wait after target box is in rotation scope"," ticks") { vis() && !pingTimeout } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/context/ComparableContext.kt b/common/src/main/kotlin/com/lambda/interaction/construction/context/ComparableContext.kt deleted file mode 100644 index 7ab3c2182..000000000 --- a/common/src/main/kotlin/com/lambda/interaction/construction/context/ComparableContext.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.lambda.interaction.construction.context - -interface ComparableContext : Comparable { - override fun compareTo(other: ComparableContext): Int { - return 0 - } -} diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt b/common/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt index 19d2647de..aeccc87e5 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt @@ -9,7 +9,6 @@ import com.lambda.interaction.material.ContainerManager.transfer import com.lambda.interaction.material.StackSelection.Companion.select import com.lambda.interaction.material.StackSelection.Companion.selectStack import com.lambda.interaction.material.container.MainHandContainer -import com.lambda.task.Task.Companion.failTask import com.lambda.task.tasks.BreakBlock.Companion.breakBlock import net.minecraft.block.BlockState import net.minecraft.item.Item @@ -23,16 +22,20 @@ sealed class BreakResult : BuildResult() { * Represents a successful break. All checks have been passed. * @param context The context of the break. */ - data class Success( + data class Break( override val blockPos: BlockPos, val context: BreakContext - ) : Resolvable, Drawable, BreakResult() { + ) : Drawable, BreakResult() { override val rank = Rank.BREAK_SUCCESS private val color = Color(222, 0, 0, 100) var collectDrop = false - override val resolve get() = breakBlock(context, collectDrop = collectDrop) + override fun SafeContext.onStart() { + breakBlock(context, collectDrop = collectDrop).onSuccess { _, _ -> + success(Unit) + }.start(this@Break) + } override fun SafeContext.buildRenderer() { withPos(context.resultingPos, color, context.result.side) @@ -40,7 +43,7 @@ sealed class BreakResult : BuildResult() { override fun compareTo(other: ComparableResult): Int { return when (other) { - is Success -> context.compareTo(other.context) + is Break -> context.compareTo(other.context) else -> super.compareTo(other) } } @@ -54,11 +57,13 @@ sealed class BreakResult : BuildResult() { data class NotExposed( override val blockPos: BlockPos, val side: Direction - ) : Resolvable, Drawable, BreakResult() { + ) : Drawable, BreakResult() { override val rank = Rank.BREAK_NOT_EXPOSED private val color = Color(46, 0, 0, 30) - override val resolve get() = failTask("Block is not exposed to air.") + override fun SafeContext.onStart() { + failure("Block is not exposed to air.") + } override fun SafeContext.buildRenderer() { withPos(blockPos, color, side) @@ -81,20 +86,24 @@ sealed class BreakResult : BuildResult() { override val blockPos: BlockPos, val blockState: BlockState, val badItem: Item - ) : Resolvable, Drawable, BreakResult() { + ) : Drawable, BreakResult() { override val rank = Rank.BREAK_ITEM_CANT_MINE private val color = Color(255, 0, 0, 100) override val pausesParent get() = true - override val resolve get() = findBestAvailableTool(blockState) - ?.select() - ?.transfer(MainHandContainer) - ?.solve ?: run { - selectStack { - isItem(badItem).not() - }.transfer(MainHandContainer)?.solve ?: failTask("No item found or space") - } + override fun SafeContext.onStart() { + findBestAvailableTool(blockState) + ?.select() + ?.transfer(MainHandContainer) + ?.onSuccess { _, _ -> + success(Unit) + }?.start(this@ItemCantMine) ?: run { + selectStack { + isItem(badItem).not() + }.transfer(MainHandContainer)?.start(this@ItemCantMine) ?: failure("No item found or space") + } + } override fun SafeContext.buildRenderer() { withPos(blockPos, color) diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt b/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt index 278c6de8d..3e12b0acb 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt @@ -8,6 +8,7 @@ import com.lambda.interaction.construction.context.BuildContext import com.lambda.interaction.material.ContainerManager.transfer import com.lambda.interaction.material.StackSelection.Companion.select import com.lambda.interaction.material.container.MainHandContainer +import com.lambda.task.Task import com.lambda.task.Task.Companion.failTask import net.minecraft.block.BlockState import net.minecraft.item.Item @@ -18,7 +19,7 @@ import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import java.awt.Color -abstract class BuildResult : ComparableResult { +abstract class BuildResult : ComparableResult, Task() { abstract val blockPos: BlockPos open val pausesParent = false @@ -164,14 +165,19 @@ abstract class BuildResult : ComparableResult { override val blockPos: BlockPos, val context: BuildContext, val neededItem: Item - ) : Resolvable, Drawable, BuildResult() { + ) : Drawable, BuildResult() { override val rank = Rank.WRONG_ITEM private val color = Color(3, 252, 169, 100) override val pausesParent get() = true - override val resolve get() = - neededItem.select().transfer(MainHandContainer)?.solve ?: failTask("Item ${neededItem.name.string} not found") + override fun SafeContext.onStart() { + neededItem.select() + .transfer(MainHandContainer) + ?.onSuccess { _, _ -> + success(Unit) + }?.start(this@WrongItem) ?: failure("Item ${neededItem.name.string} not found") + } override fun SafeContext.buildRenderer() { withBox(Box(blockPos), color) @@ -194,14 +200,19 @@ abstract class BuildResult : ComparableResult { override val blockPos: BlockPos, val context: BuildContext, val neededStack: ItemStack - ) : Resolvable, Drawable, BuildResult() { + ) : Drawable, BuildResult() { override val rank = Rank.WRONG_ITEM private val color = Color(3, 252, 169, 100) override val pausesParent get() = true - override val resolve get() = - neededStack.select().transfer(MainHandContainer)?.solve ?: failTask("Stack ${neededStack.name.string} not found") + override fun SafeContext.onStart() { + neededStack.select() + .transfer(MainHandContainer) + ?.onSuccess { _, _ -> + success(Unit) + }?.start(this@WrongStack) ?: failTask("Stack ${neededStack.name.string} not found") + } override fun SafeContext.buildRenderer() { withPos(blockPos, color) diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt b/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt index 7c79a30d6..b8547dee9 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt @@ -24,14 +24,18 @@ sealed class PlaceResult : BuildResult() { * Represents a successful placement. All checks have been passed. * @param context The context of the placement. */ - data class Success( + data class Place( override val blockPos: BlockPos, - val context: PlaceContext, - ) : Resolvable, Drawable, PlaceResult() { + val context: PlaceContext + ) : Drawable, PlaceResult() { override val rank = Rank.PLACE_SUCCESS private val color = Color(35, 188, 254, 100) - override val resolve get() = placeBlock(context) + override fun SafeContext.onStart() { + placeBlock(context).onSuccess { _, _ -> + success(Unit) + }.start(this@Place) + } override fun SafeContext.buildRenderer() { val hitPos = context.result.blockPos @@ -43,7 +47,7 @@ sealed class PlaceResult : BuildResult() { override fun compareTo(other: ComparableResult): Int { return when (other) { - is Success -> context.compareTo(other.context) + is Place -> context.compareTo(other.context) else -> super.compareTo(other) } } @@ -83,10 +87,14 @@ sealed class PlaceResult : BuildResult() { data class CantReplace( override val blockPos: BlockPos, val simulated: ItemPlacementContext - ) : Resolvable, PlaceResult() { + ) : PlaceResult() { override val rank = Rank.PLACE_CANT_REPLACE - override val resolve = breakBlock(blockPos) + override fun SafeContext.onStart() { + breakBlock(blockPos).onSuccess { _, _ -> + success(Unit) + }.start(this@CantReplace) + } } /** @@ -126,9 +134,7 @@ sealed class PlaceResult : BuildResult() { data class NotItemBlock( override val blockPos: BlockPos, val itemStack: ItemStack - ) : Resolvable, PlaceResult() { + ) : PlaceResult() { override val rank = Rank.PLACE_NOT_ITEM_BLOCK - - override val resolve get() = TODO("Not expected") } } diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt b/common/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt deleted file mode 100644 index 9bfb609c2..000000000 --- a/common/src/main/kotlin/com/lambda/interaction/construction/result/Resolvable.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.lambda.interaction.construction.result - -import com.lambda.task.Task - -interface Resolvable { - val resolve: Task<*> -} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt b/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt index 89becd7fa..073951533 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt @@ -250,7 +250,7 @@ object BuildSimulator { return@forEach } - acc.add(PlaceResult.Success(pos, placeContext)) + acc.add(PlaceResult.Place(pos, placeContext)) } } @@ -336,7 +336,7 @@ object BuildSimulator { player.activeHand, instantBreakable(state, pos) ) - acc.add(BreakResult.Success(pos, breakContext)) + acc.add(BreakResult.Break(pos, breakContext)) return acc } } @@ -392,7 +392,7 @@ object BuildSimulator { stack.item == bestTool }?.let { hand -> breakContext.hand = hand - acc.add(BreakResult.Success(pos, breakContext)) + acc.add(BreakResult.Break(pos, breakContext)) return acc } ?: run { acc.add(BuildResult.WrongItem(pos, breakContext, bestTool)) @@ -400,7 +400,7 @@ object BuildSimulator { } } - acc.add(BreakResult.Success(pos, breakContext)) + acc.add(BreakResult.Break(pos, breakContext)) } return acc diff --git a/common/src/main/kotlin/com/lambda/interaction/material/MaterialContainer.kt b/common/src/main/kotlin/com/lambda/interaction/material/MaterialContainer.kt index f268250ec..b439a4b61 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/MaterialContainer.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/MaterialContainer.kt @@ -72,7 +72,7 @@ abstract class MaterialContainer( // selection.selector = { true } // selection.count = transferAmount - return TransferResult.Success(selection, from = this, to = destination) + return TransferResult.Transfer(selection, from = this, to = destination) } enum class Rank { diff --git a/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt b/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt index 23bd5a5a8..addacadfe 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt @@ -1,32 +1,37 @@ package com.lambda.interaction.material.transfer +import com.lambda.context.SafeContext import com.lambda.interaction.material.MaterialContainer import com.lambda.interaction.material.StackSelection import com.lambda.task.Task -import com.lambda.task.Task.Companion.failTask import com.lambda.task.tasks.ContainerTransfer -abstract class TransferResult { - abstract val solve: Task<*> - - data class Success( +abstract class TransferResult : Task() { + data class Transfer( val selection: StackSelection, val from: MaterialContainer, val to: MaterialContainer ) : TransferResult() { - override val solve = ContainerTransfer(selection, from, to) - val undo = ContainerTransfer(selection, to, from) + override fun SafeContext.onStart() { + ContainerTransfer(selection, from, to).onSuccess { _, _ -> + success(Unit) + }.start(this@Transfer) + } override fun toString() = "Transfer of [$selection] from [${from.name}] to [${to.name}]" } data object NoSpace : TransferResult() { // ToDo: Needs inventory space resolver. compressing or disposing - override val solve = failTask("NoSpace") + override fun SafeContext.onStart() { + failure("No space left in the target container") + } } data class MissingItems(val missing: Int) : TransferResult() { // ToDo: Find other satisfying permutations - override val solve = failTask("MissingItems") + override fun SafeContext.onStart() { + failure("Missing $missing items") + } } } \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/module/hud/TaskFlow.kt b/common/src/main/kotlin/com/lambda/module/hud/TaskFlow.kt new file mode 100644 index 000000000..be056b02c --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/hud/TaskFlow.kt @@ -0,0 +1,19 @@ +package com.lambda.module.hud + +import com.lambda.module.HudModule +import com.lambda.module.tag.ModuleTag +import com.lambda.util.math.Vec2d + +object TaskFlow : HudModule( + name = "TaskFlow", + defaultTags = setOf(ModuleTag.CLIENT), +) { + override val width = 50.0 + override val height = 50.0 + + init { + onRender { + font.build("TaskFlow", Vec2d.ZERO) + } + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/Task.kt b/common/src/main/kotlin/com/lambda/task/Task.kt index 311801b67..6b3bbac83 100644 --- a/common/src/main/kotlin/com/lambda/task/Task.kt +++ b/common/src/main/kotlin/com/lambda/task/Task.kt @@ -99,8 +99,6 @@ abstract class Task : Nameable { COMPLETED, } - operator fun plus(other: Task<*>) = subTasks.add(other) - init { listener { parent?.let { diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt index 810b11ded..b1ac4305c 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt @@ -1,6 +1,5 @@ package com.lambda.task.tasks -import baritone.api.pathing.goals.GoalNear import com.lambda.Lambda.LOG import com.lambda.context.SafeContext import com.lambda.event.events.RenderEvent @@ -25,11 +24,10 @@ class BuildStructure @Ta5kBuilder constructor( private val stayInRange: Boolean = true, private val forceSilkTouch: Boolean = false, val collectDrops: Boolean = TaskFlow.build.collectDrops, - private val cancelOnUnsolvable: Boolean = true, + private val cancelOnUnsolvable: Boolean = false, ) : Task() { private var previousResults = setOf() private var lastResult: BuildResult? = null - private var lastTask: Task<*>? = null override fun SafeContext.onStart() { (blueprint as? DynamicBlueprint)?.create(this) @@ -54,19 +52,7 @@ class BuildStructure @Ta5kBuilder constructor( previousResults = results val result = results.minOrNull() ?: return@listener - lastResult?.let { - if (lastTask?.isCompleted == false && result.rank == it.rank) return@listener -// if (lastTask?.isCompleted == true || it.rank.compareTo(result.rank) == 0) return@listener -// if (it.pausesParent && lastTask?.isCompleted != true) return@listener -// if (/*collectDrops && it is BreakResult.Success && */lastTask?.isCompleted == false && lastTask?.isFailed == false) { -// return@listener -// } - LOG.info("${it.rank.name}${if (it.pausesParent) " (paused)" else ""} -> ${result.rank.name} (${lastTask?.identifier})") - - lastTask?.cancel() - } - - val instantResults = results.filterIsInstance() + val instantResults = results.filterIsInstance() .filter { it.context.instantBreak } .sorted() .take(TaskFlow.build.breaksPerTick) @@ -74,7 +60,7 @@ class BuildStructure @Ta5kBuilder constructor( if (TaskFlow.build.breaksPerTick > 1 && instantResults.isNotEmpty()) { instantResults.forEach { lastResult = it - lastTask = it.resolve.start(this@BuildStructure, pauseParent = false) + it.start(this@BuildStructure, pauseParent = false) } return@listener } @@ -84,27 +70,20 @@ class BuildStructure @Ta5kBuilder constructor( if (!finishOnDone) return@listener success(Unit) } - is Resolvable -> { + is Navigable -> { + if (pathing) BaritoneUtils.setGoalAndPath(result.goal) + } + else -> { + if (lastResult?.isCompleted == false) return@listener + LOG.info("Resolving: $result") - if (result is BreakResult.Success) { + if (result is BreakResult.Break) { result.collectDrop = collectDrops } lastResult = result - lastTask = result.resolve - .start(this@BuildStructure, pauseParent = result.pausesParent) -// if (pathing) { -// BaritoneUtils.setGoalAndPath(GoalNear(result.blockPos, 3)) -// } - } - is Navigable -> { - if (pathing) BaritoneUtils.setGoalAndPath(result.goal) - } - else -> { - if (!cancelOnUnsolvable) return@listener - - failure("Failed to resolve build result: $result") + result.start(this@BuildStructure, pauseParent = result.pausesParent) } } } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt b/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt index db9d39975..08788235f 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt @@ -5,7 +5,7 @@ import com.lambda.interaction.material.MaterialContainer import com.lambda.interaction.material.StackSelection import com.lambda.task.Task -class ContainerTransfer( +class ContainerTransfer @Ta5kBuilder constructor( val selection: StackSelection, val from: MaterialContainer, val to: MaterialContainer diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index 1fecd3daa..5c0ea7f5c 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -19,6 +19,7 @@ class PlaceBlock @Ta5kBuilder constructor( private val waitForConfirmation: Boolean, ) : Task() { private var beginState: BlockState? = null + override var timeout = 20 private var state = State.PLACING private var inScope = 0 diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt index 5975cfc94..d1b161ce6 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt @@ -13,13 +13,10 @@ import com.lambda.task.tasks.BuildStructure.Companion.buildStructure import com.lambda.util.BlockUtils.blockPos import com.lambda.util.item.ItemUtils.shulkerBoxes import net.minecraft.block.ChestBlock -import net.minecraft.block.ShulkerBoxBlock -import net.minecraft.block.entity.ShulkerBoxBlockEntity import net.minecraft.entity.mob.ShulkerEntity import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box import net.minecraft.util.math.Direction class PlaceContainer @Ta5kBuilder constructor( @@ -38,7 +35,7 @@ class PlaceContainer @Ta5kBuilder constructor( // val res = results.sorted() // res - val succeeds = results.filterIsInstance().filter { + val succeeds = results.filterIsInstance().filter { canBeOpened(stack, it.blockPos, it.context.result.side) } val wrongStacks = results.filterIsInstance().filter { From 5d4542944c19a4614070547c45d3c1ccbd4fdda2 Mon Sep 17 00:00:00 2001 From: Constructor Date: Tue, 6 Aug 2024 05:15:32 +0200 Subject: [PATCH 10/16] Further simplifications --- .../construction/result/PlaceResult.kt | 2 +- .../material/container/ShulkerBoxContainer.kt | 2 +- .../material/transfer/TransferResult.kt | 7 ++--- .../module/modules/player/HighwayTools.kt | 26 ++++++++----------- .../module/modules/player/InventoryTweaks.kt | 2 +- .../com/lambda/module/modules/player/Nuker.kt | 4 +-- .../src/main/kotlin/com/lambda/task/Task.kt | 23 ++++++++-------- .../tasks/{BuildStructure.kt => BuildTask.kt} | 16 +++++++----- .../lambda/task/tasks/ContainerTransfer.kt | 20 -------------- .../com/lambda/task/tasks/PlaceBlock.kt | 1 - .../com/lambda/task/tasks/PlaceContainer.kt | 4 +-- 11 files changed, 42 insertions(+), 65 deletions(-) rename common/src/main/kotlin/com/lambda/task/tasks/{BuildStructure.kt => BuildTask.kt} (92%) delete mode 100644 common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt b/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt index b8547dee9..f1d281ddc 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt @@ -4,7 +4,7 @@ import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalInverted import com.lambda.context.SafeContext import com.lambda.interaction.construction.context.PlaceContext -import com.lambda.task.tasks.BuildStructure.Companion.breakBlock +import com.lambda.task.tasks.BuildTask.Companion.breakBlock import com.lambda.task.tasks.PlaceBlock.Companion.placeBlock import net.minecraft.block.BlockState import net.minecraft.item.ItemPlacementContext diff --git a/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt b/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt index 5f02c5a40..332a26403 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/container/ShulkerBoxContainer.kt @@ -4,7 +4,7 @@ import com.lambda.context.SafeContext import com.lambda.interaction.material.MaterialContainer import com.lambda.interaction.material.StackSelection import com.lambda.task.Task -import com.lambda.task.tasks.BuildStructure.Companion.breakAndCollectBlock +import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.InventoryTask.Companion.deposit import com.lambda.task.tasks.InventoryTask.Companion.withdraw import com.lambda.task.tasks.OpenContainer.Companion.openContainer diff --git a/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt b/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt index addacadfe..42f6f03e7 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/transfer/TransferResult.kt @@ -4,7 +4,6 @@ import com.lambda.context.SafeContext import com.lambda.interaction.material.MaterialContainer import com.lambda.interaction.material.StackSelection import com.lambda.task.Task -import com.lambda.task.tasks.ContainerTransfer abstract class TransferResult : Task() { data class Transfer( @@ -13,8 +12,10 @@ abstract class TransferResult : Task() { val to: MaterialContainer ) : TransferResult() { override fun SafeContext.onStart() { - ContainerTransfer(selection, from, to).onSuccess { _, _ -> - success(Unit) + from.withdraw(selection).thenRun(this@Transfer) { _, _ -> + to.deposit(selection).onSuccess { _, _ -> + success(Unit) + } }.start(this@Transfer) } diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt b/common/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt index 0f19ba304..984f2b81f 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt @@ -5,7 +5,7 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.Task -import com.lambda.task.tasks.BuildStructure.Companion.buildStructure +import com.lambda.task.tasks.BuildTask.Companion.build import com.lambda.util.BaritoneUtils import com.lambda.util.Communication.info import com.lambda.util.player.MovementUtils.octant @@ -60,25 +60,21 @@ object HighwayTools : Module( repeat(sliceSize) { val vec = Vec3i(octant.offsetX, 0, octant.offsetZ) currentPos = currentPos.add(vec) - structure += slice.map { it.key.add(currentPos) to it.value } + structure = structure.plus(slice.map { it.key.add(currentPos) to it.value }) } - runningTask = buildStructure { + runningTask = build { structure.toBlueprint() - }.apply { - onSuccess { _, _ -> - if (distanceMoved < distance || distance < 0) { - buildSlice() - } else { - this@HighwayTools.info("Highway built") - disable() - } - } - onFailure { _, _ -> + }.onSuccess { _, _ -> + if (distanceMoved < distance || distance < 0) { + buildSlice() + } else { + this@HighwayTools.info("Highway built") disable() } - start(null) - } + }.onFailure { _, _ -> + disable() + }.start(null) } private fun highwaySlice(): Structure { diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index 08f83a273..6cc6ebd64 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -7,7 +7,7 @@ import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.Task -import com.lambda.task.tasks.BuildStructure.Companion.breakAndCollectBlock +import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainer.Companion.openContainer import com.lambda.task.tasks.PlaceContainer.Companion.placeContainer import com.lambda.util.item.ItemUtils.shulkerBoxes diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt b/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt index fc5da0fed..e89c2ad9b 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt @@ -5,7 +5,7 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.Task.Companion.emptyTask -import com.lambda.task.tasks.BuildStructure.Companion.buildStructure +import com.lambda.task.tasks.BuildTask.Companion.build import com.lambda.util.BlockUtils.blockPos import com.lambda.util.BlockUtils.blockState import net.minecraft.util.math.BlockPos @@ -25,7 +25,7 @@ object Nuker : Module( init { onEnable { - task = buildStructure( + task = build( pathing = false, finishOnDone = false, cancelOnUnsolvable = false diff --git a/common/src/main/kotlin/com/lambda/task/Task.kt b/common/src/main/kotlin/com/lambda/task/Task.kt index 6b3bbac83..9117bffb8 100644 --- a/common/src/main/kotlin/com/lambda/task/Task.kt +++ b/common/src/main/kotlin/com/lambda/task/Task.kt @@ -74,12 +74,11 @@ abstract class Task : Nameable { private var state = State.IDLE var age = 0 - private val isDeactivated get() = state == State.DEACTIVATED - val isActivated get() = state == State.ACTIVATED - val isRunning get() = state == State.ACTIVATED || state == State.DEACTIVATED + private val isWaiting get() = state == State.WAITING + private val isRunning get() = state == State.RUNNING val isFailed get() = state == State.FAILED val isCompleted get() = state == State.COMPLETED || state == State.COOLDOWN - val isRoot get() = parent == null + private val isRoot get() = parent == null override var name = this::class.simpleName ?: "Task" val identifier get() = "$name@${hashCode()}" @@ -91,8 +90,8 @@ abstract class Task : Nameable { enum class State { IDLE, - ACTIVATED, - DEACTIVATED, + RUNNING, + WAITING, CANCELLED, FAILED, COOLDOWN, @@ -129,7 +128,7 @@ abstract class Task : Nameable { LOG.info("${owner.identifier} started $identifier") this.parent = owner - if (pauseParent && owner.isActivated && !owner.isRoot) { + if (pauseParent && owner.isRunning && !owner.isRoot) { LOG.info("$identifier deactivating parent ${owner.identifier}") owner.deactivate() } @@ -144,15 +143,15 @@ abstract class Task : Nameable { @Ta5kBuilder fun activate() { - if (isActivated) return - state = State.ACTIVATED + if (isRunning) return + state = State.RUNNING startListening() } @Ta5kBuilder fun deactivate() { - if (isDeactivated) return - state = State.DEACTIVATED + if (isWaiting) return + state = State.WAITING stopListening() } @@ -266,7 +265,7 @@ abstract class Task : Nameable { LOG.info("$identifier completed parent ${par.identifier}") par.notifyParent() } - !par.isActivated -> { + !par.isRunning -> { LOG.info("$identifier reactivated parent ${par.identifier}") par.activate() } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt b/common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt similarity index 92% rename from common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt rename to common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index b1ac4305c..0388103da 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BuildStructure.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -17,7 +17,7 @@ import com.lambda.task.Task import com.lambda.util.BaritoneUtils import net.minecraft.util.math.BlockPos -class BuildStructure @Ta5kBuilder constructor( +class BuildTask @Ta5kBuilder constructor( private val blueprint: Blueprint, private val finishOnDone: Boolean = true, private val pathing: Boolean = TaskFlow.build.pathing, @@ -60,7 +60,7 @@ class BuildStructure @Ta5kBuilder constructor( if (TaskFlow.build.breaksPerTick > 1 && instantResults.isNotEmpty()) { instantResults.forEach { lastResult = it - it.start(this@BuildStructure, pauseParent = false) + it.start(this@BuildTask, pauseParent = false) } return@listener } @@ -71,6 +71,8 @@ class BuildStructure @Ta5kBuilder constructor( success(Unit) } is Navigable -> { + if (lastResult?.isCompleted == false) return@listener + if (pathing) BaritoneUtils.setGoalAndPath(result.goal) } else -> { @@ -83,7 +85,7 @@ class BuildStructure @Ta5kBuilder constructor( } lastResult = result - result.start(this@BuildStructure, pauseParent = result.pausesParent) + result.start(this@BuildTask, pauseParent = result.pausesParent) } } } @@ -91,7 +93,7 @@ class BuildStructure @Ta5kBuilder constructor( companion object { @Ta5kBuilder - fun buildStructure( + fun build( finishOnDone: Boolean = true, pathing: Boolean = TaskFlow.build.pathing, stayInRange: Boolean = true, @@ -99,7 +101,7 @@ class BuildStructure @Ta5kBuilder constructor( collectDrops: Boolean = TaskFlow.build.collectDrops, cancelOnUnsolvable: Boolean = true, blueprint: () -> Blueprint, - ) = BuildStructure( + ) = BuildTask( blueprint(), finishOnDone, pathing, @@ -114,7 +116,7 @@ class BuildStructure @Ta5kBuilder constructor( blockPos: BlockPos, withSilkTouch: Boolean = false, stayInRange: Boolean = false, - ) = BuildStructure( + ) = BuildTask( blockPos.toStructure(TargetState.Air).toBlueprint(), forceSilkTouch = withSilkTouch, stayInRange = stayInRange, @@ -124,7 +126,7 @@ class BuildStructure @Ta5kBuilder constructor( @Ta5kBuilder fun breakBlock( blockPos: BlockPos, - ) = BuildStructure( + ) = BuildTask( blockPos.toStructure(TargetState.Air).toBlueprint() ) } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt b/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt deleted file mode 100644 index 08788235f..000000000 --- a/common/src/main/kotlin/com/lambda/task/tasks/ContainerTransfer.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.lambda.task.tasks - -import com.lambda.context.SafeContext -import com.lambda.interaction.material.MaterialContainer -import com.lambda.interaction.material.StackSelection -import com.lambda.task.Task - -class ContainerTransfer @Ta5kBuilder constructor( - val selection: StackSelection, - val from: MaterialContainer, - val to: MaterialContainer -) : Task() { - override fun SafeContext.onStart() { - from.withdraw(selection).thenRun(this@ContainerTransfer) { _, _ -> - to.deposit(selection).onSuccess { _, _ -> - success(Unit) - } - }.start(this@ContainerTransfer) - } -} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index 5c0ea7f5c..1fecd3daa 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -19,7 +19,6 @@ class PlaceBlock @Ta5kBuilder constructor( private val waitForConfirmation: Boolean, ) : Task() { private var beginState: BlockState? = null - override var timeout = 20 private var state = State.PLACING private var inScope = 0 diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt index d1b161ce6..669032f13 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceContainer.kt @@ -9,7 +9,7 @@ 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.task.Task -import com.lambda.task.tasks.BuildStructure.Companion.buildStructure +import com.lambda.task.tasks.BuildTask.Companion.build import com.lambda.util.BlockUtils.blockPos import com.lambda.util.item.ItemUtils.shulkerBoxes import net.minecraft.block.ChestBlock @@ -43,7 +43,7 @@ class PlaceContainer @Ta5kBuilder constructor( canBeOpened(stack, it.blockPos, result.side) } (succeeds + wrongStacks).minOrNull()?.let { result -> - buildStructure { + build { result.blockPos .toStructure(TargetState.Stack(stack)) .toBlueprint() From 5394f6458ed42334117e63e6de0a6f2457d585c4 Mon Sep 17 00:00:00 2001 From: Constructor Date: Tue, 20 Aug 2024 06:17:34 +0200 Subject: [PATCH 11/16] Fix imports --- .../kotlin/com/lambda/command/commands/TaskCommand.kt | 2 +- .../src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt | 2 +- .../main/kotlin/com/lambda/task/tasks/InventoryTask.kt | 9 ++------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt b/common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt index 5ff321449..772f2d7c0 100644 --- a/common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt +++ b/common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt @@ -6,7 +6,7 @@ import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.task.RootTask import com.lambda.util.Communication.info -import com.lambda.util.primitives.extension.CommandBuilder +import com.lambda.util.extension.CommandBuilder object TaskCommand : LambdaCommand( name = "task", diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt index 06cee03c9..5f78d87eb 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt @@ -14,10 +14,10 @@ import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task import com.lambda.util.BaritoneUtils import com.lambda.util.BlockUtils.blockState +import com.lambda.util.extension.inventorySlots import com.lambda.util.item.ItemUtils.block import com.lambda.util.player.SlotUtils.clickSlot import com.lambda.util.player.SlotUtils.hotbarAndStorage -import com.lambda.util.primitives.extension.inventorySlots import net.minecraft.block.BlockState import net.minecraft.entity.ItemEntity import net.minecraft.screen.slot.SlotActionType diff --git a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt index 7efe78774..88bca3bb0 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt @@ -1,20 +1,15 @@ package com.lambda.task.tasks import com.lambda.context.SafeContext -import com.lambda.event.events.ScreenHandlerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.interaction.material.StackSelection import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task -import com.lambda.threading.runConcurrent -import com.lambda.threading.runGameScheduled +import com.lambda.util.extension.containerSlots +import com.lambda.util.extension.inventorySlots import com.lambda.util.item.ItemUtils.block import com.lambda.util.player.SlotUtils.clickSlot -import com.lambda.util.primitives.extension.containerSlots -import com.lambda.util.primitives.extension.inventorySlots -import kotlinx.coroutines.delay -import net.minecraft.item.ItemStack import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.Slot import net.minecraft.screen.slot.SlotActionType From bc5f6d6991b8ae86c988e6e672dfeb559827b698 Mon Sep 17 00:00:00 2001 From: Constructor Date: Sun, 22 Sep 2024 03:23:05 +0200 Subject: [PATCH 12/16] Build command and pending placements --- .../com/lambda/command/LambdaCommand.kt | 2 +- .../lambda/command/commands/BuildCommand.kt | 48 ++++++++++++++ .../config/groups/InteractionSettings.kt | 4 +- .../interaction/construction/Blueprint.kt | 2 + .../construction/DynamicBlueprint.kt | 8 +-- .../com/lambda/module/modules/player/Nuker.kt | 19 +++--- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 62 ++++++++++++++++--- .../com/lambda/task/tasks/PlaceBlock.kt | 26 +++++--- .../com/lambda/util/TransformedObservable.kt | 21 ------- 9 files changed, 136 insertions(+), 56 deletions(-) create mode 100644 common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt delete mode 100644 common/src/main/kotlin/com/lambda/util/TransformedObservable.kt diff --git a/common/src/main/kotlin/com/lambda/command/LambdaCommand.kt b/common/src/main/kotlin/com/lambda/command/LambdaCommand.kt index 96ba26a83..4a5f5f10c 100644 --- a/common/src/main/kotlin/com/lambda/command/LambdaCommand.kt +++ b/common/src/main/kotlin/com/lambda/command/LambdaCommand.kt @@ -22,7 +22,7 @@ abstract class LambdaCommand( // ToDo: Include usage and description in the help command init { (listOf(name) + aliases).forEach { - val argument = LiteralArgumentBuilder.literal(it) + val argument = LiteralArgumentBuilder.literal(it.lowercase()) argument.create() dispatcher.register(argument) } diff --git a/common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt b/common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt new file mode 100644 index 000000000..e6a605d71 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt @@ -0,0 +1,48 @@ +package com.lambda.command.commands + +import com.lambda.brigadier.argument.literal +import com.lambda.brigadier.execute +import com.lambda.brigadier.required +import com.lambda.command.LambdaCommand +import com.lambda.interaction.construction.Blueprint.Companion.toStructure +import com.lambda.interaction.construction.DynamicBlueprint.Companion.toBlueprint +import com.lambda.interaction.construction.verify.TargetState +import com.lambda.task.tasks.BuildTask.Companion.build +import com.lambda.threading.runSafe +import com.lambda.util.extension.CommandBuilder +import net.minecraft.block.Blocks +import net.minecraft.util.math.BlockBox + +object BuildCommand : LambdaCommand( + name = "Build", + description = "Builds a structure", + usage = "build " +) { + override fun CommandBuilder.create() { + required(literal("place")) { + execute { + runSafe { + val materials = setOf( + TargetState.Block(Blocks.NETHERRACK), + TargetState.Block(Blocks.AIR), + TargetState.Block(Blocks.GOLD_BLOCK), + TargetState.Block(Blocks.AIR), + ) + val facing = player.horizontalFacing + val pos = player.blockPos.add(facing.vector.multiply(2)) + + BlockBox.create(pos, pos.add(facing.rotateYClockwise().vector.multiply(4))) + .toStructure(TargetState.Block(Blocks.NETHERRACK)) + .toBlueprint { +// it.mapValues { (_, _) -> +// materials.elementAt((System.currentTimeMillis() / 5000).toInt() % materials.size) +// } + it + } + .build(finishOnDone = false) + .start(null) + } + } + } + } +} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt b/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt index 2897175d5..f23768066 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/InteractionSettings.kt @@ -8,12 +8,12 @@ import com.lambda.util.world.raycast.RayCastMask class InteractionSettings( c: Configurable, - defaultReach: Double = 4.9, + defaultReach: Double = 4.6, vis: () -> Boolean = { true }, ) : InteractionConfig { override val reach by c.setting("Reach", defaultReach, 0.1..10.0, 0.1, "Players reach / range", " blocks", vis) override val useRayCast by c.setting("Raycast", true, "Verify hit vector with ray casting (for very strict ACs)", vis) - override val resolution by c.setting("Resolution", 20, 1..40, 1, "How many raycast checks per surface (will be squared)") { vis() && useRayCast } + override val resolution by c.setting("Resolution", 4, 1..40, 1, "How many raycast checks per surface (will be squared)") { vis() && useRayCast } override val swingHand by c.setting("Swing Hand", true, "Swing hand on interactions", vis) override val pingTimeout by c.setting("Ping Timeout", false, "Timeout on high ping", vis) override val inScopeThreshold by c.setting("Constant Timeout", 1, 0..20, 1, "How many ticks to wait after target box is in rotation scope"," ticks") { diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/Blueprint.kt b/common/src/main/kotlin/com/lambda/interaction/construction/Blueprint.kt index 8d9ca25e6..6678755db 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/Blueprint.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/Blueprint.kt @@ -21,6 +21,8 @@ abstract class Blueprint { } companion object { + fun emptyStructure(): Structure = emptyMap() + fun Box.toStructure(targetState: TargetState): Structure = BlockPos.stream(this) .map { it.blockPos } diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/DynamicBlueprint.kt b/common/src/main/kotlin/com/lambda/interaction/construction/DynamicBlueprint.kt index 12227c181..61686acce 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/DynamicBlueprint.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/DynamicBlueprint.kt @@ -26,13 +26,9 @@ data class DynamicBlueprint( }.toMap() } - fun blueprintOnTick( - init: SafeContext.(Structure) -> Structure = { emptyMap() }, - onTick: SafeContext.(Structure) -> Structure - ) = DynamicBlueprint(init = init, update = onTick) - fun Structure.toBlueprint( + init: SafeContext.(Structure) -> Structure = { this@toBlueprint }, onTick: SafeContext.(Structure) -> Structure - ) = DynamicBlueprint(init = { emptyMap() }, update = onTick) + ) = DynamicBlueprint(init = init, update = onTick) } } diff --git a/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt b/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt index e89c2ad9b..c60ea9205 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt @@ -1,6 +1,7 @@ package com.lambda.module.modules.player -import com.lambda.interaction.construction.DynamicBlueprint.Companion.blueprintOnTick +import com.lambda.interaction.construction.Blueprint.Companion.emptyStructure +import com.lambda.interaction.construction.DynamicBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.Module import com.lambda.module.tag.ModuleTag @@ -25,12 +26,8 @@ object Nuker : Module( init { onEnable { - task = build( - pathing = false, - finishOnDone = false, - cancelOnUnsolvable = false - ) { - blueprintOnTick { _ -> + task = emptyStructure() + .toBlueprint { val selection = BlockPos.iterateOutwards(player.blockPos, width, height, width) .asSequence() .map { it.blockPos } @@ -44,12 +41,16 @@ object Nuker : Module( val floor = BlockPos.iterateOutwards(player.blockPos.down(), width, 0, width) .map { it.blockPos } .associateWith { TargetState.Solid } - return@blueprintOnTick selection + floor + return@toBlueprint selection + floor } selection } - } + .build( + pathing = false, + finishOnDone = false, + cancelOnUnsolvable = false + ) task.start(null) } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index 0388103da..1ae7d7e62 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -15,6 +15,7 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task import com.lambda.util.BaritoneUtils +import com.lambda.util.extension.Structure import net.minecraft.util.math.BlockPos class BuildTask @Ta5kBuilder constructor( @@ -27,7 +28,9 @@ class BuildTask @Ta5kBuilder constructor( private val cancelOnUnsolvable: Boolean = false, ) : Task() { private var previousResults = setOf() - private var lastResult: BuildResult? = null + private val placeTimeout = 15 + private val breakTimeout = 15 + private val pending = mutableListOf() override fun SafeContext.onStart() { (blueprint as? DynamicBlueprint)?.create(this) @@ -41,6 +44,15 @@ class BuildTask @Ta5kBuilder constructor( } listener { + pending.removeIf { + if (it.age > placeTimeout) { + it.cancel() + true + } else { + it.isCompleted + } + } + (blueprint as? DynamicBlueprint)?.update(this) if (finishOnDone && blueprint.structure.isEmpty()) { @@ -59,32 +71,32 @@ class BuildTask @Ta5kBuilder constructor( if (TaskFlow.build.breaksPerTick > 1 && instantResults.isNotEmpty()) { instantResults.forEach { - lastResult = it + pending.add(it) it.start(this@BuildTask, pauseParent = false) } return@listener } + if (pending.isNotEmpty()) { + return@listener + } + when (result) { is BuildResult.Done, is BuildResult.Unbreakable -> { if (!finishOnDone) return@listener success(Unit) } is Navigable -> { - if (lastResult?.isCompleted == false) return@listener - if (pathing) BaritoneUtils.setGoalAndPath(result.goal) } else -> { - if (lastResult?.isCompleted == false) return@listener - LOG.info("Resolving: $result") if (result is BreakResult.Break) { result.collectDrop = collectDrops } - lastResult = result + pending.add(result) result.start(this@BuildTask, pauseParent = result.pausesParent) } } @@ -111,6 +123,42 @@ class BuildTask @Ta5kBuilder constructor( cancelOnUnsolvable ) + @Ta5kBuilder + fun Structure.build( + finishOnDone: Boolean = true, + pathing: Boolean = TaskFlow.build.pathing, + stayInRange: Boolean = true, + forceSilkTouch: Boolean = false, + collectDrops: Boolean = TaskFlow.build.collectDrops, + cancelOnUnsolvable: Boolean = true, + ) = BuildTask( + toBlueprint(), + finishOnDone, + pathing, + stayInRange, + forceSilkTouch, + collectDrops, + cancelOnUnsolvable + ) + + @Ta5kBuilder + fun Blueprint.build( + finishOnDone: Boolean = true, + pathing: Boolean = TaskFlow.build.pathing, + stayInRange: Boolean = true, + forceSilkTouch: Boolean = false, + collectDrops: Boolean = TaskFlow.build.collectDrops, + cancelOnUnsolvable: Boolean = true, + ) = BuildTask( + this, + finishOnDone, + pathing, + stayInRange, + forceSilkTouch, + collectDrops, + cancelOnUnsolvable + ) + @Ta5kBuilder fun breakAndCollectBlock( blockPos: BlockPos, diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index f064b6881..4b44f2f6d 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -4,9 +4,9 @@ import com.lambda.Lambda.LOG import com.lambda.config.groups.InteractionConfig import com.lambda.context.SafeContext import com.lambda.event.events.RotationEvent +import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.interaction.blockplace.PlaceInteraction.placeBlock import com.lambda.interaction.construction.context.PlaceContext import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task @@ -20,8 +20,8 @@ class PlaceBlock @Ta5kBuilder constructor( private val waitForConfirmation: Boolean, ) : Task() { private var beginState: BlockState? = null - private var state = State.PLACING - private var inScope = 0 + private var state = State.ROTATING + private var t = false private val SafeContext.resultingState: BlockState get() = ctx.resultingPos.blockState(world) @@ -29,7 +29,7 @@ class PlaceBlock @Ta5kBuilder constructor( ctx.targetState.matches(ctx.resultingPos.blockState(world), ctx.resultingPos, world) enum class State { - PLACING, CONFIRMING + ROTATING, PLACING, CONFIRMING } override fun SafeContext.onStart() { @@ -46,22 +46,28 @@ class PlaceBlock @Ta5kBuilder constructor( init { listener { event -> + if (state != State.ROTATING) return@listener if (!rotate) return@listener event.context = ctx.rotation } - listener { + listener { event -> + if (state != State.ROTATING) return@listener if (!rotate) return@listener + if (event.context != ctx.rotation) return@listener + if (!event.context.isValid) return@listener + + state = State.PLACING + } + + listener { if (state != State.PLACING) return@listener - if (!it.context.isValid) return@listener - if (inScope++ >= interact.scopeThreshold) { - placeBlock() - } + if (t) placeBlock() + t = true } listener { - if (state != State.CONFIRMING) return@listener if (it.pos != ctx.resultingPos) return@listener if (ctx.targetState.matches(it.state, it.pos, world)) { diff --git a/common/src/main/kotlin/com/lambda/util/TransformedObservable.kt b/common/src/main/kotlin/com/lambda/util/TransformedObservable.kt deleted file mode 100644 index dec109bfe..000000000 --- a/common/src/main/kotlin/com/lambda/util/TransformedObservable.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.lambda.util - -import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty - -abstract class TransformedObservable(initialValue: T) : ReadWriteProperty { - private var value = initialValue - - override fun getValue(thisRef: Any?, property: KProperty<*>) = value - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - val oldValue = this.value - this.value = transform(value) - if (oldValue != this.value) onChange(oldValue, this.value) - } - - protected open fun transform(value: T): T = value - protected open fun onChange(oldValue: T, newValue: T) {} - - override fun toString(): String = "TransformedObservableProperty(value=$value)" -} From abbdb9ced9332a1bb6ba1e581bbdd27125d8698c Mon Sep 17 00:00:00 2001 From: Constructor Date: Tue, 24 Sep 2024 02:17:23 +0200 Subject: [PATCH 13/16] Dynamic disposables and rotation fix for breaking --- .../lambda/command/commands/BuildCommand.kt | 11 ++++----- .../construction/verify/TargetState.kt | 5 ++-- .../interaction/material/ContainerManager.kt | 9 ++++---- .../com/lambda/task/tasks/BreakBlock.kt | 11 ++++----- .../com/lambda/task/tasks/HelloWorldTask.kt | 23 ------------------- .../com/lambda/task/tasks/PlaceBlock.kt | 6 ++--- 6 files changed, 21 insertions(+), 44 deletions(-) delete mode 100644 common/src/main/kotlin/com/lambda/task/tasks/HelloWorldTask.kt diff --git a/common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt b/common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt index e6a605d71..a065cf754 100644 --- a/common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt +++ b/common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt @@ -25,19 +25,18 @@ object BuildCommand : LambdaCommand( val materials = setOf( TargetState.Block(Blocks.NETHERRACK), TargetState.Block(Blocks.AIR), - TargetState.Block(Blocks.GOLD_BLOCK), + TargetState.Block(Blocks.COBBLESTONE), TargetState.Block(Blocks.AIR), ) val facing = player.horizontalFacing val pos = player.blockPos.add(facing.vector.multiply(2)) - BlockBox.create(pos, pos.add(facing.rotateYClockwise().vector.multiply(4))) + BlockBox.create(pos, pos.add(facing.rotateYClockwise().vector.multiply(3))) .toStructure(TargetState.Block(Blocks.NETHERRACK)) .toBlueprint { -// it.mapValues { (_, _) -> -// materials.elementAt((System.currentTimeMillis() / 5000).toInt() % materials.size) -// } - it + it.mapValues { (_, _) -> + materials.elementAt((System.currentTimeMillis() / 5000).toInt() % materials.size) + } } .build(finishOnDone = false) .start(null) diff --git a/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index 16abd9ac9..7238654a0 100644 --- a/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/common/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -1,5 +1,6 @@ package com.lambda.interaction.construction.verify +import com.lambda.interaction.material.ContainerManager.findDisposable import com.lambda.util.BlockUtils.blockState import com.lambda.util.item.ItemUtils.block import net.minecraft.block.BlockState @@ -20,7 +21,7 @@ sealed class TargetState : StateMatcher { override fun matches(state: BlockState, pos: BlockPos, world: ClientWorld) = state.isSolidBlock(world, pos) override fun getStack(world: ClientWorld, pos: BlockPos) = - ItemStack(Items.NETHERRACK) // ToDo: Find any disposable block + findDisposable()?.stacks?.firstOrNull() ?: ItemStack(Items.NETHERRACK) } data class Support(val direction: Direction) : TargetState() { override fun matches(state: BlockState, pos: BlockPos, world: ClientWorld) = @@ -28,7 +29,7 @@ sealed class TargetState : StateMatcher { || state.isSolidBlock(world, pos) override fun getStack(world: ClientWorld, pos: BlockPos) = - ItemStack(Items.NETHERRACK) // ToDo: Find any disposable block + findDisposable()?.stacks?.firstOrNull() ?: ItemStack(Items.NETHERRACK) } data class State(val blockState: BlockState) : TargetState() { override fun matches(state: BlockState, pos: BlockPos, world: ClientWorld) = diff --git a/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt b/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt index d9de3bda7..da9d5fa7d 100644 --- a/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt +++ b/common/src/main/kotlin/com/lambda/interaction/material/ContainerManager.kt @@ -6,7 +6,9 @@ import com.lambda.event.events.ScreenHandlerEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.interaction.material.StackSelection.Companion.select import com.lambda.interaction.material.container.* +import com.lambda.module.modules.client.TaskFlow import com.lambda.util.BlockUtils.blockEntity +import com.lambda.util.BlockUtils.item import com.lambda.util.Communication.info import com.lambda.util.item.ItemUtils import com.lambda.util.extension.containerStacks @@ -18,10 +20,7 @@ import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.screen.GenericContainerScreenHandler -import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType -import org.reflections.util.ClasspathHelper.forPackage -import java.util.* // ToDo: Make this a Configurable to save container caches. Should use a cached region based storage system. object ContainerManager : Loadable { @@ -114,7 +113,9 @@ object ContainerManager : Loadable { it.second }?.first -// fun SafeContext.nextDisposable() = player.combined.firstOrNull { it.item in TaskFlow.disposables } + fun findDisposable() = container().find { container -> + TaskFlow.disposables.any { container.available(it.item.select()) >= 0 } + } class NoContainerFound(selection: StackSelection): Exception("No container found matching $selection") } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt index 5f78d87eb..205ef6e3f 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt @@ -41,6 +41,7 @@ class BreakBlock @Ta5kBuilder constructor( private var drop: ItemEntity? = null private var state = State.BREAKING + private var isValid = false private var inScope = 0 enum class State { @@ -61,18 +62,16 @@ class BreakBlock @Ta5kBuilder constructor( init { listener { event -> + if (state != State.BREAKING) return@listener if (!rotate) return@listener event.context = lookAtBlock(blockPos, rotation, interact, sides) } listener { - if (!rotate) return@listener if (state != State.BREAKING) return@listener - if (!it.context.isValid) return@listener + if (!rotate) return@listener - if (inScope++ >= interact.inScopeThreshold) { - breakBlock(ctx.result.side) - } + isValid = it.context.isValid } listener { @@ -93,7 +92,7 @@ class BreakBlock @Ta5kBuilder constructor( BaritoneUtils.setGoalAndPath(GoalBlock(itemDrop.blockPos)) } ?: BaritoneUtils.cancel() - if (!rotate) { + if (isValid || !rotate) { breakBlock(ctx.result.side) } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/HelloWorldTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/HelloWorldTask.kt deleted file mode 100644 index 3fcf01079..000000000 --- a/common/src/main/kotlin/com/lambda/task/tasks/HelloWorldTask.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.lambda.task.tasks - -import com.lambda.Lambda.LOG -import com.lambda.event.events.TickEvent -import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.task.Task - -class HelloWorldTask @Ta5kBuilder constructor() : Task() { - init { - listener { - LOG.info("$name: ticking $age") - - if (age > 20) { - success(Unit) - } - } - } - - companion object { - @Ta5kBuilder - fun helloWorld() = HelloWorldTask() - } -} \ No newline at end of file diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index 4b44f2f6d..1bc820a85 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -21,7 +21,7 @@ class PlaceBlock @Ta5kBuilder constructor( ) : Task() { private var beginState: BlockState? = null private var state = State.ROTATING - private var t = false + private var findOutIfNeeded = false private val SafeContext.resultingState: BlockState get() = ctx.resultingPos.blockState(world) @@ -63,8 +63,8 @@ class PlaceBlock @Ta5kBuilder constructor( listener { if (state != State.PLACING) return@listener - if (t) placeBlock() - t = true + if (findOutIfNeeded) placeBlock() + findOutIfNeeded = true } listener { From 59fbffab6b8d37b293999837a7df613a069cee6c Mon Sep 17 00:00:00 2001 From: Constructor Date: Tue, 24 Sep 2024 02:44:33 +0200 Subject: [PATCH 14/16] Next tick stack check --- .../com/lambda/config/groups/BuildSettings.kt | 2 +- .../com/lambda/task/tasks/InventoryTask.kt | 24 +++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt b/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt index ab4a6554a..98ffe549d 100644 --- a/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt +++ b/common/src/main/kotlin/com/lambda/config/groups/BuildSettings.kt @@ -17,7 +17,7 @@ class BuildSettings( override val breakConfirmation by c.setting("Break Confirmation", false, "Wait for block break confirmation") { vis() && page == Page.BREAK } override val breakWeakBlocks by c.setting("Break Weak Blocks", false, "Break blocks that dont have structural integrity (e.g: grass)") { vis() && page == Page.BREAK } override val breaksPerTick by c.setting("Instant Breaks Per Tick", 10, 1..30, 1, "Maximum instant block breaks per tick") { vis() && page == Page.BREAK } - override val rotateForBreak by c.setting("Rotate For Break", false, "Rotate towards block while breaking") { vis() && page == Page.BREAK } + override val rotateForBreak by c.setting("Rotate For Break", true, "Rotate towards block while breaking") { vis() && page == Page.BREAK } override val collectDrops by c.setting("Collect All Drops", false, "Collect all drops when breaking blocks") { vis() && page == Page.BREAK } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt index 88bca3bb0..0ba6fb1ce 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt @@ -28,6 +28,15 @@ class InventoryTask( // ToDo: Needs smart code to move as efficient as possible. // Also should handle overflow etc. Should be more generic listener { + val moved = selector.filterSlots(to) + .filter { it.hasStack() } + .sumOf { it.stack.count } >= selector.count + + if (selectedFrom.isEmpty() || moved) { + if (closeScreen) player.closeHandledScreen() + success(Unit) + } + selector.filterSlots(from).firstOrNull { it.hasStack() }?.let { from -> // player.currentScreenHandler // .inventorySlots @@ -47,25 +56,10 @@ class InventoryTask( clickSlot(emptySlot.id, 0, SlotActionType.SWAP) clickSlot(from.id, 0, SlotActionType.SWAP) } - } ?: finish() - } - - listener { - val moved = selector.filterSlots(to) - .filter { it.hasStack() } - .sumOf { it.stack.count } >= selector.count - - if (selectedFrom.isEmpty() || moved) { - finish() } } } - private fun SafeContext.finish() { - if (closeScreen) player.closeHandledScreen() - success(Unit) - } - companion object { @Ta5kBuilder fun moveItems( From e5b48a5de3fd4cda836141d2dab2e8e892af93d6 Mon Sep 17 00:00:00 2001 From: Constructor Date: Tue, 24 Sep 2024 03:08:00 +0200 Subject: [PATCH 15/16] Iterative inventory transactions --- .../com/lambda/task/tasks/InventoryTask.kt | 36 ++++++++----------- .../com/lambda/util/player/SlotUtils.kt | 13 +++++++ 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt index 0ba6fb1ce..4beec1ecb 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt @@ -9,6 +9,7 @@ import com.lambda.task.Task import com.lambda.util.extension.containerSlots import com.lambda.util.extension.inventorySlots import com.lambda.util.item.ItemUtils.block +import com.lambda.util.player.SlotUtils import com.lambda.util.player.SlotUtils.clickSlot import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.Slot @@ -22,7 +23,17 @@ class InventoryTask( private val closeScreen: Boolean = true ) : Task() { private val selectedFrom get() = selector.filterSlots(from).filter { it.hasStack() } - private val selectedTo = to.filter { !it.hasStack() } + private val selectedTo = to.filter { it.stack.isEmpty } + to.filter { it.stack.item.block in TaskFlow.disposables } + private val transactions = mutableListOf() + + override fun SafeContext.onStart() { + selectedFrom.zip(selectedTo).forEach { (from, to) -> + transactions.add(SlotUtils.Transaction(to.id, 0, SlotActionType.SWAP)) + transactions.add(SlotUtils.Transaction(from.id, 0, SlotActionType.SWAP)) + + // ToDo: Handle overflow of cursor for PICKUP + } + } init { // ToDo: Needs smart code to move as efficient as possible. @@ -32,31 +43,12 @@ class InventoryTask( .filter { it.hasStack() } .sumOf { it.stack.count } >= selector.count - if (selectedFrom.isEmpty() || moved) { + if (transactions.isEmpty() || moved) { if (closeScreen) player.closeHandledScreen() success(Unit) } - selector.filterSlots(from).firstOrNull { it.hasStack() }?.let { from -> -// player.currentScreenHandler -// .inventorySlots -// .firstOrNull { -// it.stack.item.block in TaskFlow.disposables || it.stack.isEmpty -// }?.let { to -> -// clickSlot(from.id, 0, SlotActionType.PICKUP) -// clickSlot(to.id, 0, SlotActionType.PICKUP) -// // ToDo: Handle overflow of cursor -// } - - player.currentScreenHandler - .inventorySlots - .firstOrNull { - it.stack.item.block in TaskFlow.disposables || it.stack.isEmpty - }?.let { emptySlot -> - clickSlot(emptySlot.id, 0, SlotActionType.SWAP) - clickSlot(from.id, 0, SlotActionType.SWAP) - } - } + transactions.removeFirst().click() } } diff --git a/common/src/main/kotlin/com/lambda/util/player/SlotUtils.kt b/common/src/main/kotlin/com/lambda/util/player/SlotUtils.kt index ce1a94dd7..c1cc9d4e9 100644 --- a/common/src/main/kotlin/com/lambda/util/player/SlotUtils.kt +++ b/common/src/main/kotlin/com/lambda/util/player/SlotUtils.kt @@ -1,6 +1,7 @@ package com.lambda.util.player import com.lambda.context.SafeContext +import com.lambda.threading.runSafe import net.minecraft.client.network.ClientPlayerEntity import net.minecraft.item.ItemStack import net.minecraft.screen.slot.SlotActionType @@ -27,4 +28,16 @@ object SlotUtils { player, ) } + + data class Transaction( + val slotId: Int, + val button: Int, + val actionType: SlotActionType, + ) { + fun click() { + runSafe { + clickSlot(slotId, button, actionType) + } + } + } } \ No newline at end of file From d2f09067e3ca1cec1980e9249d99ae9515978bb1 Mon Sep 17 00:00:00 2001 From: Constructor Date: Tue, 24 Sep 2024 04:15:53 +0200 Subject: [PATCH 16/16] No rotation on insta break --- .../src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt | 9 ++++----- .../main/kotlin/com/lambda/task/tasks/InventoryTask.kt | 1 - .../src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt | 3 ++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt index 205ef6e3f..43cf19c17 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/BreakBlock.kt @@ -42,7 +42,6 @@ class BreakBlock @Ta5kBuilder constructor( private var drop: ItemEntity? = null private var state = State.BREAKING private var isValid = false - private var inScope = 0 enum class State { BREAKING, COLLECTING @@ -55,7 +54,7 @@ class BreakBlock @Ta5kBuilder constructor( } beginState = blockState - if (!rotate) { + if (!rotate || ctx.instantBreak) { breakBlock(ctx.result.side) } } @@ -63,13 +62,13 @@ class BreakBlock @Ta5kBuilder constructor( init { listener { event -> if (state != State.BREAKING) return@listener - if (!rotate) return@listener + if (!rotate || ctx.instantBreak) return@listener event.context = lookAtBlock(blockPos, rotation, interact, sides) } listener { if (state != State.BREAKING) return@listener - if (!rotate) return@listener + if (!rotate || ctx.instantBreak) return@listener isValid = it.context.isValid } @@ -92,7 +91,7 @@ class BreakBlock @Ta5kBuilder constructor( BaritoneUtils.setGoalAndPath(GoalBlock(itemDrop.blockPos)) } ?: BaritoneUtils.cancel() - if (isValid || !rotate) { + if (isValid || !rotate || ctx.instantBreak) { breakBlock(ctx.result.side) } diff --git a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt index 4beec1ecb..bcd6c459f 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/InventoryTask.kt @@ -10,7 +10,6 @@ import com.lambda.util.extension.containerSlots import com.lambda.util.extension.inventorySlots import com.lambda.util.item.ItemUtils.block import com.lambda.util.player.SlotUtils -import com.lambda.util.player.SlotUtils.clickSlot import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.Slot import net.minecraft.screen.slot.SlotActionType diff --git a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt index 1bc820a85..355f70e4b 100644 --- a/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt +++ b/common/src/main/kotlin/com/lambda/task/tasks/PlaceBlock.kt @@ -11,6 +11,7 @@ import com.lambda.interaction.construction.context.PlaceContext import com.lambda.module.modules.client.TaskFlow import com.lambda.task.Task import com.lambda.util.BlockUtils.blockState +import com.lambda.util.Communication.warn import net.minecraft.block.BlockState class PlaceBlock @Ta5kBuilder constructor( @@ -98,7 +99,7 @@ class PlaceBlock @Ta5kBuilder constructor( if (!waitForConfirmation) finish() } } else { - failure("Internal interaction failed with $actionResult") + warn("Internal interaction failed with $actionResult") } }