From 788bcc91ed65c454a312c712cb75cddb34f22ce3 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Mon, 6 Jul 2026 11:25:41 +0100 Subject: [PATCH 01/18] rename material directory to inventory and rename MaterialContainer to Container --- .../command/commands/TransferCommand.kt | 2 +- .../com/lambda/config/blocks/EatConfig.kt | 2 +- .../lambda/config/blocks/InventoryConfig.kt | 24 +++++------ .../com/lambda/event/events/ContainerEvent.kt | 6 +-- .../simulation/checks/BreakSim.kt | 12 +++--- .../simulation/checks/InteractSim.kt | 10 ++--- .../simulation/context/BreakContext.kt | 2 +- .../simulation/result/results/BreakResult.kt | 4 +- .../result/results/GenericResult.kt | 4 +- .../interaction/handlers/ContainerHandler.kt | 34 ++++++++-------- .../interaction/handlers/GlideHandler.kt | 2 +- .../ContainerSelection.kt | 27 ++++++------- .../{material => inventory}/StackSelection.kt | 4 +- .../container/Container.kt} | 31 ++++++-------- .../container/ExternalContainer.kt | 2 +- .../container/containers/ArmorContainer.kt | 40 +++++++++++++++++++ .../container/containers/ChestContainer.kt | 8 ++-- .../container/containers/CreativeContainer.kt | 8 ++-- .../containers/EnderChestContainer.kt | 10 ++--- .../container/containers/HotbarContainer.kt | 6 +-- .../containers/InventoryContainer.kt | 6 +-- .../container/containers/MainHandContainer.kt | 6 +-- .../container/containers/OffHandContainer.kt | 6 +-- .../container/containers/PlayerContainer.kt | 40 +++++++++++++++++++ .../containers/ShulkerBoxContainer.kt | 10 ++--- .../container/containers/StashContainer.kt | 8 ++-- .../managers/breaking/BreakManager.kt | 4 +- .../lambda/module/modules/combat/AutoTotem.kt | 2 +- .../module/modules/combat/CrystalAura.kt | 6 +-- .../lambda/module/modules/combat/KillAura.kt | 2 +- .../module/modules/debug/ContainerTest.kt | 2 +- .../module/modules/movement/BetterFirework.kt | 4 +- .../elytrafly/modes/GrimControlElytraFly.kt | 2 +- .../lambda/module/modules/player/ToolSaver.kt | 2 +- .../module/modules/render/ContainerPreview.kt | 2 +- .../lambda/module/modules/world/AutoPortal.kt | 2 +- .../lambda/module/modules/world/Scaffold.kt | 4 +- .../lambda/module/modules/world/StashMover.kt | 2 +- .../lambda/task/tasks/AcquireMaterialTask.kt | 4 +- .../task/tasks/ContainerTransferTask.kt | 12 +++--- .../kotlin/com/lambda/task/tasks/EatTask.kt | 4 +- .../com/lambda/util/player/SlotUtils.kt | 32 +++++++++------ 42 files changed, 241 insertions(+), 159 deletions(-) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/ContainerSelection.kt (70%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/StackSelection.kt (99%) rename src/main/kotlin/com/lambda/interaction/{material/container/MaterialContainer.kt => inventory/container/Container.kt} (88%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/ExternalContainer.kt (94%) create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/ChestContainer.kt (90%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/CreativeContainer.kt (91%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/EnderChestContainer.kt (86%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/HotbarContainer.kt (89%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/InventoryContainer.kt (87%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/MainHandContainer.kt (89%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/OffHandContainer.kt (89%) create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/ShulkerBoxContainer.kt (90%) rename src/main/kotlin/com/lambda/interaction/{material => inventory}/container/containers/StashContainer.kt (88%) diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index e37d1bdfc..b3c99c2e7 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -28,7 +28,7 @@ import com.lambda.brigadier.executeWithResult import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial import com.lambda.interaction.handlers.ContainerHandler.findContainersWithSpace diff --git a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt index 1e0e5714b..0900a1e0f 100644 --- a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt @@ -19,7 +19,7 @@ package com.lambda.config.blocks import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.threading.runSafe import com.lambda.util.Describable import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 6a0c26116..c60f8b4b8 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -19,9 +19,9 @@ package com.lambda.config.blocks import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent -import com.lambda.interaction.material.ContainerSelection -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.ContainerSelection +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.container.Container import com.lambda.util.Describable import com.lambda.util.NamedEnum import net.minecraft.item.Item @@ -41,11 +41,11 @@ interface InventoryConfig { val containerSelection: ContainerSelection get() = ContainerSelection.selectContainer { val allowedContainers = buildSet { - addAll(MaterialContainer.Rank.entries) - if (!accessShulkerBoxes) remove(MaterialContainer.Rank.ShulkerBox) - if (!accessEnderChest) remove(MaterialContainer.Rank.EnderChest) - if (!accessChests) remove(MaterialContainer.Rank.Chest) - if (!accessStashes) remove(MaterialContainer.Rank.Stash) + addAll(Container.Rank.entries) + if (!accessShulkerBoxes) remove(Container.Rank.ShulkerBox) + if (!accessEnderChest) remove(Container.Rank.EnderChest) + if (!accessChests) remove(Container.Rank.Chest) + if (!accessStashes) remove(Container.Rank.Stash) } ofAnyType(*allowedContainers.toTypedArray()) } @@ -60,11 +60,11 @@ interface InventoryConfig { context(_: SafeContext) fun materialComparator(selection: StackSelection) = when (this) { - WithMaxItems -> compareBy { it.rank } + WithMaxItems -> compareBy { it.rank } .thenByDescending { it.materialAvailable(selection) } .thenBy { it.name } - WithMinItems -> compareBy { it.rank } + WithMinItems -> compareBy { it.rank } .thenBy { it.materialAvailable(selection) } .thenBy { it.name } } @@ -72,11 +72,11 @@ interface InventoryConfig { context(_: SafeContext) fun spaceComparator(selection: StackSelection) = when (this) { - WithMaxItems -> compareBy { it.rank } + WithMaxItems -> compareBy { it.rank } .thenByDescending { it.spaceAvailable(selection) } .thenBy { it.name } - WithMinItems -> compareBy { it.rank } + WithMinItems -> compareBy { it.rank } .thenBy { it.spaceAvailable(selection) } .thenBy { it.name } } diff --git a/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt b/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt index 2c0031cb1..f586dd52a 100644 --- a/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt +++ b/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt @@ -19,14 +19,14 @@ package com.lambda.event.events import com.lambda.event.callback.Cancellable import com.lambda.event.callback.ICancellable -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.Container import net.minecraft.screen.slot.Slot sealed class ContainerEvent { data class Transfer( val fromSlot: Slot, val toSlot: Slot, - val from: MaterialContainer, - val to: MaterialContainer + val from: Container, + val to: Container ) : ICancellable by Cancellable() } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt index a9fd15e65..afe212b7f 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt @@ -31,12 +31,12 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.managers.hotbar.HotbarManager import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.material.ContainerSelection.Companion.selectContainer -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.StackSelection.Companion.EVERYTHING -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.ContainerSelection.Companion.selectContainer +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.StackSelection.Companion.EVERYTHING +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta import com.lambda.util.BlockUtils.instantBreakable @@ -168,7 +168,7 @@ class BreakSim private constructor(simInfo: SimInfo) } val silentSwapSelection = selectContainer { - ofAnyType(MaterialContainer.Rank.Hotbar) + ofAnyType(Container.Rank.Hotbar) } val hotbarCandidates = stackSelection diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt index 3aa534c83..f7372a0be 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt @@ -32,10 +32,10 @@ import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotat import com.lambda.interaction.managers.rotating.Rotation import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.material.ContainerSelection.Companion.selectContainer -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.StackSelection.Companion.select -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.ContainerSelection.Companion.selectContainer +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.StackSelection.Companion.select +import com.lambda.interaction.inventory.container.Container import com.lambda.util.BlockUtils.blockState import com.lambda.util.EntityUtils.getPositionsWithinHitboxXZ import com.lambda.util.PlaceDirection @@ -213,7 +213,7 @@ class InteractSim private constructor(simInfo: InteractSimInfo) } val stackSelection = item?.select()?.apply { if (item == Items.AIR) count = 0 } ?: StackSelection.selectStack(0, sorter = compareByDescending { it.inventoryIndex == player.inventory.selectedSlot }) - val containerSelection = selectContainer { ofAnyType(MaterialContainer.Rank.Hotbar) } + val containerSelection = selectContainer { ofAnyType(Container.Rank.Hotbar) } val container = stackSelection.findContainersWithMaterial(containerSelection).firstOrNull() ?: run { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt index 2222f6791..67ec97b81 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.construction.simulation.context import com.lambda.context.Automated import com.lambda.graphics.mc.RenderBuilder import com.lambda.interaction.managers.rotating.RotationRequest -import com.lambda.interaction.material.StackSelection +import com.lambda.interaction.inventory.StackSelection import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.emptyState import net.minecraft.block.BlockState diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 0de9e0844..6837ab8ea 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -32,9 +32,9 @@ import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.interaction.handlers.ContainerHandler.transferByTask -import com.lambda.interaction.material.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import net.minecraft.block.BlockState import net.minecraft.item.Item diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index eeabf4945..a9b550507 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -27,9 +27,9 @@ import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable -import com.lambda.interaction.material.StackSelection +import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.handlers.ContainerHandler.transferByTask -import com.lambda.interaction.material.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import net.minecraft.client.data.TextureMap.side import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt index e7a083287..733931f37 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt @@ -23,12 +23,12 @@ import com.lambda.core.Loadable import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.material.ContainerSelection -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.StackSelection.Companion.select -import com.lambda.interaction.material.container.MaterialContainer -import com.lambda.interaction.material.container.containers.ChestContainer -import com.lambda.interaction.material.container.containers.EnderChestContainer +import com.lambda.interaction.inventory.ContainerSelection +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.StackSelection.Companion.select +import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.containers.ChestContainer +import com.lambda.interaction.inventory.container.containers.EnderChestContainer import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.ReflectionUtils import com.lambda.util.extension.containerStacks @@ -42,11 +42,11 @@ import net.minecraft.screen.slot.Slot // ToDo: Make this a Configurable to save container caches. Should use a cached region based storage system. @Suppress("unused") object ContainerHandler : Loadable { - private val containers: List + private val containers: List get() = compileContainers + runtimeContainers - private val compileContainers = ReflectionUtils.getInstances() - private val runtimeContainers = mutableSetOf() + private val compileContainers = ReflectionUtils.getInstances() + private val runtimeContainers = mutableSetOf() var lastInteractedBlockEntity: BlockEntity? = null @@ -89,7 +89,7 @@ object ContainerHandler : Loadable { fun containers() = containers.flatMap { setOf(it) + it.shulkerContainer }.sorted() context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.transfer(destination: MaterialContainer) = + fun StackSelection.transfer(destination: Container) = with(automatedSafeContext) { findContainerWithMaterial( inventoryConfig.containerSelection @@ -98,25 +98,25 @@ object ContainerHandler : Loadable { } context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.transferByTask(destination: MaterialContainer) = + fun StackSelection.transferByTask(destination: Container) = with(automatedSafeContext) { findContainerWithMaterial()?.transferByTask(this@transferByTask, destination) } context(_: SafeContext) fun findContainer( - block: (MaterialContainer) -> Boolean, - ): MaterialContainer? = containers().find(block) + block: (Container) -> Boolean, + ): Container? = containers().find(block) context(automatedSafeContext: AutomatedSafeContext) fun StackSelection.findContainerWithMaterial( containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ): MaterialContainer? = findContainersWithMaterial(containerSelection).firstOrNull() + ): Container? = findContainersWithMaterial(containerSelection).firstOrNull() context(automatedSafeContext: AutomatedSafeContext) fun StackSelection.findContainersWithMaterial( containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection, - ): List = + ): List = containers() .filter { containerSelection.matches(it) } .filter { it.materialAvailable(this) >= count } @@ -125,12 +125,12 @@ object ContainerHandler : Loadable { context(automatedSafeContext: AutomatedSafeContext) fun StackSelection.findContainerWithSpace( containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ): MaterialContainer? = findContainersWithSpace(containerSelection).firstOrNull() + ): Container? = findContainersWithSpace(containerSelection).firstOrNull() context(automatedSafeContext: AutomatedSafeContext) fun StackSelection.findContainersWithSpace( containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ): List = + ): List = containers() .filter { containerSelection.matches(it) } .filter { it.spaceAvailable(this) >= count } diff --git a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt index c519e2774..8f3df5c02 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.handlers import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.modules.movement.elytrafly.ElytraFly import com.lambda.module.modules.movement.elytrafly.ElytraFly.mode diff --git a/src/main/kotlin/com/lambda/interaction/material/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt similarity index 70% rename from src/main/kotlin/com/lambda/interaction/material/ContainerSelection.kt rename to src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt index fca5a4d20..5d0948fb0 100644 --- a/src/main/kotlin/com/lambda/interaction/material/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt @@ -15,23 +15,23 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material +package com.lambda.interaction.inventory import com.lambda.context.SafeContext -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.Container /** * ContainerSelection is a class that holds a predicate for matching MaterialContainers. * It can be combined using "and", "or", etc. */ class ContainerSelection { - private var selector: (MaterialContainer) -> Boolean = { true } + private var selector: (Container) -> Boolean = { true } /** * Tests whether the provided container matches this selection. */ @ContainerSelectionDsl - fun matches(container: MaterialContainer): Boolean = selector(container) + fun matches(container: Container): Boolean = selector(container) /** * Returns a function that matches containers having at least one stack @@ -39,7 +39,7 @@ class ContainerSelection { */ @ContainerSelectionDsl context(_: SafeContext) - fun matches(stackSelection: StackSelection): (MaterialContainer) -> Boolean = + fun matches(stackSelection: StackSelection): (Container) -> Boolean = { container -> container.matchingSlots(stackSelection).isNotEmpty() } /** @@ -47,42 +47,42 @@ class ContainerSelection { * defined in the provided ContainerSelection. */ @ContainerSelectionDsl - fun matches(containerSelection: ContainerSelection): (MaterialContainer) -> Boolean = + fun matches(containerSelection: ContainerSelection): (Container) -> Boolean = { container -> containerSelection.matches(container) } /** * Returns a function that matches containers whose rank is any of the types provided. */ @ContainerSelectionDsl - fun ofAnyType(vararg types: MaterialContainer.Rank): (MaterialContainer) -> Boolean = + fun ofAnyType(vararg types: Container.Rank): (Container) -> Boolean = { container -> types.contains(container.rank) } /** * Returns a function that matches containers whose rank is not any of the types provided. */ @ContainerSelectionDsl - fun noneOfType(vararg types: MaterialContainer.Rank): (MaterialContainer) -> Boolean = + fun noneOfType(vararg types: Container.Rank): (Container) -> Boolean = { container -> !types.contains(container.rank) } /** * Returns a function that combines two container predicates using logical AND. */ @ContainerSelectionDsl - infix fun ((MaterialContainer) -> Boolean).and(other: (MaterialContainer) -> Boolean): (MaterialContainer) -> Boolean = + infix fun ((Container) -> Boolean).and(other: (Container) -> Boolean): (Container) -> Boolean = { container -> this(container) && other(container) } /** * Returns a function that combines two container predicates using logical OR. */ @ContainerSelectionDsl - infix fun ((MaterialContainer) -> Boolean).or(other: (MaterialContainer) -> Boolean): (MaterialContainer) -> Boolean = + infix fun ((Container) -> Boolean).or(other: (Container) -> Boolean): (Container) -> Boolean = { container -> this(container) || other(container) } /** * Returns a function that negates the current selection predicate. */ @ContainerSelectionDsl - fun ((MaterialContainer) -> Boolean).negate(): (MaterialContainer) -> Boolean = + fun ((Container) -> Boolean).negate(): (Container) -> Boolean = { container -> !this(container) } companion object { @@ -91,8 +91,7 @@ class ContainerSelection { @ContainerSelectionDsl fun selectContainer( - block: ContainerSelection.() -> (MaterialContainer) -> Boolean - ): ContainerSelection = - ContainerSelection().apply { selector = block() } + block: ContainerSelection.() -> (Container) -> Boolean + ): ContainerSelection = ContainerSelection().apply { selector = block() } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/material/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt similarity index 99% rename from src/main/kotlin/com/lambda/interaction/material/StackSelection.kt rename to src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index 96a8b96ad..daa5231cb 100644 --- a/src/main/kotlin/com/lambda/interaction/material/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -15,9 +15,9 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material +package com.lambda.interaction.inventory -import com.lambda.interaction.material.StackSelection.Companion.StackSelectionDsl +import com.lambda.interaction.inventory.StackSelection.Companion.StackSelectionDsl import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemStackUtils.shulkerBoxContents import com.lambda.util.item.ItemUtils diff --git a/src/main/kotlin/com/lambda/interaction/material/container/MaterialContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt similarity index 88% rename from src/main/kotlin/com/lambda/interaction/material/container/MaterialContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 895bdcbdb..9e514a27d 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/MaterialContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container +package com.lambda.interaction.inventory.container import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext @@ -24,9 +24,8 @@ import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.container.containers.ShulkerBoxContainer -import com.lambda.task.Task +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.container.containers.ShulkerBoxContainer import com.lambda.task.tasks.ContainerTransferTask import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count @@ -47,9 +46,9 @@ import net.minecraft.screen.slot.Slot import net.minecraft.text.Text // ToDo: Make jsonable to persistently store them -abstract class MaterialContainer( +abstract class Container( val rank: Rank -) : Nameable, Comparable { +) : Nameable, Comparable { context(_: SafeContext) abstract val slots: List abstract var stacks: List @@ -106,7 +105,7 @@ abstract class MaterialContainer( }.map { slot -> ShulkerBoxContainer( slot.stack.shulkerBoxContents, - containedIn = this@MaterialContainer, + containedIn = this@Container, shulkerSlot = slot ) }.toSet() @@ -115,12 +114,6 @@ abstract class MaterialContainer( this.stacks = slots } - class FailureTask(override val name: String) : Task() { - override fun SafeContext.onStart() { - failure(name) - } - } - context(_: SafeContext) open fun InventoryRequest.InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { if (fromHere.stack.isEmpty) pickupAndPlace(toSlot.id, fromHere.id) @@ -131,11 +124,11 @@ abstract class MaterialContainer( } context(automatedSafeContext: AutomatedSafeContext) - fun transfer(stackSelection: StackSelection, destination: MaterialContainer): Boolean = + fun transfer(stackSelection: StackSelection, destination: Container): Boolean = with(automatedSafeContext) { val fromSlot = getSlot(stackSelection) ?: return false val toSlot = destination.getReplaceableSlot() ?: return false - val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@MaterialContainer, destination) + val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@Container, destination) if (transferEvent.post().isCanceled()) return false return inventoryRequest { if (swapMethodPriority > destination.swapMethodPriority) transfer(fromSlot, toSlot) @@ -144,7 +137,7 @@ abstract class MaterialContainer( } context(automatedSafeContext: AutomatedSafeContext) - fun transferByTask(stackSelection: StackSelection, destination: MaterialContainer, failIfNoMaterial: Boolean = false) = + fun transferByTask(stackSelection: StackSelection, destination: Container, failIfNoMaterial: Boolean = false) = ContainerTransferTask(this, destination, stackSelection, automatedSafeContext, failIfNoMaterial) protected fun InventoryRequest.InvRequestBuilder.pickupAndPlace(fromId: Int, toId: Int) { @@ -180,6 +173,8 @@ abstract class MaterialContainer( OffHand, Hotbar, Inventory, + Armor, + Player, Creative, ShulkerBox, EnderChest, @@ -187,8 +182,8 @@ abstract class MaterialContainer( Stash } - override fun compareTo(other: MaterialContainer) = - compareBy { + override fun compareTo(other: Container) = + compareBy { it.rank }.compare(this, other) } diff --git a/src/main/kotlin/com/lambda/interaction/material/container/ExternalContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt similarity index 94% rename from src/main/kotlin/com/lambda/interaction/material/container/ExternalContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt index 291cbbaa2..9d0bf3f14 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/ExternalContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container +package com.lambda.interaction.inventory.container import com.lambda.context.AutomatedSafeContext import com.lambda.task.Task diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt new file mode 100644 index 000000000..061298208 --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container.containers + +import com.lambda.Lambda.mc +import com.lambda.context.SafeContext +import com.lambda.interaction.inventory.container.Container +import com.lambda.util.player.SlotUtils.armorSlots +import com.lambda.util.player.SlotUtils.armorStacks +import com.lambda.util.text.buildText +import com.lambda.util.text.literal +import net.minecraft.item.ItemStack +import net.minecraft.screen.slot.Slot + +@Suppress("unused") +object ArmorContainer : Container(Rank.Armor) { + context(safeContext: SafeContext) + override val slots: List + get() = safeContext.player.armorSlots + override var stacks: List + get() = mc.player?.armorStacks ?: emptyList() + set(_) {} + + override val description = buildText { literal("Armor") } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt similarity index 90% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt index f5c2a670e..cbbf7c616 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt @@ -15,13 +15,13 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.interaction.handlers.ContainerHandler -import com.lambda.interaction.material.container.ExternalContainer -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.task.Task import com.lambda.task.TaskGenerator import com.lambda.task.tasks.OpenContainerTask @@ -38,7 +38,7 @@ data class ChestContainer( override var stacks: List, val blockPos: BlockPos, val containedInStash: StashContainer? = null -) : MaterialContainer(Rank.Chest), ExternalContainer { +) : Container(Rank.Chest), ExternalContainer { context(safeContext: SafeContext) override val slots get(): List = diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt similarity index 91% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/CreativeContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt index 5845263a1..3c00c1a6a 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt @@ -15,12 +15,12 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.context.SafeContext import com.lambda.interaction.managers.inventory.InventoryRequest -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.container.Container import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen @@ -30,7 +30,7 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.PlayerScreenHandler import net.minecraft.screen.slot.Slot -data object CreativeContainer : MaterialContainer(Rank.Creative) { +data object CreativeContainer : Container(Rank.Creative) { context(_: SafeContext) override val slots: List get() = emptyList() diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt similarity index 86% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt index a20fbfb83..a7b6993fa 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt @@ -15,15 +15,15 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext -import com.lambda.interaction.material.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial -import com.lambda.interaction.material.container.ExternalContainer -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.task.TaskGenerator import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainerTask @@ -35,7 +35,7 @@ import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.item.ItemStack import net.minecraft.item.Items -object EnderChestContainer : MaterialContainer(Rank.EnderChest), ExternalContainer { +object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { context(safeContext: SafeContext) override val slots get() = diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/HotbarContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt similarity index 89% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/HotbarContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt index f2dc5d3f4..1e62c37aa 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/HotbarContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt @@ -15,19 +15,19 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.managers.inventory.InventoryRequest -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.hotbarSlots import com.lambda.util.player.SlotUtils.hotbarStacks import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.screen.slot.Slot -object HotbarContainer : MaterialContainer(Rank.Hotbar) { +object HotbarContainer : Container(Rank.Hotbar) { context(safeContext: SafeContext) override val slots: List get() = safeContext.player.hotbarSlots diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/InventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt similarity index 87% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/InventoryContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt index 10867bdb2..7cc269548 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/InventoryContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt @@ -15,11 +15,11 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.inventorySlots import com.lambda.util.player.SlotUtils.inventoryStacks import com.lambda.util.text.buildText @@ -27,7 +27,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object InventoryContainer : MaterialContainer(Rank.Inventory) { +object InventoryContainer : Container(Rank.Inventory) { context(safeContext: SafeContext) override val slots: List get() = safeContext.player.inventorySlots diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt similarity index 89% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt index 88d936f34..018859489 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/MainHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt @@ -15,19 +15,19 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.managers.inventory.InventoryRequest -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.mainHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object MainHandContainer : MaterialContainer(Rank.MainHand) { +object MainHandContainer : Container(Rank.MainHand) { context(safeContext: SafeContext) override val slots: List get() = safeContext.player.mainHandSlots diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/OffHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt similarity index 89% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/OffHandContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt index 2ae235e42..f48df2fd4 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/OffHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt @@ -15,19 +15,19 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.managers.inventory.InventoryRequest -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.offHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object OffHandContainer : MaterialContainer(Rank.OffHand) { +object OffHandContainer : Container(Rank.OffHand) { context(safeContext: SafeContext) override val slots: List get() = safeContext.player.offHandSlots diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt new file mode 100644 index 000000000..1fbe889ec --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container.containers + +import com.lambda.Lambda.mc +import com.lambda.context.SafeContext +import com.lambda.interaction.inventory.container.Container +import com.lambda.util.player.SlotUtils.allSlots +import com.lambda.util.player.SlotUtils.allStacks +import com.lambda.util.text.buildText +import com.lambda.util.text.literal +import net.minecraft.item.ItemStack +import net.minecraft.screen.slot.Slot + +@Suppress("unused") +object PlayerContainer : Container(Rank.Player) { + context(safeContext: SafeContext) + override val slots: List + get() = safeContext.player.allSlots + override var stacks: List + get() = mc.player?.allStacks ?: emptyList() + set(_) {} + + override val description = buildText { literal("Player") } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt similarity index 90% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt index f0ade4bb5..5a644647b 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt @@ -15,13 +15,13 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.interaction.handlers.ContainerHandler -import com.lambda.interaction.material.container.ExternalContainer -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.container.Container import com.lambda.task.TaskGenerator import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainerTask @@ -38,9 +38,9 @@ import net.minecraft.util.math.BlockPos data class ShulkerBoxContainer( override var stacks: List, - val containedIn: MaterialContainer, + val containedIn: Container, val shulkerSlot: Slot, -) : MaterialContainer(Rank.ShulkerBox), ExternalContainer { +) : Container(Rank.ShulkerBox), ExternalContainer { context(safeContext: SafeContext) override val slots get(): List = diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/StashContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt similarity index 88% rename from src/main/kotlin/com/lambda/interaction/material/container/containers/StashContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt index e84b3ce4d..6c23b7d5b 100644 --- a/src/main/kotlin/com/lambda/interaction/material/container/containers/StashContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt @@ -15,11 +15,11 @@ * along with this program. If not, see . */ -package com.lambda.interaction.material.container.containers +package com.lambda.interaction.inventory.container.containers import com.lambda.context.SafeContext -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.container.MaterialContainer +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.container.Container import com.lambda.util.math.roundedBlockPos import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -31,7 +31,7 @@ import net.minecraft.util.math.Box data class StashContainer( val chests: Set, val pos: Box, -) : MaterialContainer(Rank.Stash) { +) : Container(Rank.Stash) { context(_: SafeContext) override val slots: List get() = chests.flatMap { it.slots } diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt index 79d8d30b2..551e48286 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt @@ -73,8 +73,8 @@ import com.lambda.interaction.managers.breaking.SwapInfo.Companion.getSwapInfo import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.interacting.InteractManager import com.lambda.interaction.managers.rotating.RotationRequest -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.threading.runGameScheduled import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index f2ac4ff80..76708df58 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -25,7 +25,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.FriendHandler import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.material.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.combat.CombatUtils.hasDeadlyCrystal diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 20cf1d653..2dfdd7150 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -31,10 +31,10 @@ import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.interaction.handlers.ContainerHandler.transfer -import com.lambda.interaction.material.container.containers.HotbarContainer -import com.lambda.interaction.material.container.containers.OffHandContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.OffHandContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index 29c598b01..dc3f79d4a 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -30,7 +30,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index fc9ceb73a..599e9dc87 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.material.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 316743d57..48bc00c39 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -31,8 +31,8 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.GlideHandler import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.material.StackSelection.Companion.select -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt index 95138afa0..d7620c087 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt @@ -25,7 +25,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.material.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.module.modules.movement.BetterFirework.startFirework import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFlyMode diff --git a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt index e4c528946..160b949c8 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt @@ -24,7 +24,7 @@ import com.lambda.event.events.ContainerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.material.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.EnchantmentUtils.forEachEnchantment diff --git a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt index d8c79f5d4..a5fa8c7f5 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt @@ -21,7 +21,7 @@ import com.lambda.Lambda.mc import com.lambda.config.Tab import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.config.settings.complex.Bind -import com.lambda.interaction.material.container.containers.EnderChestContainer +import com.lambda.interaction.inventory.container.containers.EnderChestContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 4cf4a1432..2d541772f 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -38,7 +38,7 @@ import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.material.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.module.Module import com.lambda.module.modules.world.AutoPortal.PosHandler.currAnchorPos import com.lambda.module.modules.world.AutoPortal.PosHandler.obiPositions diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index f14d5d125..32a761990 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -32,8 +32,8 @@ import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.managers.interacting.InteractRequest.Companion.interactRequest -import com.lambda.interaction.material.StackSelection.Companion.selectStack -import com.lambda.interaction.material.container.containers.HotbarContainer +import com.lambda.interaction.inventory.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index e7c2b2307..5ae411744 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -47,7 +47,7 @@ import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotat import com.lambda.interaction.managers.rotating.Rotation import com.lambda.interaction.managers.rotating.Rotation.Companion.dist import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.material.container.containers.EnderChestContainer +import com.lambda.interaction.inventory.container.containers.EnderChestContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt index d3a8eeab4..72aec175b 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt @@ -19,10 +19,10 @@ package com.lambda.task.tasks import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.material.StackSelection +import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.handlers.ContainerHandler.findContainerWithMaterial -import com.lambda.interaction.material.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index 4d92b7202..ee24da55f 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -23,16 +23,16 @@ import com.lambda.event.events.ContainerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.material.StackSelection -import com.lambda.interaction.material.container.ExternalContainer -import com.lambda.interaction.material.container.MaterialContainer -import com.lambda.interaction.material.container.containers.InventoryContainer +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.task.Task import com.lambda.threading.runSafeAutomated class ContainerTransferTask( - private var fromContainer: MaterialContainer, - private val toContainer: MaterialContainer, + private var fromContainer: Container, + private val toContainer: Container, private val stackSelection: StackSelection, automated: Automated, private val failIfNoMaterial: Boolean = false diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index e67320e33..99c636fae 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -24,8 +24,8 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.managers.hotbar.HotbarRequest -import com.lambda.interaction.material.container.containers.HotbarContainer -import com.lambda.interaction.material.container.containers.InventoryContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.task.Task import com.lambda.threading.runSafeAutomated import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt index d09c0ae32..81e89d0c2 100644 --- a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt +++ b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt @@ -29,22 +29,30 @@ import net.minecraft.screen.slot.SlotActionType object SlotUtils { val ClientPlayerEntity.allSlots get() = currentScreenHandler.slots.filter { it.inventory is PlayerInventory } val ClientPlayerEntity.armorSlots get() = allSlots.filterIsInstance() - val ClientPlayerEntity.inventorySlots: List get() = - if (currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler) emptyList() - else if (currentScreenHandler === playerScreenHandler) allSlots.subList(4, 31) - else allSlots.subList(0, 27) - val ClientPlayerEntity.hotbarSlots: List get() = - if (currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler) allSlots - else if (currentScreenHandler === playerScreenHandler) allSlots.subList(31, 40) - else allSlots.subList(27, 36) - val ClientPlayerEntity.hotbarAndInventorySlots: List get() = - if (currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler) allSlots - else if (currentScreenHandler === playerScreenHandler) allSlots.subList(4, 40) - else allSlots.subList(0, 36) + + val ClientPlayerEntity.inventorySlots: List + get() = + if (currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler) emptyList() + else if (currentScreenHandler === playerScreenHandler) allSlots.subList(4, 31) + else allSlots.subList(0, 27) + + val ClientPlayerEntity.hotbarSlots: List + get() = + if (currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler) allSlots + else if (currentScreenHandler === playerScreenHandler) allSlots.subList(31, 40) + else allSlots.subList(27, 36) + + val ClientPlayerEntity.hotbarAndInventorySlots: List + get() = + if (currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler) allSlots + else if (currentScreenHandler === playerScreenHandler) allSlots.subList(4, 40) + else allSlots.subList(0, 36) + val ClientPlayerEntity.mainHandSlots: List get() = listOf(hotbarSlots[inventory.selectedSlot]) val ClientPlayerEntity.offHandSlots: List get() = if (currentScreenHandler === playerScreenHandler) listOf(allSlots.last()) else emptyList() val ClientPlayerEntity.allStacks: List get() = hotbarAndInventoryStacks + equipmentStacks + val ClientPlayerEntity.armorStacks: List get() = inventory.equipment.map.filter { it.key.index in 1..4 }.map { it.value } val ClientPlayerEntity.equipmentStacks: List get() = inventory.equipment.map.map { it.value } val ClientPlayerEntity.hotbarStacks: List get() = inventory.mainStacks.slice(0..8) val ClientPlayerEntity.inventoryStacks: List get() = inventory.mainStacks.slice(9..35) From b961cf2a422c2bdd910de7c119e331aa733dc802 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Thu, 9 Jul 2026 00:24:12 +0100 Subject: [PATCH 02/18] rework StackSelection. Uses builder dsl and the final product is immutable. --- .../command/commands/TransferCommand.kt | 2 +- .../com/lambda/config/blocks/EatConfig.kt | 28 +- src/main/kotlin/com/lambda/gui/MenuBar.kt | 2 +- .../simulation/checks/BreakSim.kt | 44 +- .../simulation/checks/InteractSim.kt | 15 +- .../simulation/context/BreakContext.kt | 2 +- .../simulation/result/results/BreakResult.kt | 6 +- .../result/results/GenericResult.kt | 4 +- .../result/results/InteractResult.kt | 2 +- .../simulation/result/results/PreSimResult.kt | 2 +- .../interaction/handlers/ContainerHandler.kt | 2 +- .../interaction/handlers/FriendHandler.kt | 2 +- .../interaction/handlers/GlideHandler.kt | 66 +-- .../handlers/breaking/BrokenBlockHandler.kt | 4 +- .../handlers/breaking/RebreakHandler.kt | 6 +- .../interaction/inventory/StackSelection.kt | 493 ++++++++---------- .../inventory/container/Container.kt | 11 +- .../container/containers/ArmorContainer.kt | 1 - .../container/containers/ChestContainer.kt | 2 +- .../container/containers/CreativeContainer.kt | 2 +- .../containers/EnderChestContainer.kt | 4 +- .../containers/HotbarAndInventoryContainer.kt | 39 ++ .../container/containers/HotbarContainer.kt | 2 +- .../container/containers/MainHandContainer.kt | 2 +- .../container/containers/OffHandContainer.kt | 2 +- .../containers/ShulkerBoxContainer.kt | 2 +- .../managers/breaking/BreakManager.kt | 23 +- .../managers/breaking/BreakRequest.kt | 138 ++--- .../managers/interacting/InteractManager.kt | 10 +- .../managers/interacting/InteractRequest.kt | 63 ++- .../managers/rotating/RotationRequest.kt | 101 ++-- .../kotlin/com/lambda/module/hud/Baritone.kt | 2 +- .../lambda/module/modules/combat/AutoArmor.kt | 14 +- .../lambda/module/modules/combat/AutoTotem.kt | 2 +- .../module/modules/combat/CrystalAura.kt | 17 +- .../lambda/module/modules/combat/KillAura.kt | 23 +- .../module/modules/combat/PlayerTrap.kt | 6 +- .../lambda/module/modules/combat/Surround.kt | 4 +- .../combat/autodisconnect/AutoDisconnect.kt | 5 +- .../module/modules/debug/ContainerTest.kt | 2 +- .../module/modules/debug/RotationTest.kt | 2 +- .../module/modules/movement/AutoSpiral.kt | 2 +- .../module/modules/movement/BetterFirework.kt | 22 +- .../modules/movement/ElytraAltitudeControl.kt | 2 +- .../lambda/module/modules/movement/Speed.kt | 2 +- .../movement/elytrafly/ElytraFlyMode.kt | 8 +- .../elytrafly/modes/BounceElytraFly.kt | 2 +- .../elytrafly/modes/GrimControlElytraFly.kt | 13 +- .../lambda/module/modules/player/AntiAim.kt | 2 +- .../module/modules/player/AutoElytraSwap.kt | 8 +- .../lambda/module/modules/player/FastBreak.kt | 2 +- .../module/modules/player/InventoryMove.kt | 2 +- .../module/modules/player/PacketMine.kt | 2 +- .../lambda/module/modules/player/Replay.kt | 4 +- .../module/modules/player/RotationLock.kt | 2 +- .../module/modules/player/StackReplenish.kt | 8 +- .../lambda/module/modules/player/ToolSaver.kt | 9 +- .../module/modules/render/ContainerPreview.kt | 8 +- .../lambda/module/modules/render/Freecam.kt | 2 +- .../lambda/module/modules/render/Nametags.kt | 2 +- .../lambda/module/modules/render/Tracers.kt | 2 +- .../lambda/module/modules/world/AirPlace.kt | 2 +- .../lambda/module/modules/world/AutoPortal.kt | 14 +- .../module/modules/world/AutoVillagerCycle.kt | 2 +- .../module/modules/world/HighwayTools.kt | 2 +- .../module/modules/world/MapDownloader.kt | 4 +- .../lambda/module/modules/world/Scaffold.kt | 8 +- .../lambda/module/modules/world/StashMover.kt | 46 +- .../lambda/task/tasks/AcquireMaterialTask.kt | 2 +- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 10 +- .../task/tasks/ContainerTransferTask.kt | 4 +- .../kotlin/com/lambda/task/tasks/EatTask.kt | 2 +- .../lambda/task/tasks/OpenContainerTask.kt | 2 +- .../com/lambda/util/item/ItemStackUtils.kt | 4 +- .../kotlin/com/lambda/util/item/ItemUtils.kt | 4 +- 75 files changed, 681 insertions(+), 688 deletions(-) create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index b3c99c2e7..6027680c4 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -28,10 +28,10 @@ import com.lambda.brigadier.executeWithResult import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial import com.lambda.interaction.handlers.ContainerHandler.findContainersWithSpace +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.task.RootTask import com.lambda.task.Task import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt index 0900a1e0f..10af94609 100644 --- a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt @@ -19,7 +19,8 @@ package com.lambda.config.blocks import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackAndSlot +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.threading.runSafe import com.lambda.util.Describable import com.lambda.util.NamedEnum @@ -55,17 +56,17 @@ interface EatConfig { @Suppress("unused") enum class SelectionPriority( - val comparator: Comparator, + val comparator: Comparator>, override val displayName: String, override val description: String ): NamedEnum, Describable { LeastNutritious( - compareBy { it.item.nutrition }, + compareBy { it.stack.item.nutrition }, "Least Nutritious", "Eats food items with the least nutritional value." ), MostNutritious( - compareByDescending { it.item.nutrition }, + compareByDescending { it.stack.item.nutrition }, "Most Nutritious", "Eats food items with the most nutritional value." ) @@ -94,14 +95,17 @@ interface EatConfig { } ?: false context(c: Automated) - fun selector() = selectStack(sorter = c.eatConfig.selectionPriority.comparator) { - when(this@Reason) { - None -> any() - Hunger -> isOneOfItems(c.eatConfig.nutritiousFood) - Damage -> isOneOfItems(c.eatConfig.regenerationFood) - Fire -> isOneOfItems(c.eatConfig.resistanceFood) - } and if (c.eatConfig.ignoreBadFood) isNoneOfItems(c.eatConfig.badFood) else any() - } + fun selector() = + selectStack { + when(this@Reason) { + Hunger -> isOneOfItems(c.eatConfig.nutritiousFood) + Damage -> isOneOfItems(c.eatConfig.regenerationFood) + Fire -> isOneOfItems(c.eatConfig.resistanceFood) + else -> {} + } + if (c.eatConfig.ignoreBadFood) isNoneOfItems(c.eatConfig.badFood) + sortedWith(c.eatConfig.selectionPriority.comparator) + } } companion object { diff --git a/src/main/kotlin/com/lambda/gui/MenuBar.kt b/src/main/kotlin/com/lambda/gui/MenuBar.kt index 4dc97c8d1..2b205382b 100644 --- a/src/main/kotlin/com/lambda/gui/MenuBar.kt +++ b/src/main/kotlin/com/lambda/gui/MenuBar.kt @@ -39,8 +39,8 @@ import com.lambda.imgui.ImGui import com.lambda.imgui.ImGui.closeCurrentPopup import com.lambda.imgui.flag.ImGuiCol import com.lambda.imgui.flag.ImGuiStyleVar -import com.lambda.imgui.type.ImBoolean import com.lambda.imgui.flag.ImGuiWindowFlags +import com.lambda.imgui.type.ImBoolean import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.module.ModuleRegistry import com.lambda.module.ModuleRegistry.moduleNameMap diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt index afe212b7f..ffea00e15 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt @@ -28,15 +28,15 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.hotbar.HotbarManager -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial import com.lambda.interaction.inventory.ContainerSelection.Companion.selectContainer +import com.lambda.interaction.inventory.StackAndSlot import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.StackSelection.Companion.EVERYTHING -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack -import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.managers.hotbar.HotbarManager +import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta import com.lambda.util.BlockUtils.instantBreakable @@ -145,26 +145,20 @@ class BreakSim private constructor(simInfo: SimInfo) private fun AutomatedSafeContext.getSwapStack(): Pair? { // Stack size 0 to account for attacking with an empty hand. Empty slots have stack size 0 - val stackSelection = selectStack( - count = 0, - sorter = compareByDescending { - it.canBreak(CachedBlockPosition(world, pos, false)) - }.thenByDescending { - state.calcItemBlockBreakingDelta(pos, it) - }.thenByDescending { - it.inventoryIndex == HotbarManager.serverSlot - } - ) { - EVERYTHING - .andIf(breakConfig.efficientOnly) { - isEfficientForBreaking(state) - }.andIf(breakConfig.suitableToolsOnly) { - isSuitableForBreaking(state) - }.andIf(breakConfig.forceSilkTouch) { - hasEnchantment(Enchantments.SILK_TOUCH) - }.andIf(breakConfig.forceFortunePickaxe) { - hasEnchantment(Enchantments.FORTUNE) + val stackSelection = selectStack { + if (breakConfig.efficientOnly) isEfficientForBreaking(state) + if(breakConfig.suitableToolsOnly) isSuitableForBreaking(state) + if (breakConfig.forceSilkTouch) hasEnchantment(Enchantments.SILK_TOUCH) + if (breakConfig.forceFortunePickaxe) hasEnchantment(Enchantments.FORTUNE) + sortedWith { + compareByDescending> { + it.stack.canBreak(CachedBlockPosition(world, pos, false)) + }.thenByDescending { + state.calcItemBlockBreakingDelta(pos, it.stack) + }.thenByDescending { + it.stack.inventoryIndex == HotbarManager.serverSlot } + } } val silentSwapSelection = selectContainer { diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt index f7372a0be..f5d4b848e 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt @@ -28,14 +28,14 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.inventory.ContainerSelection.Companion.selectContainer +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.managers.rotating.Rotation import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.inventory.ContainerSelection.Companion.selectContainer -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.StackSelection.Companion.select -import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.util.BlockUtils.blockState import com.lambda.util.EntityUtils.getPositionsWithinHitboxXZ import com.lambda.util.PlaceDirection @@ -60,7 +60,6 @@ import net.minecraft.entity.Entity import net.minecraft.item.BlockItem import net.minecraft.item.Item import net.minecraft.item.ItemPlacementContext -import net.minecraft.item.Items import net.minecraft.screen.slot.Slot import net.minecraft.state.property.Properties import net.minecraft.util.Hand @@ -211,8 +210,8 @@ class InteractSim private constructor(simInfo: InteractSimInfo) supervisorScope.cancel() return null } - val stackSelection = item?.select()?.apply { if (item == Items.AIR) count = 0 } - ?: StackSelection.selectStack(0, sorter = compareByDescending { it.inventoryIndex == player.inventory.selectedSlot }) + val stackSelection = item?.select() + ?: selectStack { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } val containerSelection = selectContainer { ofAnyType(Container.Rank.Hotbar) } val container = stackSelection.findContainersWithMaterial(containerSelection).firstOrNull() ?: run { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt index 67ec97b81..5fbdb6fa7 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt @@ -19,8 +19,8 @@ package com.lambda.interaction.construction.simulation.context import com.lambda.context.Automated import com.lambda.graphics.mc.RenderBuilder -import com.lambda.interaction.managers.rotating.RotationRequest import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.managers.rotating.RotationRequest import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.emptyState import net.minecraft.block.BlockState diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 6837ab8ea..1ac15b8ed 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -22,7 +22,6 @@ import baritone.api.pathing.goals.GoalInverted import com.lambda.context.AutomatedSafeContext import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.util.DirectionMask.mask -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.ComparableResult @@ -32,8 +31,9 @@ import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack +import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.handlers.ContainerHandler.transferByTask +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import net.minecraft.block.BlockState @@ -120,7 +120,7 @@ sealed class BreakResult : BuildResult() { context(task: Task<*>, _: AutomatedSafeContext) override fun resolve() { selectStack { - isItem(badItem).not() + inverted { isItem(badItem) } }.transferByTask(HotbarContainer)?.softFail()?.execute(task) } diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index a9b550507..9762b191d 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -20,15 +20,15 @@ package com.lambda.interaction.construction.simulation.result.results import baritone.api.pathing.goals.GoalNear import com.lambda.context.AutomatedSafeContext import com.lambda.graphics.mc.RenderBuilder -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.ComparableResult import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable -import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.handlers.ContainerHandler.transferByTask +import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import net.minecraft.client.data.TextureMap.side diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt index f0f9f5932..a05e9f570 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt @@ -20,7 +20,6 @@ package com.lambda.interaction.construction.simulation.result.results import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalInverted import com.lambda.graphics.mc.RenderBuilder -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.simulation.context.InteractContext import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Contextual @@ -28,6 +27,7 @@ import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank +import com.lambda.interaction.handlers.BaritoneHandler import net.minecraft.block.BlockState import net.minecraft.entity.Entity import net.minecraft.item.Item diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt index d7a320f2b..efa0cbaf6 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt @@ -19,12 +19,12 @@ package com.lambda.interaction.construction.simulation.result.results import baritone.api.pathing.goals.GoalBlock import com.lambda.graphics.mc.RenderBuilder -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.ComparableResult import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank +import com.lambda.interaction.handlers.BaritoneHandler import net.minecraft.block.BlockState import net.minecraft.util.math.BlockPos import java.awt.Color diff --git a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt index 733931f37..0398fc6cb 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt @@ -25,7 +25,7 @@ import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.containers.ChestContainer import com.lambda.interaction.inventory.container.containers.EnderChestContainer diff --git a/src/main/kotlin/com/lambda/interaction/handlers/FriendHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/FriendHandler.kt index a27a7d4bb..9afa8a5d3 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/FriendHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/FriendHandler.kt @@ -34,7 +34,7 @@ import com.mojang.authlib.GameProfile import net.minecraft.entity.player.PlayerEntity import net.minecraft.text.Text import java.awt.Color -import java.util.UUID +import java.util.* object FriendHandler : Config( "friends", diff --git a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt index 8f3df5c02..af39eafcd 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt @@ -20,7 +20,9 @@ package com.lambda.interaction.handlers import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackAndSlot +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.modules.movement.elytrafly.ElytraFly import com.lambda.module.modules.movement.elytrafly.ElytraFly.mode @@ -30,7 +32,6 @@ import com.lambda.module.modules.player.AutoElytraSwap.glideDelay import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.player.PlayerUtils.canGlideWithChestPiece import com.lambda.util.player.PlayerUtils.canStartGliding -import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots import net.minecraft.component.DataComponentTypes import net.minecraft.enchantment.Enchantments import net.minecraft.entity.attribute.EntityAttributes @@ -41,36 +42,40 @@ import net.minecraft.registry.tag.ItemTags object GlideHandler { val ELYTRA_SELECTION = selectStack { - sortByDescending { - it.getEnchantment(Enchantments.UNBREAKING) - }.thenByDescending { - it.getEnchantment(Enchantments.MENDING) - } isItem(Items.ELYTRA) - .and { it.damage < it.maxDamage } + custom { stack, _ -> stack.damage < stack.maxDamage } + sortedWith { + compareByDescending> { + it.stack.getEnchantment(Enchantments.UNBREAKING) + }.thenByDescending { + it.stack.getEnchantment(Enchantments.MENDING) + } + } } val CHESTPLATE_SELECTION = selectStack { - sortByDescending { - it.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) - ?.modifiers - ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR } - ?.modifier?.value - ?: 0.0 - }.thenByDescending { - it.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) - ?.modifiers - ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR_TOUGHNESS } - ?.modifier?.value - ?: 0.0 - }.thenByDescending { - it.getEnchantment(Enchantments.UNBREAKING) - }.thenByDescending { - it.getEnchantment(Enchantments.MENDING) - } hasTag(ItemTags.CHEST_ARMOR) - .and { it.item != Items.ELYTRA } - .and { it.damage < it.maxDamage } + inverted { isItem(Items.ELYTRA) } + custom { stack, _ -> stack.damage < stack.maxDamage } + sortedWith { + compareByDescending> { + it.stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) + ?.modifiers + ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR } + ?.modifier?.value + ?: 0.0 + }.thenByDescending { + it.stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) + ?.modifiers + ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR_TOUGHNESS } + ?.modifier?.value + ?: 0.0 + }.thenByDescending { + it.stack.getEnchantment(Enchantments.UNBREAKING) + }.thenByDescending { + it.stack.getEnchantment(Enchantments.MENDING) + } + } } @JvmStatic val overridingGlide @@ -84,7 +89,10 @@ object GlideHandler { init { listen({ -1000 }) { - if (!player.isGliding && pendingGlides.isEmpty()) AutoElytraSwap.restore() + if (pendingGlides.isEmpty()) { + if (swapped && !player.isGliding) AutoElytraSwap.restore() + return@listen + } tickPendingGlides() } @@ -163,7 +171,7 @@ object GlideHandler { val fakeFly = ElytraFly.isEnabled && ElytraFly.fakeFly val canGlideAlready = player.canGlideWithChestPiece() != fakeFly if (!autoSwapChecking || canGlideAlready) return canGlideAlready - return player.hotbarAndInventorySlots.let { slots -> + return HotbarAndInventoryContainer.slots.let { slots -> if (fakeFly) CHESTPLATE_SELECTION.filterSlots(slots).isNotEmpty() else ELYTRA_SELECTION.filterSlots(slots).isNotEmpty() } diff --git a/src/main/kotlin/com/lambda/interaction/handlers/breaking/BrokenBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/breaking/BrokenBlockHandler.kt index 7d91d6e59..b34ccf2c6 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/breaking/BrokenBlockHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/breaking/BrokenBlockHandler.kt @@ -24,11 +24,11 @@ import com.lambda.event.events.EntityEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.processing.ProcessorRegistry +import com.lambda.interaction.handlers.breaking.RebreakHandler.rebreak import com.lambda.interaction.managers.PostActionHandler +import com.lambda.interaction.managers.breaking.BreakInfo import com.lambda.interaction.managers.breaking.BreakManager.lastPosStarted import com.lambda.interaction.managers.breaking.BreakManager.matchesBlockItem -import com.lambda.interaction.handlers.breaking.RebreakHandler.rebreak -import com.lambda.interaction.managers.breaking.BreakInfo import com.lambda.module.modules.client.Client import com.lambda.module.modules.client.Client.verboseDebug import com.lambda.threading.runGameScheduled diff --git a/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakHandler.kt index ee4a0fdb4..122414983 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakHandler.kt @@ -24,13 +24,13 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.BreakContext -import com.lambda.interaction.handlers.packet.PacketLimitHandler -import com.lambda.interaction.handlers.packet.PacketType import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.destroyBlock -import com.lambda.interaction.managers.breaking.BreakManager.calcBreakDelta import com.lambda.interaction.handlers.breaking.RebreakHandler.rebreak +import com.lambda.interaction.handlers.packet.PacketLimitHandler +import com.lambda.interaction.handlers.packet.PacketType import com.lambda.interaction.managers.breaking.BreakInfo import com.lambda.interaction.managers.breaking.BreakManager +import com.lambda.interaction.managers.breaking.BreakManager.calcBreakDelta import com.lambda.interaction.managers.breaking.BreakRequest import com.lambda.threading.runSafeAutomated import com.lambda.util.player.PlayerUtils.swingHand diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index daa5231cb..31534912f 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -17,9 +17,8 @@ package com.lambda.interaction.inventory -import com.lambda.interaction.inventory.StackSelection.Companion.StackSelectionDsl import com.lambda.util.EnchantmentUtils.getEnchantment -import com.lambda.util.item.ItemStackUtils.shulkerBoxContents +import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils import net.minecraft.block.Block import net.minecraft.block.BlockState @@ -33,288 +32,214 @@ import net.minecraft.registry.RegistryKey import net.minecraft.registry.tag.TagKey import net.minecraft.screen.slot.Slot import java.util.* -import kotlin.reflect.KClass -/** - * [StackSelection] is a class that holds a predicate for matching [ItemStack]s. - */ @Suppress("unused") -@StackSelectionDsl -class StackSelection { - var selector: (ItemStack) -> Boolean = EVERYTHING - var comparator: Comparator = NO_COMPARE - var count: Int = DEFAULT_AMOUNT - var inShulkerBox: Boolean = false - - var item: Item? = null - var itemClass: KClass? = null - private var damage: Int? = null - var itemStack: ItemStack? = null - val stackSize: Int - get() = optimalStack?.maxCount ?: 64 - - val optimalStack: ItemStack? - get() = itemStack ?: item?.let { ItemStack(it, count) } - - /** - * Filters the given [stacks], sorts them with the [comparator] and returns the first value - */ - fun bestItemMatch(stacks: List): ItemStack? = filterStacks(stacks).firstOrNull() - - fun matches(stack: ItemStack): Boolean = filterStack(stack) - - fun filterStack(stack: ItemStack) = - if (inShulkerBox) stack.shulkerBoxContents.any { selector(it) } - else selector(stack) - - fun filterSlot(slot: Slot): Boolean = filterStack(slot.stack) - - fun filterStacks(stacks: List): List = - stacks.filter(::filterStack).sortedWith(comparator) - - fun filterSlots(slots: List): List = - slots.filter(::filterSlot).sortedWith { slot, slot2 -> comparator.compare(slot.stack, slot2.stack) } - - fun > sortBy(selector: (ItemStack) -> R?): StackSelection = apply { - comparator = compareBy(selector) - } - - fun > sortByDescending(selector: (ItemStack) -> R?): StackSelection = apply { - comparator = compareByDescending(selector) - } - - fun > thenBy(selector: (ItemStack) -> R?): StackSelection = apply { - check(comparator != NO_COMPARE) { "No comparator specified" } - comparator = comparator.thenBy(selector) - } - - fun > thenByDescending(selector: (ItemStack) -> R?): StackSelection = apply { - check(comparator != NO_COMPARE) { "No comparator specified" } - comparator = comparator.thenByDescending(selector) - } - - fun sortWith(custom: Comparator): StackSelection = apply { - comparator = custom - } - - fun reversed(): StackSelection = apply { - comparator = comparator.reversed() - } - - /** - * returns a function that finds a shulker box to push matching items into. - */ - val findShulkerToPush = { stack: ItemStack -> - stack.shulkerBoxContents.let { inventory -> - if (inventory.all { selector(it) || it.isEmpty }) { - val storableItems = inventory.sumOf { -// if (it.isEmpty) item.itemStackLimit else it.maxStackSize - it.count - if (it.isEmpty) item?.maxCount ?: 0 else 0 - } - - if (storableItems > 0) storableItems else null - } else { - null - } - } - } - - /** - * returns a function that finds a shulker box to pull matching items from. - */ - val findShulkerToPull = { slot: Slot -> - slot.stack.shulkerBoxContents.let { inventory -> - val usableItems = inventory.sumOf { if (selector(it)) it.count else 0 } - - if (usableItems > 0) slot to usableItems else null - } - } - - fun any() = EVERYTHING - fun none() = NOTHING - - /** - * [isItem] returns a predicate that matches a specific [Item]. - * @param item The [Item] to be matched. - * @return A predicate that matches the [Item]. - */ - fun isItem(item: Item): (ItemStack) -> Boolean { - this.item = item - return { it.item == item } - } - - /** - * Returns a predicate that matches if the `ItemStack`'s item is one of the specified items in the collection. - * - * @param items The collection of `Item` instances to match against. - * @return A predicate that checks if the `ItemStack`'s item is contained in the provided collection. - */ - fun isOneOfItems(items: Collection): (ItemStack) -> Boolean = { it.item in items } - - fun isNoneOfItems(items: Collection): (ItemStack) -> Boolean = isOneOfItems(items).not() - - /** - * Returns a predicate that checks if a given `ItemStack` exists within the provided collection of `ItemStack`s. - * - * @param stacks A collection of `ItemStack` instances to be checked against. - * @return A predicate that evaluates to `true` if the given `ItemStack` is within the specified collection, otherwise `false`. - */ - fun isOneOfStacks(stacks: Collection): (ItemStack) -> Boolean = stacks::contains - - fun isEfficientForBreaking(blockState: BlockState): (ItemStack) -> Boolean = { itemStack -> - val hasEfficientTool = efficientToolCache.getOrPut(blockState) { - ItemUtils.tools.any { it.getMiningSpeed(it.defaultStack, blockState) > 1f } - } - if (hasEfficientTool) itemStack.item.getMiningSpeed(itemStack, blockState) > 1f - else true - } - - fun isSuitableForBreaking(blockState: BlockState): (ItemStack) -> Boolean = { !blockState.isToolRequired || it.isSuitableFor(blockState) } - - fun hasTag(tag: TagKey): (ItemStack) -> Boolean = { it.isIn(tag) } - - fun hasUseAction(action: UseAction): (ItemStack) -> Boolean = { it.useAction == action } - - fun isTool(): (ItemStack) -> Boolean = hasComponent(DataComponentTypes.TOOL) - - fun isFood(): (ItemStack) -> Boolean = hasComponent(DataComponentTypes.FOOD) - - fun hasComponent(type: ComponentType<*>): (ItemStack) -> Boolean = { it.components.contains(type) } - - /** - * [isItem] returns a predicate that matches a specific [Item] instance. - * @param T The instance of [Item] to be matched. - * @return A predicate that matches the [Item]. - */ - inline fun isItem(): (ItemStack) -> Boolean { - itemClass = T::class - return { it.item is T } - } - - /** - * [isBlock] returns a predicate that matches a specific [Block]. - * @param block The [Block] to be matched. - * @return A predicate that matches the [Block]. - */ - fun isBlock(block: Block): (ItemStack) -> Boolean { - item = block.asItem() - return { it.item == block.asItem() } - } - - /** - * [isItemStack] returns a predicate that matches a specific [ItemStack]. - * @param stack The [ItemStack] to be matched. - * @return A predicate that matches the [ItemStack]. - */ - fun isItemStack(stack: ItemStack): (ItemStack) -> Boolean { - this.itemStack = stack - return { ItemStack.areEqual(it, stack) } - } - - /** - * [hasDamage] returns a predicate that matches a specific damage value. - * @param damage The damage value to be matched. - * @return A predicate that matches the damage value. - */ - fun hasDamage(damage: Int): (ItemStack) -> Boolean { - this.damage = damage - return { it.damage == damage } - } - - /** - * [hasEnchantment] returns a predicate that matches a specific [Enchantment] and level. - * @param enchantment The [Enchantment] to be matched. - * @param level The level to be matched (if -1 will look for any level above 0). - * @return A predicate that matches the [Enchantment] and `level`. - */ - fun hasEnchantment(enchantment: RegistryKey, level: Int = -1): (ItemStack) -> Boolean = { - if (level < 0) { - it.getEnchantment(enchantment) > 0 - } else { - it.getEnchantment(enchantment) == level - } - } - - /** - * Returns the negation of the original predicate. - * @return A new predicate that matches if the original predicate does not match. - */ - fun ((ItemStack) -> Boolean).not(): (ItemStack) -> Boolean = { !this(it) } - - /** - * Combines two predicates using the logical AND operator. - * @param otherPredicate The second predicate. - * @return A new predicate that matches if both inputs predicate match. - */ - infix fun ((ItemStack) -> Boolean).and(otherPredicate: (ItemStack) -> Boolean): (ItemStack) -> Boolean = { this(it) && otherPredicate(it) } - - /** - * Combines two predicates using the logical OR operator. - * @param otherPredicate The second predicate. - * @return A new predicate that matches if either input predicate matches. - */ - infix fun ((ItemStack) -> Boolean).or(otherPredicate: (ItemStack) -> Boolean): (ItemStack) -> Boolean = { this(it) || otherPredicate(it) } - - fun ((ItemStack) -> Boolean).andIf(predicate: Boolean, otherPredicate: () -> (ItemStack) -> Boolean): (ItemStack) -> Boolean = - if (predicate) { { this(it) && otherPredicate()(it) } } else this - - override fun toString() = buildString { - append("selection of ${count}x ") - item?.let { append(it.name.string) } - itemClass?.let { append(it.simpleName) } - itemStack?.let { append(it.name.string) } - damage?.let { append(" with damage $it") } - when (selector) { - EVERYTHING -> append(" everything") - NOTHING -> append(" nothing") - else -> append(" custom predicate") - } - if (inShulkerBox) append(" in shulker box") - if (comparator != NO_COMPARE) append(" sorted by custom comparator") - } - - companion object { - @DslMarker - annotation class StackSelectionDsl - - const val DEFAULT_AMOUNT = 1 - - val FULL_SHULKERS: (ItemStack) -> Boolean = { stack -> stack.shulkerBoxContents.none { it.isEmpty } } - val EMPTY_SHULKERS: (ItemStack) -> Boolean = { stack -> stack.shulkerBoxContents.all { it.isEmpty } } - val EVERYTHING: (ItemStack) -> Boolean = { true } - val NOTHING: (ItemStack) -> Boolean = { false } - val NO_COMPARE: Comparator = Comparator { _, _ -> 0 } - - val efficientToolCache: MutableMap = Collections.synchronizedMap(mutableMapOf()) - - @StackSelectionDsl - fun Item.select() = selectStack { isItem(this@select) } - - @StackSelectionDsl - fun ItemStack.select() = selectStack { isItemStack(this@select) } - - @StackSelectionDsl - @JvmName("selectStacks") - fun Collection.select() = selectStack { isOneOfStacks(this@select) } - - @StackSelectionDsl - @JvmName("selectItems") - fun Collection.select() = selectStack { isOneOfItems(this@select) } - - @StackSelectionDsl - fun ((ItemStack) -> Boolean).select() = selectStack { this@select } - - @StackSelectionDsl - fun selectStack( - count: Int = DEFAULT_AMOUNT, - inShulkerBox: Boolean = false, - sorter: Comparator = NO_COMPARE, - block: StackSelection.() -> (ItemStack) -> Boolean = { EVERYTHING }, - ) = StackSelection().apply { - selector = block() - comparator = sorter - this.count = count - this.inShulkerBox = inShulkerBox - } - } +class StackSelection( + val count: Int = 0, + val item: Item? = null, + val itemStack: ItemStack? = null, + val inShulkerBox: Boolean = false, + val comparator: Comparator> = compareBy { it.stack.count }, + val selector: (ItemStack, Slot?) -> Boolean, +) { + val optimalStack = itemStack ?: item?.let { ItemStack(it, count) } + + @StackSelectionMarker + fun bestMatch(stacks: List) = filterStacks(stacks).firstOrNull() + @StackSelectionMarker + fun bestMatch(slots: List) = filterSlots(slots).firstOrNull() + + @StackSelectionMarker + fun matches(stack: ItemStack) = filterStack(stack) + @StackSelectionMarker + fun matches(slot: Slot) = filterSlot(slot) + + @StackSelectionMarker + fun filterStack(stack: ItemStack) = + if (inShulkerBox) stack.shulkerBoxStacks.any { selector(it, null) } + else selector(stack, null) + @StackSelectionMarker + fun filterSlot(slot: Slot): Boolean = + if (inShulkerBox) slot.stack.shulkerBoxStacks.any { selector(it, null) } + else selector(slot.stack, slot) + + @StackSelectionMarker + fun filterStacks(stacks: List): List = + stacks + .filter(::filterStack) + .map { StackAndSlot(it, null) } + .sortedWith(comparator) + .map { it.stack } + @StackSelectionMarker + fun filterSlots(slots: List): List = + slots + .filter(::filterSlot) + .map { StackAndSlot(it.stack, it) } + .sortedWith(comparator) + .map { it.slot } + + companion object { + val EVERYTHING = StackSelection { _, _ -> true } + val NOTHING = StackSelection { _, _ -> false } + } +} + +@DslMarker +private annotation class StackSelectionMarker + +@Suppress("unused") +@StackSelectionMarker +class StackSelectionBuilder(private val count: Int = 0) { + private var selector: (ItemStack, Slot?) -> Boolean = { _, _ -> true } + private var item: Item? = null + private var stackByRef = false + private var itemStack: ItemStack? = null + private var comparator: Comparator> = compareBy { it.stack.count } + private var inShulkerBoxesOnly: Boolean = false + private var invertNewSelectors = false + + fun isItem(item: Item) { + this.item = item + } + + inline fun isItem() { + val kClass = T::class + appendSelector { stack, _ -> stack::class == kClass } + } + + fun isItemStack(stack: ItemStack) { + this.itemStack = stack + appendSelector { s, _ -> ItemStack.areEqual(s, stack) } + } + + fun isItemStackByRef(stack: ItemStack) { + this.itemStack = stack + appendSelector { s, _ -> s === stack } + } + + fun inShulkerBoxesOnly() { + inShulkerBoxesOnly = true + } + + fun isOneOfItems(items: Collection) { + appendSelector { stack, _ -> items.contains(stack.item) } + } + + fun isNoneOfItems(items: Collection) { + appendSelector { stack, _ -> !items.contains(stack.item) } + } + + fun isOneOfStacks(stacks: Collection) { + appendSelector { stack, _ -> stacks.contains(stack) } + } + + fun isNoneOfStacks(stacks: Collection) { + appendSelector { stack, _ -> !stacks.contains(stack) } + } + + fun isEfficientForBreaking(blockState: BlockState) { + appendSelector { itemStack, _ -> + val hasEfficientTool = efficientToolCache.getOrPut(blockState) { + ItemUtils.tools.any { it.getMiningSpeed(it.defaultStack, blockState) > 1f } + } + if (hasEfficientTool) itemStack.item.getMiningSpeed(itemStack, blockState) > 1f + else true + } + } + + fun isSuitableForBreaking(blockState: BlockState) { + appendSelector { itemStack, _ -> + !blockState.isToolRequired || itemStack.isSuitableFor(blockState) + } + } + + fun hasTag(tag: TagKey) { + appendSelector { stack, _ -> stack.isIn(tag) } + } + + fun hasUseAction(action: UseAction) { + appendSelector { stack, _ -> stack.useAction == action } + } + + fun isTool() = hasComponent(DataComponentTypes.TOOL) + + fun isFood() = hasComponent(DataComponentTypes.FOOD) + + fun hasComponent(type: ComponentType<*>) { + appendSelector { stack, _ -> + stack.components.contains(type) + } + } + + fun isBlock(block: Block) { + item = block.asItem() + appendSelector { stack, _ -> stack.item == block.asItem() } + } + + fun hasDamage(damage: Int) { + appendSelector { stack, _ -> stack.damage == damage } + } + + fun hasEnchantment(enchantment: RegistryKey, level: Int = -1) { + appendSelector { stack, _ -> + if (level < 0) { + stack.getEnchantment(enchantment) > 0 + } else { + stack.getEnchantment(enchantment) == level + } + } + } + + fun inverted(block: () -> Unit) { + invertNewSelectors = true + block() + invertNewSelectors = false + } + + fun custom(predicate: (ItemStack, Slot?) -> Boolean) { + appendSelector { stack, slot -> predicate(stack, slot) } + } + + fun sortedWith(comparator: Comparator>) { + this.comparator = comparator + } + + fun sortedWith(comparatorSupplier: () -> Comparator>) { + this.comparator = comparatorSupplier() + } + + @PublishedApi + internal fun appendSelector(selector: (ItemStack, Slot?) -> Boolean) { + val invert = invertNewSelectors + this.selector = { stack, slot -> + this.selector(stack, slot) && (selector(stack, slot) xor invert) + } + } + + private fun build() = + StackSelection( + count, + item, + itemStack, + inShulkerBoxesOnly, + comparator, + selector + ) + + companion object { + private val efficientToolCache: MutableMap = Collections.synchronizedMap(mutableMapOf()) + + @StackSelectionMarker + fun Item.select(count: Int = 0) = selectStack(count) { isItem(this@select) } + + @StackSelectionMarker + fun ItemStack.select(count: Int = 0) = selectStack(count) { isItemStack(this@select) } + + fun selectStack( + count: Int = 0, + builder: StackSelectionBuilder.() -> Unit + ) = StackSelectionBuilder(count).apply(builder).build() + } } + +data class StackAndSlot(val stack: ItemStack, val slot: T) \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 9e514a27d..46a0ad7e5 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -22,15 +22,15 @@ import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent -import com.lambda.interaction.managers.inventory.InventoryRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.ShulkerBoxContainer +import com.lambda.interaction.managers.inventory.InventoryRequest +import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.task.tasks.ContainerTransferTask import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.empty -import com.lambda.util.item.ItemStackUtils.shulkerBoxContents +import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemStackUtils.spaceLeft import com.lambda.util.item.ItemUtils import com.lambda.util.item.ItemUtils.toItemCount @@ -104,7 +104,7 @@ abstract class Container( it.stack.item in ItemUtils.shulkerBoxes }.map { slot -> ShulkerBoxContainer( - slot.stack.shulkerBoxContents, + slot.stack.shulkerBoxStacks, containedIn = this@Container, shulkerSlot = slot ) @@ -159,7 +159,7 @@ abstract class Container( context(_: SafeContext) open fun spaceAvailable(selection: StackSelection) = - matchingStacks(selection).spaceLeft + stacks.empty * selection.stackSize + matchingStacks(selection).spaceLeft + stacks.empty * selection.count context(_: AutomatedSafeContext) open fun getReplaceableSlot() = slots.sortedWith(replaceSorter).firstOrNull() @@ -173,6 +173,7 @@ abstract class Container( OffHand, Hotbar, Inventory, + HotbarAndInventory, Armor, Player, Creative, diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt index 061298208..479ce919e 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt @@ -27,7 +27,6 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -@Suppress("unused") object ArmorContainer : Container(Rank.Armor) { context(safeContext: SafeContext) override val slots: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt index cbbf7c616..dc2f69b1e 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt @@ -20,8 +20,8 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.interaction.handlers.ContainerHandler -import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.task.Task import com.lambda.task.TaskGenerator import com.lambda.task.tasks.OpenContainerTask diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt index 3c00c1a6a..9c9ff74db 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt @@ -18,9 +18,9 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.context.SafeContext -import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt index a7b6993fa..4b74135cf 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt @@ -19,11 +19,11 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial -import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.task.TaskGenerator import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainerTask diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt new file mode 100644 index 000000000..c2dc8c52c --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container.containers + +import com.lambda.Lambda.mc +import com.lambda.context.SafeContext +import com.lambda.interaction.inventory.container.Container +import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots +import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks +import com.lambda.util.text.buildText +import com.lambda.util.text.literal +import net.minecraft.item.ItemStack +import net.minecraft.screen.slot.Slot + +object HotbarAndInventoryContainer : Container(Rank.HotbarAndInventory) { + context(safeContext: SafeContext) + override val slots: List + get() = safeContext.player.hotbarAndInventorySlots + override var stacks: List + get() = mc.player?.hotbarAndInventoryStacks ?: emptyList() + set(_) {} + + override val description = buildText { literal("Hotbar and Inventory") } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt index 1e62c37aa..f3db002c0 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt @@ -19,8 +19,8 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.util.player.SlotUtils.hotbarSlots import com.lambda.util.player.SlotUtils.hotbarStacks import com.lambda.util.text.buildText diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt index 018859489..839c1fa6d 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt @@ -19,8 +19,8 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.util.player.SlotUtils.mainHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt index f48df2fd4..74f9f252a 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt @@ -19,8 +19,8 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.managers.inventory.InventoryRequest import com.lambda.util.player.SlotUtils.offHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt index 5a644647b..8cb68f275 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt @@ -20,8 +20,8 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.interaction.handlers.ContainerHandler -import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.task.TaskGenerator import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainerTask diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt index 551e48286..daae64b81 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt @@ -34,11 +34,18 @@ import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.Manager -import com.lambda.interaction.managers.ManagerUtils.isPosBlocked +import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.destroyBlock +import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.pendingActions +import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.setPendingConfigs +import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.startPending +import com.lambda.interaction.handlers.breaking.RebreakHandler +import com.lambda.interaction.handlers.breaking.RebreakHandler.getRebreakPotential +import com.lambda.interaction.handlers.breaking.RebreakResult import com.lambda.interaction.handlers.packet.PacketLimitHandler import com.lambda.interaction.handlers.packet.PacketType -import com.lambda.interaction.handlers.breaking.RebreakHandler +import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.managers.Manager +import com.lambda.interaction.managers.ManagerUtils.isPosBlocked import com.lambda.interaction.managers.PositionBlocking import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Primary import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Rebreak @@ -63,18 +70,10 @@ import com.lambda.interaction.managers.breaking.BreakManager.rotationRequest import com.lambda.interaction.managers.breaking.BreakManager.simulateAbandoned import com.lambda.interaction.managers.breaking.BreakManager.updateBreakProgress import com.lambda.interaction.managers.breaking.BreakManager.updatePreProcessing -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.destroyBlock -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.pendingActions -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.setPendingConfigs -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.startPending -import com.lambda.interaction.handlers.breaking.RebreakHandler.getRebreakPotential -import com.lambda.interaction.handlers.breaking.RebreakResult import com.lambda.interaction.managers.breaking.SwapInfo.Companion.getSwapInfo import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.interacting.InteractManager import com.lambda.interaction.managers.rotating.RotationRequest -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.threading.runGameScheduled import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated @@ -141,7 +140,7 @@ object BreakManager : Manager( .lastOrNull { it.breakConfig.doubleBreak || it.type == Secondary }?.context?.itemSelection - ?: StackSelection.EVERYTHING.select() + ?: StackSelection.EVERYTHING override val blockedPositions get() = activeInfos.map { it.context.blockPos } + pendingActions.map { it.context.blockPos } diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt index 583afaae8..312e473d5 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt @@ -28,7 +28,7 @@ import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.managers.Request -import com.lambda.interaction.managers.breaking.BreakRequest.Companion.breakRequest +import com.lambda.interaction.managers.breaking.BreakRequest.BreakRequestMarker import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.isEmpty @@ -40,7 +40,7 @@ import net.minecraft.util.math.BlockPos * * The callbacks can be used to keep track of the break progress. * - * A private constructor is used to force use of the cleaner [BreakRequestDsl] builder. This is + * A private constructor is used to force use of the cleaner [BreakRequestMarker] builder. This is * accessed through the [breakRequest] method. * * @param contexts A collection of [BreakContext]'s gathered from the BuildSimulator. @@ -48,75 +48,98 @@ import net.minecraft.util.math.BlockPos * * @see com.lambda.interaction.construction.simulation.BuildSimulator */ -data class BreakRequest private constructor( +data class BreakRequest( val contexts: Collection, val pendingInteractions: MutableCollection, + override val nowOrNothing: Boolean, private val automated: Automated, - override val nowOrNothing: Boolean = false + val onStart: (SafeContext.(BlockPos) -> Unit)?, + val onUpdate: (SafeContext.(BlockPos) -> Unit)?, + val onStop: (SafeContext.(BlockPos) -> Unit)?, + val onCancel: (SafeContext.(BlockPos) -> Unit)?, + val onItemDrop: (SafeContext.(ItemEntity) -> Unit)?, + val onReBreakStart: (SafeContext.(BlockPos) -> Unit)?, + val onReBreak: (SafeContext.(BlockPos) -> Unit)? ) : Request(), Automated by automated { override val requestId = ++requestCount override val tickStageMask get() = breakConfig.tickStageMask - var onStart: (SafeContext.(BlockPos) -> Unit)? = null - var onUpdate: (SafeContext.(BlockPos) -> Unit)? = null - var onStop: (SafeContext.(BlockPos) -> Unit)? = null - var onCancel: (SafeContext.(BlockPos) -> Unit)? = null - var onItemDrop: (SafeContext.(ItemEntity) -> Unit)? = null - var onReBreakStart: (SafeContext.(BlockPos) -> Unit)? = null - var onReBreak: (SafeContext.(BlockPos) -> Unit)? = null - override val done: Boolean get() = runSafe { contexts.all { blockState(it.blockPos).isEmpty } } == true @DslMarker - annotation class BreakRequestDsl + annotation class BreakRequestMarker - @BreakRequestDsl + @BreakRequestMarker override fun submit(queueIfMismatchedStage: Boolean) = BreakManager.request(this, queueIfMismatchedStage) - @BreakRequestDsl - class BreakRequestBuilder( - contexts: Collection, - pendingInteractions: MutableCollection, - nowOrNothing: Boolean, - automated: Automated - ) { - val request = BreakRequest(contexts, pendingInteractions, automated, nowOrNothing) - - fun onStart(callback: SafeContext.(BlockPos) -> Unit) { - request.onStart = callback - } - - fun onUpdate(callback: SafeContext.(BlockPos) -> Unit) { - request.onUpdate = callback - } - - fun onStop(callback: SafeContext.(BlockPos) -> Unit) { - request.onStop = callback - } - - fun onCancel(callback: SafeContext.(BlockPos) -> Unit) { - request.onCancel = callback - } - - fun onItemDrop(callback: SafeContext.(ItemEntity) -> Unit) { - request.onItemDrop = callback - } - - fun onReBreakStart(callback: SafeContext.(BlockPos) -> Unit) { - request.onReBreakStart = callback - } - - fun onReBreak(callback: SafeContext.(BlockPos) -> Unit) { - request.onReBreak = callback - } - } - companion object { var requestCount = 0 + } +} + +@BreakRequestMarker +class BreakRequestBuilder( + private val contexts: Collection, + private val pendingInteractions: MutableCollection, + private val nowOrNothing: Boolean, + private val automated: Automated +) { + private var onStart: (SafeContext.(BlockPos) -> Unit)? = null + private var onUpdate: (SafeContext.(BlockPos) -> Unit)? = null + private var onStop: (SafeContext.(BlockPos) -> Unit)? = null + private var onCancel: (SafeContext.(BlockPos) -> Unit)? = null + private var onItemDrop: (SafeContext.(ItemEntity) -> Unit)? = null + private var onReBreakStart: (SafeContext.(BlockPos) -> Unit)? = null + private var onReBreak: (SafeContext.(BlockPos) -> Unit)? = null + + fun onStart(callback: SafeContext.(BlockPos) -> Unit) { + onStart = callback + } + + fun onUpdate(callback: SafeContext.(BlockPos) -> Unit) { + onUpdate = callback + } + + fun onStop(callback: SafeContext.(BlockPos) -> Unit) { + onStop = callback + } - @BreakRequestDsl + fun onCancel(callback: SafeContext.(BlockPos) -> Unit) { + onCancel = callback + } + + fun onItemDrop(callback: SafeContext.(ItemEntity) -> Unit) { + onItemDrop = callback + } + + fun onReBreakStart(callback: SafeContext.(BlockPos) -> Unit) { + onReBreakStart = callback + } + + fun onReBreak(callback: SafeContext.(BlockPos) -> Unit) { + onReBreak = callback + } + + @BreakRequestMarker + private fun build() = + BreakRequest( + contexts, + pendingInteractions, + nowOrNothing, + automated, + onStart, + onUpdate, + onStop, + onCancel, + onItemDrop, + onReBreakStart, + onReBreak + ) + + companion object { + @BreakRequestMarker @JvmName("breakRequest1") fun AutomatedSafeContext.breakRequest( positions: Collection, @@ -128,7 +151,7 @@ data class BreakRequest private constructor( .simulate() .breakRequest(pendingInteractions, nowOrNothing, builder) - @BreakRequestDsl + @BreakRequestMarker @JvmName("breakRequest2") context(automated: Automated) fun Collection.breakRequest( @@ -138,7 +161,7 @@ data class BreakRequest private constructor( ) = asSequence() .breakRequest(pendingInteractions, nowOrNothing, builder) - @BreakRequestDsl + @BreakRequestMarker @JvmName("breakRequest3") context(automated: Automated) fun Sequence.breakRequest( @@ -153,7 +176,7 @@ data class BreakRequest private constructor( .takeIf { it.isNotEmpty() } ?.let { automated.breakRequest(it, pendingInteractions, nowOrNothing, builder) } - @BreakRequestDsl + @BreakRequestMarker @JvmName("breakRequest4") fun Automated.breakRequest( contexts: Collection, @@ -163,8 +186,5 @@ data class BreakRequest private constructor( ) = BreakRequestBuilder( contexts, pendingInteractions, nowOrNothing, this ).apply { builder?.invoke(this) }.build() - - @BreakRequestDsl - private fun BreakRequestBuilder.build(): BreakRequest = request } } diff --git a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt index 442e05e38..b016527b6 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt @@ -29,10 +29,13 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.InteractContext -import com.lambda.interaction.managers.Manager -import com.lambda.interaction.managers.ManagerUtils.isPosBlocked +import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.pendingActions +import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.setPendingConfigs +import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.startPending import com.lambda.interaction.handlers.packet.PacketLimitHandler import com.lambda.interaction.handlers.packet.PacketType +import com.lambda.interaction.managers.Manager +import com.lambda.interaction.managers.ManagerUtils.isPosBlocked import com.lambda.interaction.managers.PositionBlocking import com.lambda.interaction.managers.breaking.BreakManager import com.lambda.interaction.managers.hotbar.HotbarRequest @@ -41,9 +44,6 @@ import com.lambda.interaction.managers.interacting.InteractManager.maxInteractio import com.lambda.interaction.managers.interacting.InteractManager.populateFrom import com.lambda.interaction.managers.interacting.InteractManager.potentialInteractions import com.lambda.interaction.managers.interacting.InteractManager.processRequest -import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.pendingActions -import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.setPendingConfigs -import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.startPending import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.module.modules.world.AutoSign.signWriteDelay import com.lambda.threading.runConcurrent diff --git a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt index 80d6a859f..b5baa4a98 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt @@ -25,52 +25,63 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.managers.Request +import com.lambda.interaction.managers.interacting.InteractRequest.PlaceRequestMarker import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.matches import net.minecraft.util.math.BlockPos -data class InteractRequest private constructor( +data class InteractRequest( val contexts: Collection, val pendingInteractions: MutableCollection, - private val automated: Automated, override val nowOrNothing: Boolean = false, + private val automated: Automated, + val onPlace: (SafeContext.(BlockPos) -> Unit)? ) : Request(), Automated by automated { override val requestId = ++requestCount override val tickStageMask get() = interactConfig.tickStageMask - var onPlace: (SafeContext.(BlockPos) -> Unit)? = null - override val done: Boolean get() = runSafe { contexts.all { it.expectedState.matches(blockState(it.blockPos)) } } == true @DslMarker - annotation class PlaceRequestDsl + annotation class PlaceRequestMarker - @PlaceRequestDsl + @PlaceRequestMarker override fun submit(queueIfMismatchedStage: Boolean) = InteractManager.request(this, queueIfMismatchedStage) - @PlaceRequestDsl - class PlaceRequestBuilder( - contexts: Collection, - pendingInteractions: MutableCollection, - nowOrNothing: Boolean, - automated: Automated - ) { - val request = InteractRequest(contexts, pendingInteractions, automated, nowOrNothing) + companion object { + var requestCount = 0 + } +} + +@PlaceRequestMarker +class PlaceRequestBuilder( + private val contexts: Collection, + private val pendingInteractions: MutableCollection, + private val nowOrNothing: Boolean, + private val automated: Automated +) { + private var onPlace: (SafeContext.(BlockPos) -> Unit)? = null - fun onPlace(callback: SafeContext.(BlockPos) -> Unit) { - request.onPlace = callback - } + fun onPlace(callback: SafeContext.(BlockPos) -> Unit) { + onPlace = callback } - companion object { - var requestCount = 0 + @PlaceRequestMarker + private fun build() = + InteractRequest( + contexts, + pendingInteractions, + nowOrNothing, + automated, + onPlace + ) - @PlaceRequestDsl + companion object { @JvmName("interactRequest1") context(automated: Automated) fun Collection.interactRequest( @@ -80,7 +91,6 @@ data class InteractRequest private constructor( ) = asSequence() .interactRequest(pendingInteractions, nowOrNothing, builder) - @PlaceRequestDsl @JvmName("interactRequest2") context(automated: Automated) fun Sequence.interactRequest( @@ -95,16 +105,17 @@ data class InteractRequest private constructor( .takeIf { it.isNotEmpty() } ?.let { automated.interactRequest(it, pendingInteractions, nowOrNothing, builder) } - @PlaceRequestDsl @JvmName("interactRequest3") fun Automated.interactRequest( contexts: Collection, pendingInteractions: MutableCollection, nowOrNothing: Boolean = false, builder: (PlaceRequestBuilder.() -> Unit)? = null - ) = PlaceRequestBuilder(contexts, pendingInteractions, nowOrNothing, this).apply { builder?.invoke(this) }.build() - - @PlaceRequestDsl - fun PlaceRequestBuilder.build() = request + ) = PlaceRequestBuilder( + contexts, + pendingInteractions, + nowOrNothing, + this + ).apply { builder?.invoke(this) }.build() } } diff --git a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt index be39fa5e5..46b385b1e 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt @@ -22,18 +22,19 @@ import com.lambda.context.SafeContext import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.managers.Request import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.requestCount +import com.lambda.interaction.managers.rotating.IRotationRequest.Full +import com.lambda.interaction.managers.rotating.IRotationRequest.Pitch +import com.lambda.interaction.managers.rotating.IRotationRequest.Yaw import com.lambda.interaction.managers.rotating.Rotation.Companion.dist import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation import com.lambda.interaction.managers.rotating.Rotation.Companion.wrap +import com.lambda.interaction.managers.rotating.RotationRequest.RotationRequestMarker import com.lambda.threading.runSafe import com.lambda.util.collections.UpdatableLazy import com.lambda.util.collections.updatableLazy import kotlin.math.abs import kotlin.math.hypot -@DslMarker -annotation class RotationRequestDsl - abstract class RotationRequest(automated: Automated) : Request(), Automated by automated { override val requestId = requestCount++ override val tickStageMask = automated.rotationConfig.tickStageMask @@ -41,7 +42,10 @@ abstract class RotationRequest(automated: Automated) : Request(), Automated by a abstract infix fun dist(rotation: Rotation): Double - @RotationRequestDsl + @DslMarker + annotation class RotationRequestMarker + + @RotationRequestMarker override fun submit(queueIfMismatchedStage: Boolean) = RotationManager.request(this, queueIfMismatchedStage) } @@ -136,72 +140,61 @@ interface IRotationRequest : Automated { interface PitchRot : IRotationRequest { val pitch: UpdatableLazy } interface FullRot : YawRot, PitchRot { val rotation: UpdatableLazy } - class RotationRequestBuilder { - var pitchBuilder: (SafeContext.() -> Double)? = null - var yawBuilder: (SafeContext.() -> Double)? = null - var rotationBuilder: (SafeContext.() -> Rotation)? = null + companion object { + var requestCount = 0 + } +} + +@RotationRequestMarker +class RotationRequestBuilder { + private var pitchBuilder: (SafeContext.() -> Double)? = null + private var yawBuilder: (SafeContext.() -> Double)? = null + private var rotationBuilder: (SafeContext.() -> Rotation)? = null - @JvmName("yawBuilder1") - @RotationRequestDsl - fun yaw(builder: SafeContext.() -> Double) { yawBuilder = builder } + @JvmName("yawBuilder1") + fun yaw(builder: SafeContext.() -> Double) { yawBuilder = builder } - @JvmName("yawBuilder2") - @RotationRequestDsl - fun yaw(builder: SafeContext.() -> Float) { yawBuilder = { builder().toDouble() } } + @JvmName("yawBuilder2") + fun yaw(builder: SafeContext.() -> Float) { yawBuilder = { builder().toDouble() } } - @RotationRequestDsl - fun yaw(yaw: Double) { yawBuilder = { yaw } } + fun yaw(yaw: Double) { yawBuilder = { yaw } } - @RotationRequestDsl - fun yaw(yaw: Float) { yawBuilder = { yaw.toDouble() } } + fun yaw(yaw: Float) { yawBuilder = { yaw.toDouble() } } - @JvmName("pitchBuilder1") - @RotationRequestDsl - fun pitch(builder: SafeContext.() -> Double) { pitchBuilder = builder } + @JvmName("pitchBuilder1") + fun pitch(builder: SafeContext.() -> Double) { pitchBuilder = builder } - @JvmName("pitchBuilder2") - @RotationRequestDsl - fun pitch(builder: SafeContext.() -> Float) { pitchBuilder = { builder().toDouble() } } + @JvmName("pitchBuilder2") + fun pitch(builder: SafeContext.() -> Float) { pitchBuilder = { builder().toDouble() } } - @RotationRequestDsl - fun pitch(pitch: Double) { pitchBuilder = { pitch } } + fun pitch(pitch: Double) { pitchBuilder = { pitch } } - @RotationRequestDsl - fun pitch(pitch: Float) { pitchBuilder = { pitch.toDouble() } } + fun pitch(pitch: Float) { pitchBuilder = { pitch.toDouble() } } - @RotationRequestDsl - fun rotation(builder: SafeContext.() -> Rotation) { rotationBuilder = builder } + fun rotation(builder: SafeContext.() -> Rotation) { rotationBuilder = builder } - @RotationRequestDsl - fun rotation(yaw: Double, pitch: Double) { rotationBuilder = { Rotation(yaw, pitch) } } + fun rotation(yaw: Double, pitch: Double) { rotationBuilder = { Rotation(yaw, pitch) } } - @RotationRequestDsl - fun rotation(yaw: Float, pitch: Float) { rotationBuilder = { Rotation(yaw, pitch) } } + fun rotation(yaw: Float, pitch: Float) { rotationBuilder = { Rotation(yaw, pitch) } } - @RotationRequestDsl - fun rotation(rotation: Rotation) { rotationBuilder = { rotation } } + fun rotation(rotation: Rotation) { rotationBuilder = { rotation } } + + context(automated: Automated) + private fun build(): RotationRequest { + val yawBuilder = yawBuilder + val pitchBuilder = pitchBuilder + val rotationBuilder = rotationBuilder + return when { + rotationBuilder != null -> Full(automated, rotationBuilder) + yawBuilder != null && pitchBuilder != null -> Full(automated) { Rotation(yawBuilder(), pitchBuilder()) } + yawBuilder != null -> Yaw(automated, yawBuilder) + pitchBuilder != null -> Pitch(automated, pitchBuilder) + else -> throw IllegalArgumentException("Must specify at least one rotation value to build a rotation request") + } } companion object { - var requestCount = 0 - - @RotationRequestDsl fun Automated.rotationRequest(builder: RotationRequestBuilder.() -> Unit) = RotationRequestBuilder().apply(builder).build() - - @RotationRequestDsl - context(automated: Automated) - private fun RotationRequestBuilder.build(): RotationRequest { - val yawBuilder = yawBuilder - val pitchBuilder = pitchBuilder - val rotationBuilder = rotationBuilder - return when { - rotationBuilder != null -> Full(automated, rotationBuilder) - yawBuilder != null && pitchBuilder != null -> Full(automated) { Rotation(yawBuilder(), pitchBuilder()) } - yawBuilder != null -> Yaw(automated, yawBuilder) - pitchBuilder != null -> Pitch(automated, pitchBuilder) - else -> throw IllegalArgumentException("Must specify at least one rotation value to build a rotation request") - } - } } } diff --git a/src/main/kotlin/com/lambda/module/hud/Baritone.kt b/src/main/kotlin/com/lambda/module/hud/Baritone.kt index 5551231da..601602b71 100644 --- a/src/main/kotlin/com/lambda/module/hud/Baritone.kt +++ b/src/main/kotlin/com/lambda/module/hud/Baritone.kt @@ -18,8 +18,8 @@ package com.lambda.module.hud import com.lambda.gui.dsl.ImGuiBuilder -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.simulation.BuildGoal +import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.module.HudModule import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt index 395fd1767..dc827d9be 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt @@ -25,13 +25,13 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.inventory.container.containers.ArmorContainer +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemUtils.armorSlot -import com.lambda.util.player.SlotUtils.armorSlots -import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots import net.minecraft.component.DataComponentTypes import net.minecraft.enchantment.Enchantment import net.minecraft.enchantment.Enchantments @@ -98,7 +98,7 @@ object AutoArmor : Module( }.thenByDescending { slot -> slot.stack.getEnchantment(Enchantments.UNBREAKING) + slot.stack.getEnchantment(Enchantments.MENDING) - } + }.thenBy { it.index in 0..8 } init { setDefaultAutomationConfig() @@ -117,9 +117,9 @@ object AutoArmor : Module( fun SafeContext.tick() { tickedThisTick = true - val armorSlots = player.armorSlots + val armorSlots = ArmorContainer.slots - val swappable = player.hotbarAndInventorySlots + val swappable = HotbarAndInventoryContainer.slots .filter { it.stack.isEquipable && (!ignoreBinding || it.stack.getEnchantment(Enchantments.BINDING_CURSE) <= 0) } .sortedWith(SORTER) .distinctBy { it.stack.armorSlot } @@ -142,9 +142,9 @@ object AutoArmor : Module( }.submit() } - context(safeContext: SafeContext) + context(_: SafeContext) private val ItemStack.isEquipable - get() = safeContext.player.armorSlots.any { it.canInsert(this) } + get() = ArmorContainer.slots.any { it.canInsert(this) } private enum class Protection(val enchant: RegistryKey) { Protection(Enchantments.PROTECTION), diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index 76708df58..348045061 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -24,8 +24,8 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.FriendHandler +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.inventory.StackSelection.Companion.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.combat.CombatUtils.hasDeadlyCrystal diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 2dfdd7150..f5b071e0b 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -27,14 +27,14 @@ import com.lambda.context.SafeContext import com.lambda.event.events.EntityEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.hotbar.HotbarRequest -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.interaction.handlers.ContainerHandler.transfer +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer +import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe @@ -55,7 +55,6 @@ import com.lambda.util.math.getHitVec import com.lambda.util.math.minus import com.lambda.util.math.plus import com.lambda.util.player.RotationUtils.getVisibleSurfaces -import com.lambda.util.player.SlotUtils.hotbarStacks import com.lambda.util.world.fastEntitySearch import net.minecraft.block.Blocks import net.minecraft.entity.Entity @@ -361,7 +360,7 @@ object CrystalAura : Module( val entitiesNearby = fastEntitySearch(3.5, pos) val crystals = entitiesNearby.filterIsInstance() - val otherEntities = entitiesNearby - crystals + player + val otherEntities = entitiesNearby - crystals.toSet() + player if (otherEntities.any { it.boundingBox.intersects(crystalBox) @@ -487,14 +486,14 @@ object CrystalAura : Module( (swapHand == Hand.OFF_HAND && player.offHandStack.item != selection.item) ) runSafeAutomated { if (!swap) return@runSafe - var crystalSlot = player.hotbarStacks.indexOfFirst { selection.filterStack(it) } + var crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.filterStack(it) } if (crystalSlot < 0) { val swapTo = when (swapHand) { Hand.MAIN_HAND -> HotbarContainer Hand.OFF_HAND -> OffHandContainer } if (!selection.transfer(swapTo)) return@runSafe - crystalSlot = player.hotbarStacks.indexOfFirst { selection.filterStack(it) } + crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.filterStack(it) } } if (!HotbarRequest(crystalSlot, this).submit().done) return@runSafe } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index dc3f79d4a..bc64a3c70 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -28,9 +28,10 @@ import com.lambda.context.SafeContext import com.lambda.event.events.InventoryEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.managers.hotbar.HotbarRequest -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated @@ -39,7 +40,6 @@ import com.lambda.util.item.ItemStackUtils.attackDamage import com.lambda.util.item.ItemStackUtils.attackSpeed import com.lambda.util.math.random import com.lambda.util.player.RotationUtils.lookAtEntity -import com.lambda.util.player.SlotUtils.hotbarStacks import net.minecraft.entity.Entity import net.minecraft.item.ItemStack import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket @@ -119,12 +119,17 @@ object KillAura : Module( } if (swap) { - val selection = selectStack().sortByDescending { - damageMode.block(this, it) - } - - selection.bestItemMatch(player.hotbarStacks)?.let { bestStack -> - val slotId = player.hotbarStacks.indexOf(bestStack) + val selection = + selectStack { + sortedWith { + compareByDescending { + damageMode.block(this@listen, it.stack) + } + } + } + + selection.bestMatch(HotbarContainer.stacks)?.let { bestStack -> + val slotId = HotbarContainer.stacks.indexOf(bestStack) if (!HotbarRequest(slotId, this@KillAura, nowOrNothing = false).submit().done) return@listen } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index af36ab55f..79848af5d 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -22,9 +22,10 @@ import com.lambda.config.ConfigEditor.hideBlock import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig import com.lambda.config.withEdits import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.FriendHandler.isFriend import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.handlers.FriendHandler.isFriend +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run @@ -34,7 +35,6 @@ import com.lambda.util.BlockUtils.blockState import com.lambda.util.extension.shrinkByEpsilon import com.lambda.util.item.ItemUtils.block import com.lambda.util.math.flooredBlockPos -import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks import com.lambda.util.world.entitySearch import net.minecraft.block.Blocks import net.minecraft.client.network.OtherClientPlayerEntity @@ -69,7 +69,7 @@ object PlayerTrap : Module( onEnable { task = tickingBlueprint { - val block = player.hotbarAndInventoryStacks.firstOrNull { + val block = HotbarAndInventoryContainer.stacks.firstOrNull { it.item is BlockItem && blocks.contains(it.item.block) }?.item?.block ?: return@tickingBlueprint emptyMap() val targetPlayer = if (self) player diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt index 017beec2c..a46767893 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt @@ -23,6 +23,7 @@ import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomat import com.lambda.config.withEdits import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.module.Module import com.lambda.module.modules.combat.PlayerTrap.getTrapPositions import com.lambda.module.tag.ModuleTag @@ -30,7 +31,6 @@ import com.lambda.task.RootTask.run import com.lambda.task.Task import com.lambda.task.tasks.BuildTask.Companion.build import com.lambda.util.item.ItemUtils.block -import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks import net.minecraft.block.Blocks import net.minecraft.item.BlockItem @@ -59,7 +59,7 @@ object Surround : Module( onEnable { task = tickingBlueprint { - val block = player.hotbarAndInventoryStacks.firstOrNull { + val block = HotbarAndInventoryContainer.stacks.firstOrNull { it.item is BlockItem && blocks.contains(it.item.block) }?.item?.block ?: return@tickingBlueprint emptyMap() getTrapPositions(player) diff --git a/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt b/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt index c4ca17648..d8c912926 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt @@ -26,6 +26,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.FriendHandler +import com.lambda.interaction.inventory.container.containers.PlayerContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.sound.SoundHandler.playSound @@ -37,10 +38,8 @@ import com.lambda.util.TickTimer import com.lambda.util.combat.CombatUtils.crystalDamage import com.lambda.util.combat.DamageUtils.isFallDeadly import com.lambda.util.extension.fullHealth -import com.lambda.util.extension.getBlockState import com.lambda.util.extension.tickDeltaF import com.lambda.util.player.PlayerUtils.isIn2b2tQueue -import com.lambda.util.player.SlotUtils.allStacks import com.lambda.util.player.SlotUtils.armorSlots import com.lambda.util.text.buildText import com.lambda.util.text.color @@ -389,7 +388,7 @@ object AutoDisconnect : Module( } else null }), Totem("Totem", { totem }, { totemSmart }, { - val totemCount = player.allStacks.count { it.item == Items.TOTEM_OF_UNDYING } + val totemCount = PlayerContainer.stacks.count { it.item == Items.TOTEM_OF_UNDYING } if (totemCount < minTotems) { buildText { literal("Only ") diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index 599e9dc87..955694f8c 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.StackSelection.Companion.select +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt index 6e8a3e4a0..aeaeb7a3f 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.player.RotationUtils.lookAt diff --git a/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt b/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt index ba2af3e0f..7548a0e24 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt @@ -22,7 +22,7 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.BlockPosIterators diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 48bc00c39..35bec0adf 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -29,10 +29,12 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.GlideHandler +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.inventory.StackSelection.Companion.select -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe @@ -41,8 +43,6 @@ import com.lambda.util.KeyCode import com.lambda.util.Mouse import com.lambda.util.player.PlayerUtils import com.lambda.util.player.PlayerUtils.canStartGliding -import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks -import com.lambda.util.player.SlotUtils.hotbarStacks import net.minecraft.client.network.ClientPlayerEntity import net.minecraft.item.Items import net.minecraft.network.packet.c2s.play.HandSwingC2SPacket @@ -85,7 +85,7 @@ object BetterFirework : Module( val ClientPlayerEntity.hasFireworks: Boolean get() = Items.FIREWORK_ROCKET.select() - .filterStacks(hotbarAndInventoryStacks) + .filterStacks(HotbarAndInventoryContainer.stacks) .isNotEmpty() || offHandStack.item == Items.FIREWORK_ROCKET context(_: SafeContext) @@ -156,11 +156,11 @@ object BetterFirework : Module( * Return true if a firework has been used */ fun SafeContext.startFirework(inventory: Boolean) { - val stack = selectStack(count = 1) { isItem(Items.FIREWORK_ROCKET) } + val stack = selectStack(1) { isItem(Items.FIREWORK_ROCKET) } - stack.bestItemMatch(player.hotbarStacks) + stack.bestMatch(HotbarContainer.stacks) ?.let { - val request = HotbarRequest(player.hotbarStacks.indexOf(it), this@BetterFirework, keepTicks = 0) + val request = HotbarRequest(HotbarContainer.stacks.indexOf(it), this@BetterFirework, keepTicks = 0) .submit(queueIfMismatchedStage = false) if (request.done) { interaction.interactItem(player, Hand.MAIN_HAND) @@ -171,10 +171,10 @@ object BetterFirework : Module( if (!inventory) return - stack.bestItemMatch(player.hotbarAndInventoryStacks) + stack.bestMatch(HotbarContainer.stacks) ?.let { - val swapSlotId = player.hotbarAndInventoryStacks.indexOf(it) - val hotbarSlotToSwapWith = player.hotbarStacks.find { slot -> slot.isEmpty }?.let { slot -> player.hotbarStacks.indexOf(slot) } ?: 8 + val swapSlotId = HotbarAndInventoryContainer.stacks.indexOf(it) + val hotbarSlotToSwapWith = HotbarContainer.stacks.find { slot -> slot.isEmpty }?.let { slot -> HotbarContainer.stacks.indexOf(slot) } ?: 8 inventoryRequest { swap(swapSlotId, hotbarSlotToSwapWith) diff --git a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt index fc5ad0fab..1416e7428 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt @@ -23,7 +23,7 @@ import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomat import com.lambda.config.withEdits import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.modules.movement.BetterFirework.startFirework import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt index 0ccaa9b9e..4e3fa5740 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt @@ -26,7 +26,7 @@ import com.lambda.event.events.ClientEvent import com.lambda.event.events.MovementEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt index 11242cb2b..640ef95e7 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt @@ -25,6 +25,8 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.GlideHandler.ELYTRA_SELECTION +import com.lambda.interaction.inventory.container.containers.ArmorContainer +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.inventory.InventoryManager import com.lambda.interaction.managers.inventory.InventoryRequest @@ -33,8 +35,6 @@ import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFly.fakeFly import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.logError -import com.lambda.util.player.SlotUtils.armorSlots -import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots import net.minecraft.entity.Entity import net.minecraft.entity.EquipmentSlot import net.minecraft.item.Items @@ -93,7 +93,7 @@ abstract class ElytraFlyMode( } val elytraInHotbar = elytraSlot.index in 0..8 - val chestSlot = player.armorSlots.getOrNull(1) ?: return false + val chestSlot = ArmorContainer.slots.getOrNull(1) ?: return false if (elytraInHotbar) { val hotbarRequest = HotbarRequest( @@ -126,7 +126,7 @@ abstract class ElytraFlyMode( open fun interrupt() {} fun SafeContext.findElytra(): Slot? = - ELYTRA_SELECTION.filterSlots(player.hotbarAndInventorySlots).minByOrNull { it.index } + ELYTRA_SELECTION.filterSlots(HotbarAndInventoryContainer.slots).minByOrNull { it.index } protected fun SafeContext.startFly() { player.setFlag(Entity.GLIDING_FLAG_INDEX, true) diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt index 25dcee4f4..e765ca705 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt @@ -27,8 +27,8 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.handlers.GlideHandler -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.hud.Speedometer import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFly.fakeFly diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt index d7620c087..22b8e3048 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt @@ -18,14 +18,15 @@ package com.lambda.module.modules.movement.elytrafly.modes import com.lambda.config.Config -import com.lambda.context.SafeContext import com.lambda.event.events.PacketEvent import com.lambda.event.events.PlayerPacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select +import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.inventory.StackSelection.Companion.select +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.modules.movement.BetterFirework.startFirework import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFlyMode @@ -35,8 +36,6 @@ import com.lambda.util.TickTimer import com.lambda.util.Timer import com.lambda.util.math.MathUtils.toFloat import com.lambda.util.player.PlayerUtils.hasFirework -import com.lambda.util.player.SlotUtils.hotbarStacks -import com.lambda.util.player.SlotUtils.inventoryStacks import net.minecraft.component.DataComponentTypes import net.minecraft.item.ItemStack import net.minecraft.item.Items @@ -135,8 +134,8 @@ class GrimControlElytraFly( } } - private fun SafeContext.findFirework(): ItemStack? { + private fun findFirework(): ItemStack? { val stack = Items.FIREWORK_ROCKET.select() - return stack.bestItemMatch(player.hotbarStacks) ?: if (inventory) stack.bestItemMatch(player.inventoryStacks) else null + return stack.bestMatch(HotbarContainer.stacks) ?: if (inventory) stack.bestMatch(InventoryContainer.stacks) else null } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt index 77ba3ca05..b078fcb14 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt @@ -21,8 +21,8 @@ import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.distSq diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt index 091341b9e..b912ec751 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt @@ -22,14 +22,14 @@ import com.lambda.interaction.handlers.GlideHandler.CHESTPLATE_SELECTION import com.lambda.interaction.handlers.GlideHandler.ELYTRA_SELECTION import com.lambda.interaction.handlers.GlideHandler.manuallySwapped import com.lambda.interaction.handlers.GlideHandler.swapped +import com.lambda.interaction.inventory.container.containers.ArmorContainer +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.tag.ModuleTag import com.lambda.util.CommunicationUtils.warn import com.lambda.util.player.PlayerUtils.canGlideWithChestPiece -import com.lambda.util.player.SlotUtils.armorSlots -import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots import net.minecraft.screen.slot.Slot object AutoElytraSwap : Module( @@ -47,7 +47,7 @@ object AutoElytraSwap : Module( context(safeContext: SafeContext) fun manualSwap(elytra: Boolean): Boolean { val swapSlot = - safeContext.player.hotbarAndInventorySlots.let { slots -> + HotbarAndInventoryContainer.slots.let { slots -> if (elytra) ELYTRA_SELECTION.filterSlots(slots) else CHESTPLATE_SELECTION.filterSlots(slots) }.minByOrNull { it.index } ?: run { @@ -59,7 +59,7 @@ object AutoElytraSwap : Module( } private fun SafeContext.swapWithChestplate(swapSlot: Slot): Boolean { - val chestplateSlot = player.armorSlots[1] + val chestplateSlot = ArmorContainer.slots.getOrNull(1) ?: return false return AutoElytraSwap.inventoryRequest { if (swapSlot.index in 0..8) swap(chestplateSlot.id, swapSlot.index) else { diff --git a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index e9d37d309..4b0ce1787 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -27,7 +27,7 @@ import com.lambda.event.events.PlayerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.context.BuildContext -import com.lambda.interaction.managers.breaking.BreakRequest.Companion.breakRequest +import com.lambda.interaction.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt index 0fdbccd43..833f0a7db 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt @@ -22,8 +22,8 @@ import com.lambda.config.blocks.RotationConfig import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.LambdaScreen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.RotationMode +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.InputUtils diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index ad179d3b4..1d8fd9e99 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -37,7 +37,7 @@ import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.breaking.BreakRequest.Companion.breakRequest +import com.lambda.interaction.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt index d5558a631..d0edbc647 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt @@ -29,15 +29,15 @@ import com.lambda.brigadier.CommandResult import com.lambda.config.blocks.RotationConfig import com.lambda.config.settings.complex.KeybindSetting.Companion.onPress import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.TimerHandler import com.lambda.event.EventFlow.lambdaScope import com.lambda.event.events.MovementEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.components.ClickGuiLayout -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.handlers.TimerHandler import com.lambda.interaction.managers.rotating.Rotation import com.lambda.interaction.managers.rotating.RotationMode +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.modules.player.Replay.InputAction.Companion.toAction import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt index 426b57c9a..307251bc7 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt @@ -23,8 +23,8 @@ import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomat import com.lambda.config.withEdits import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.RotationMode +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import kotlin.math.roundToInt diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index 67f369774..664e7363d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -24,12 +24,12 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.item.ItemStackUtils.slotId -import com.lambda.util.player.SlotUtils.hotbarStacks -import com.lambda.util.player.SlotUtils.inventoryStacks import net.minecraft.item.ItemStack import net.minecraft.item.Items @@ -53,7 +53,7 @@ object StackReplenish : Module( listen { if (player.currentScreenHandler.cursorStack.item !== Items.AIR) return@listen - player.hotbarStacks.forEach { stack -> checkReplenish(stack) } + HotbarContainer.stacks.forEach { stack -> checkReplenish(stack) } if (offhand) checkReplenish(player.offHandStack) } } @@ -62,7 +62,7 @@ object StackReplenish : Module( if (stack.count.toFloat() / stack.maxCount >= (minStackPercent.toFloat() / 100)) return if (!stack.isStackable) return - player.inventoryStacks.forEach { invStack -> + InventoryContainer.stacks.forEach { invStack -> if (!ItemStack.areItemsAndComponentsEqual(invStack, stack)) return@forEach val invId = invStack.slotId val completing = stack.count + invStack.count >= stack.maxCount diff --git a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt index 160b949c8..a9984aa86 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt @@ -23,14 +23,13 @@ import com.lambda.config.withEdits import com.lambda.event.events.ContainerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.EnchantmentUtils.forEachEnchantment import com.lambda.util.EnchantmentUtils.getEnchantment -import com.lambda.util.player.SlotUtils.hotbarSlots -import com.lambda.util.player.SlotUtils.inventorySlots import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot @@ -50,9 +49,9 @@ object ToolSaver : Module( } listen { - val endangeredStacks = player.hotbarSlots.filter { it.stack.isEndangered } + val endangeredStacks = HotbarContainer.slots.filter { it.stack.isEndangered } - val inventorySlots = player.inventorySlots + val inventorySlots = InventoryContainer.slots val swaps = endangeredStacks .mapNotNull { endangered -> val sorter = compareByDescending { swapSlot -> diff --git a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt index a5fa8c7f5..2712076b1 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt @@ -27,8 +27,8 @@ import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.InputUtils.isSatisfied import com.lambda.util.KeyCode -import com.lambda.util.item.ItemStackUtils.bundleContents -import com.lambda.util.item.ItemStackUtils.shulkerBoxContents +import com.lambda.util.item.ItemStackUtils.bundleStacks +import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils.bundles import com.lambda.util.item.ItemUtils.shulkerBoxes import com.lambda.util.text.buildText @@ -261,7 +261,7 @@ object ContainerPreview : Module( private fun getContainerContents(stack: ItemStack): List { return when { - isShulkerBox(stack) -> stack.shulkerBoxContents + isShulkerBox(stack) -> stack.shulkerBoxStacks isEnderChest(stack) -> EnderChestContainer.stacks else -> emptyList() } @@ -360,7 +360,7 @@ object ContainerPreview : Module( val hash = container.hashCode() return containerCache.computeIfAbsent(hash) { - val contents = container.shulkerBoxContents + container.bundleContents + val contents = container.shulkerBoxStacks + container.bundleStacks if (contents.isEmpty()) return@computeIfAbsent ContainerPreviewInfo(null, false) val group = contents.filter { stack -> stack.item != Items.AIR } diff --git a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt index 856071afd..1ff346388 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt @@ -29,9 +29,9 @@ import com.lambda.event.events.PlayerEvent import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.Rotation import com.lambda.interaction.managers.rotating.RotationMode +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt b/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt index 8368d108d..b097805d2 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt @@ -25,12 +25,12 @@ import com.lambda.config.Tab import com.lambda.config.blocks.EntitySelectionSettings import com.lambda.config.blocks.ScreenTextSettings import com.lambda.config.withEdits -import com.lambda.interaction.handlers.FriendHandler.isFriend import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.mc.renderer.RendererUtils.worldToScreenNormalized import com.lambda.graphics.text.FontHandler import com.lambda.graphics.util.DynamicAABB.Companion.interpolatedBox +import com.lambda.interaction.handlers.FriendHandler.isFriend import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt b/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt index 7239f74dc..f2d4d074e 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt @@ -24,9 +24,9 @@ import com.lambda.config.blocks.EntityColorSettings import com.lambda.config.blocks.EntitySelectionSettings import com.lambda.config.blocks.ScreenLineSettings import com.lambda.config.withEdits -import com.lambda.interaction.handlers.FriendHandler.isFriend import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.mc.renderer.RendererUtils.worldToScreenNormalized +import com.lambda.interaction.handlers.FriendHandler.isFriend import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt index bfac64ee2..182d49707 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt @@ -33,7 +33,7 @@ import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.managers.interacting.InteractRequest -import com.lambda.interaction.managers.interacting.InteractRequest.Companion.interactRequest +import com.lambda.interaction.managers.interacting.PlaceRequestBuilder.Companion.interactRequest import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 2d541772f..7335d5399 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -34,11 +34,13 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.util.DirectionMask -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack import com.lambda.module.Module import com.lambda.module.modules.world.AutoPortal.PosHandler.currAnchorPos import com.lambda.module.modules.world.AutoPortal.PosHandler.obiPositions @@ -58,8 +60,6 @@ import com.lambda.util.extension.tickDelta import com.lambda.util.math.lerp import com.lambda.util.math.setAlpha import com.lambda.util.math.vec3d -import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots -import com.lambda.util.player.SlotUtils.hotbarSlots import net.minecraft.block.Blocks import net.minecraft.item.FlintAndSteelItem import net.minecraft.item.Items @@ -326,7 +326,7 @@ object AutoPortal : Module( val sel = selectStack(1) { isItem() } - val hotbarStack = sel.filterSlots(player.hotbarSlots).firstOrNull() + val hotbarStack = sel.filterSlots(HotbarContainer.slots).firstOrNull() if (hotbarStack != null) { val request = HotbarRequest( hotbarStack.index, @@ -338,14 +338,14 @@ object AutoPortal : Module( } val invSlot = - if (inventory) sel.filterSlots(player.hotbarAndInventorySlots).firstOrNull() + if (inventory) sel.filterSlots(HotbarAndInventoryContainer.slots).firstOrNull() else null if (invSlot == null) { failure("No Flint and Steel!") return } val hotbarSlotToSwapWith = - player.hotbarSlots.find { slot -> + HotbarContainer.slots.find { slot -> slot.stack.isEmpty }?.index ?: 8 diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt index 4ee65b7c1..bb68c9222 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt @@ -30,7 +30,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.sound.SoundHandler.playSound diff --git a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt index d03db7fd6..c288468d9 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt @@ -20,10 +20,10 @@ package com.lambda.module.modules.world import com.lambda.config.ConfigEditor.editTypedSettings import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig import com.lambda.config.withEdits -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.blueprint.Blueprint.Companion.emptyStructure import com.lambda.interaction.construction.blueprint.PropagatingBlueprint.Companion.propagatingBlueprint import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run diff --git a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt index b4de4c5e7..4c6ed0869 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt @@ -19,12 +19,12 @@ package com.lambda.module.modules.world import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.inventory.container.containers.PlayerContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.FileUtils.locationBoundDirectory import com.lambda.util.FolderRegistry import com.lambda.util.StringUtils.hashString -import com.lambda.util.player.SlotUtils.allStacks import com.lambda.util.world.entitySearch import net.minecraft.block.MapColor import net.minecraft.entity.decoration.ItemFrameEntity @@ -43,7 +43,7 @@ object MapDownloader : Module( listen { val mapStates = entitySearch(128.0) .mapNotNull { FilledMapItem.getMapState(it.heldItemStack, world) } + - player.allStacks.mapNotNull { FilledMapItem.getMapState(it, world) } + PlayerContainer.stacks.mapNotNull { FilledMapItem.getMapState(it, world) } mapStates.forEach { map -> val name = map.hash diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index 32a761990..07fc716de 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -31,9 +31,9 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.interacting.InteractRequest.Companion.interactRequest -import com.lambda.interaction.inventory.StackSelection.Companion.selectStack +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.managers.interacting.PlaceRequestBuilder.Companion.interactRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated @@ -82,7 +82,9 @@ object Scaffold : Module( listen { val selection = selectStack { - { it.blockItem.let { blockItem -> blockItem != null && blockItem.block !in blacklistedBlocks } } + custom { stack, _ -> + stack.blockItem.let { blockItem -> blockItem != null && blockItem.block !in blacklistedBlocks } + } } val stack = player.mainHandStack.takeIf { selection.filterStack(it) } ?: selection.filterStacks(HotbarContainer.stacks).firstOrNull() ?: return@listen diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index 5ae411744..cb38bb2a3 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -39,15 +39,19 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.inventory.container.containers.EnderChestContainer +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.inventory.container.containers.OffHandContainer import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest import com.lambda.interaction.managers.rotating.Rotation import com.lambda.interaction.managers.rotating.Rotation.Companion.dist import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.inventory.container.containers.EnderChestContainer +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run @@ -68,12 +72,6 @@ import com.lambda.util.extension.rotation import com.lambda.util.math.distSq import com.lambda.util.math.setAlpha import com.lambda.util.player.SlotUtils.allSlots -import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots -import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks -import com.lambda.util.player.SlotUtils.hotbarSlots -import com.lambda.util.player.SlotUtils.hotbarStacks -import com.lambda.util.player.SlotUtils.inventoryStacks -import com.lambda.util.player.SlotUtils.offHandSlots import com.lambda.util.text.bold import com.lambda.util.text.buildText import com.lambda.util.text.color @@ -460,7 +458,7 @@ object StashMover : Module( MoverState.DispensingPearl -> handleDispensingPearl() MoverState.AwaitingPearl -> checkTimerProgress(MoverState.DispensingPearl, pearlButtonTimeout) { - if (player.hotbarAndInventoryStacks.any { it.item === Items.ENDER_PEARL }) { + if (HotbarAndInventoryContainer.stacks.any { it.item === Items.ENDER_PEARL }) { pearlThrown = false moverState = MoverState.ThrowingPearl true @@ -507,7 +505,7 @@ object StashMover : Module( if (moverState != MoverState.AwaitingTeleport) return@listen val packet = event.packet if (packet !is PlayerPositionLookS2CPacket) return@listen - if (finished && player.hotbarAndInventoryStacks.all { it.isEmpty }) { + if (finished && HotbarAndInventoryContainer.stacks.all { it.isEmpty }) { success(finishedMessage) return@listen } @@ -526,12 +524,12 @@ object StashMover : Module( moverState = MoverState.OpeningPullContainer return } - if (!moveFromContainerToContainer(screenHandler.containerSlots, player.hotbarAndInventoryStacks)) return + if (!moveFromContainerToContainer(screenHandler.containerSlots, HotbarAndInventoryContainer.stacks)) return pullContainer?.let { container -> if (screenHandler.containerStacks.all { it.isEmpty }) { pullContainers.remove(container) pulledContainers.add(container) - if (player.hotbarAndInventoryStacks.any { it.isEmpty }) { + if (HotbarAndInventoryContainer.stacks.any { it.isEmpty }) { moverState = MoverState.OpeningPullContainer return } @@ -549,7 +547,7 @@ object StashMover : Module( moverState = MoverState.OpeningPutEnderChest return } - if (moveFromContainerToContainer(player.hotbarAndInventorySlots, screenHandler.containerStacks)) { + if (moveFromContainerToContainer(HotbarAndInventoryContainer.slots, screenHandler.containerStacks)) { moverState = MoverState.OpeningPullContainer } } @@ -587,7 +585,7 @@ object StashMover : Module( rotation(rotation) }.submit() if (!rotationRequest.done || rotation dist RotationManager.serverRotation > 0.001) return - val throwSlots = player.hotbarAndInventorySlots.filter { !it.stack.isEmpty } + val throwSlots = HotbarAndInventoryContainer.slots.filter { !it.stack.isEmpty } if (throwSlots.isNotEmpty()) { val inventoryRequest = inventoryRequest(settleForLess = true) { throwSlots.forEach { slot -> @@ -604,12 +602,12 @@ object StashMover : Module( moverState = MoverState.OpeningPutContainer return } - if (!moveFromContainerToContainer(player.hotbarAndInventorySlots, screenHandler.containerStacks)) return + if (!moveFromContainerToContainer(HotbarAndInventoryContainer.slots, screenHandler.containerStacks)) return putContainer?.let { container -> if (screenHandler.containerStacks.all { !it.isEmpty }) { putContainers.remove(container) filledContainers.add(container) - if (player.hotbarAndInventoryStacks.any { !it.isEmpty }) { + if (HotbarAndInventoryContainer.stacks.any { !it.isEmpty }) { moverState = MoverState.OpeningPutContainer return } @@ -623,7 +621,7 @@ object StashMover : Module( moverState = MoverState.OpeningPullEnderChest return } - if (moveFromContainerToContainer(screenHandler.containerSlots, player.hotbarAndInventoryStacks)) { + if (moveFromContainerToContainer(screenHandler.containerSlots, HotbarAndInventoryContainer.stacks)) { putOrThrowItems() } } @@ -635,9 +633,9 @@ object StashMover : Module( return } if (BaritoneHandler.isActive) return - if (player.hotbarStacks.none { it.isEmpty }) { - val firstSlot = player.hotbarSlots.getOrNull(0) ?: run { failWithLog("No first slot? This shouldn't occur."); return } - if (player.inventoryStacks.any { it.isEmpty }) { + if (HotbarContainer.stacks.none { it.isEmpty }) { + val firstSlot = HotbarContainer.slots.getOrNull(0) ?: run { failWithLog("No first slot? This shouldn't occur."); return } + if (InventoryContainer.stacks.any { it.isEmpty }) { inventoryRequest { quickMove(firstSlot.id) }.submit() return } else if (player.offHandStack.isEmpty) { @@ -666,11 +664,11 @@ object StashMover : Module( if (pearlThrown) { if (!player.offHandStack.isEmpty) { - if (player.hotbarAndInventoryStacks.none { it.isEmpty }) { + if (HotbarAndInventoryContainer.stacks.none { it.isEmpty }) { failWithLog("No free slots to return the offhand stack to!") return } - val offhandSlot = player.offHandSlots.firstOrNull() ?: run { failWithLog("No offhand slot? This shouldn't occur."); return } + val offhandSlot = OffHandContainer.slots.firstOrNull() ?: run { failWithLog("No offhand slot? This shouldn't occur."); return } inventoryRequest { quickMove(offhandSlot.id) }.submit() } putOrThrowItems() @@ -683,7 +681,7 @@ object StashMover : Module( }.submit() if (!rotationRequest.done) return if (player.mainHandStack.item != Items.ENDER_PEARL) { - val hotbarSlot = player.hotbarSlots.firstOrNull { it.stack.item === Items.ENDER_PEARL } + val hotbarSlot = HotbarContainer.slots.firstOrNull { it.stack.item === Items.ENDER_PEARL } if (hotbarSlot != null) { val hotbarRequest = HotbarRequest(hotbarSlot.index, StashMover, nowOrNothing = false).submit() if (!hotbarRequest.done) return diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt index 72aec175b..de9264b21 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt @@ -19,9 +19,9 @@ package com.lambda.task.tasks import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.handlers.ContainerHandler.findContainerWithMaterial +import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index 9f5fb31cb..044ecd6bf 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -26,7 +26,6 @@ import com.lambda.context.SafeContext import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.construction.blueprint.Blueprint import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.PropagatingBlueprint @@ -47,8 +46,10 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.simulation.result.results.PreSimResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.breaking.BreakRequest.Companion.breakRequest -import com.lambda.interaction.managers.interacting.InteractRequest.Companion.interactRequest +import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.managers.breaking.BreakRequestBuilder.Companion.breakRequest +import com.lambda.interaction.managers.interacting.PlaceRequestBuilder.Companion.interactRequest import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.module.modules.client.Client import com.lambda.task.Task @@ -63,7 +64,6 @@ import com.lambda.util.FormattingUtils.format import com.lambda.util.extension.Structure import com.lambda.util.extension.playerSlots import com.lambda.util.math.dist -import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks import kotlinx.coroutines.Job import kotlinx.coroutines.runBlocking import net.minecraft.block.BlockState @@ -322,7 +322,7 @@ class BuildTask private constructor( return@let true } - if (player.hotbarAndInventoryStacks.none { it.isEmpty }) { + if (HotbarAndInventoryContainer.stacks.none { it.isEmpty }) { val stackToThrow = player.currentScreenHandler.playerSlots.firstOrNull { it.stack.item in inventoryConfig.disposables } ?: run { diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index ee24da55f..e71aa3f42 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -22,11 +22,11 @@ import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index 99c636fae..3ab6bf685 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -23,9 +23,9 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.managers.hotbar.HotbarRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt index 3877f6267..a5c181286 100644 --- a/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt @@ -23,7 +23,7 @@ import com.lambda.event.events.InventoryEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest +import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated import com.lambda.util.TickTimer diff --git a/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt b/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt index 9e39a0cbd..867acc01d 100644 --- a/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt +++ b/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt @@ -111,11 +111,11 @@ object ItemStackUtils { return listOf(copyWithCount(maxCount), copyWithCount(remainder)) } - val ItemStack.shulkerBoxContents: List by cacheable { stack -> + val ItemStack.shulkerBoxStacks: List by cacheable { stack -> stack.components.get(DataComponentTypes.CONTAINER)?.stream()?.toList() ?: emptyList() } - val ItemStack.bundleContents: List by cacheable { stack -> + val ItemStack.bundleStacks: List by cacheable { stack -> stack.components.get(DataComponentTypes.BUNDLE_CONTENTS)?.stream()?.toList() ?: emptyList() } diff --git a/src/main/kotlin/com/lambda/util/item/ItemUtils.kt b/src/main/kotlin/com/lambda/util/item/ItemUtils.kt index 836aa1dba..a3485c5ea 100644 --- a/src/main/kotlin/com/lambda/util/item/ItemUtils.kt +++ b/src/main/kotlin/com/lambda/util/item/ItemUtils.kt @@ -18,7 +18,7 @@ package com.lambda.util.item import com.lambda.context.SafeContext -import com.lambda.util.player.SlotUtils.armorSlots +import com.lambda.interaction.inventory.container.containers.ArmorContainer import net.minecraft.block.Block import net.minecraft.component.DataComponentTypes import net.minecraft.item.BlockItem @@ -150,7 +150,7 @@ object ItemUtils { context(safeContext: SafeContext) val ItemStack.armorSlot get() = - safeContext.player.armorSlots.firstOrNull { it.canInsert(this) } + ArmorContainer.slots.firstOrNull { it.canInsert(this) } fun Int.toItemCount(): String { if (this < 0) { From 3b043d9604bce0bf2ba9b292b1c495aa22a8eb8c Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:32:45 +0100 Subject: [PATCH 03/18] immutable container selections with builder and general cleanup --- .../lambda/config/blocks/InventoryConfig.kt | 3 +- .../simulation/checks/BreakSim.kt | 2 +- .../simulation/checks/InteractSim.kt | 4 +- .../interaction/handlers/ContainerHandler.kt | 2 +- .../interaction/handlers/GlideHandler.kt | 4 +- .../inventory/ContainerSelection.kt | 136 +++++----- .../interaction/inventory/StackSelection.kt | 43 ++-- .../inventory/container/Container.kt | 43 +--- .../inventory/container/ExternalContainer.kt | 2 + .../container/containers/ArmorContainer.kt | 4 +- .../container/containers/ChestContainer.kt | 9 +- .../container/containers/CreativeContainer.kt | 23 +- .../containers/EnderChestContainer.kt | 17 +- .../containers/HotbarAndInventoryContainer.kt | 4 +- .../container/containers/HotbarContainer.kt | 9 +- .../containers/InventoryContainer.kt | 4 +- .../container/containers/MainHandContainer.kt | 9 +- .../container/containers/OffHandContainer.kt | 9 +- .../container/containers/PlayerContainer.kt | 4 +- .../containers/ShulkerBoxContainer.kt | 4 +- .../container/containers/StashContainer.kt | 3 - .../managers/breaking/BreakManager.kt | 13 +- .../managers/breaking/BreakRequest.kt | 15 +- .../managers/hotbar/HotbarManager.kt | 6 +- .../managers/hotbar/HotbarRequest.kt | 35 ++- .../managers/interacting/InteractManager.kt | 9 +- .../managers/interacting/InteractRequest.kt | 15 +- .../managers/inventory/InventoryRequest.kt | 232 +++++++++--------- .../managers/rotating/RotationRequest.kt | 19 +- .../lambda/module/modules/combat/AutoArmor.kt | 2 +- .../lambda/module/modules/combat/AutoTotem.kt | 6 +- .../module/modules/combat/CrystalAura.kt | 8 +- .../lambda/module/modules/combat/KillAura.kt | 4 +- .../lambda/module/modules/debug/SilentSwap.kt | 4 +- .../module/modules/movement/BetterFirework.kt | 63 +++-- .../movement/elytrafly/ElytraFlyMode.kt | 21 +- .../elytrafly/modes/GrimControlElytraFly.kt | 15 +- .../module/modules/player/AutoElytraSwap.kt | 13 +- .../module/modules/player/InventoryResync.kt | 2 +- .../module/modules/player/StackReplenish.kt | 2 +- .../lambda/module/modules/player/ToolSaver.kt | 2 +- .../lambda/module/modules/world/AutoPortal.kt | 35 ++- .../lambda/module/modules/world/Scaffold.kt | 4 +- .../lambda/module/modules/world/StashMover.kt | 10 +- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 2 +- .../task/tasks/ContainerTransferTask.kt | 45 ++-- .../kotlin/com/lambda/task/tasks/EatTask.kt | 16 +- .../kotlin/com/lambda/util/PacketUtils.kt | 2 +- 48 files changed, 458 insertions(+), 480 deletions(-) diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index c60f8b4b8..18be96b21 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -20,6 +20,7 @@ package com.lambda.config.blocks import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.interaction.inventory.ContainerSelection +import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container import com.lambda.util.Describable @@ -39,7 +40,7 @@ interface InventoryConfig { val accessStashes: Boolean val containerSelection: ContainerSelection - get() = ContainerSelection.selectContainer { + get() = selectContainer { val allowedContainers = buildSet { addAll(Container.Rank.entries) if (!accessShulkerBoxes) remove(Container.Rank.ShulkerBox) diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt index ffea00e15..0fe648ead 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt @@ -29,7 +29,7 @@ import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial -import com.lambda.interaction.inventory.ContainerSelection.Companion.selectContainer +import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackAndSlot import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt index f5d4b848e..e81c88b73 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt @@ -28,7 +28,7 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial -import com.lambda.interaction.inventory.ContainerSelection.Companion.selectContainer +import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container @@ -217,7 +217,7 @@ class InteractSim private constructor(simInfo: InteractSimInfo) result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null } - return stackSelection.filterSlots(container.slots).run { + return stackSelection.filter(container.slots).run { firstOrNull { it.index == player.inventory.selectedSlot } ?: firstOrNull() } diff --git a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt index 0398fc6cb..b71db2c36 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt @@ -146,7 +146,7 @@ object ContainerHandler : Loadable { containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection ): List = findContainersWithMaterial(containerSelection) - .flatMap { filterSlots(it.slots) } + .flatMap { filter(it.slots) } context(automatedSafeContext: AutomatedSafeContext) diff --git a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt index af39eafcd..73157e79f 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt @@ -172,8 +172,8 @@ object GlideHandler { val canGlideAlready = player.canGlideWithChestPiece() != fakeFly if (!autoSwapChecking || canGlideAlready) return canGlideAlready return HotbarAndInventoryContainer.slots.let { slots -> - if (fakeFly) CHESTPLATE_SELECTION.filterSlots(slots).isNotEmpty() - else ELYTRA_SELECTION.filterSlots(slots).isNotEmpty() + if (fakeFly) CHESTPLATE_SELECTION.filter(slots).isNotEmpty() + else ELYTRA_SELECTION.filter(slots).isNotEmpty() } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt index 5d0948fb0..f0e405e92 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt @@ -17,81 +17,89 @@ package com.lambda.interaction.inventory -import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container /** * ContainerSelection is a class that holds a predicate for matching MaterialContainers. - * It can be combined using "and", "or", etc. */ -class ContainerSelection { - private var selector: (Container) -> Boolean = { true } +@Suppress("unused") +class ContainerSelection( + val selector: (Container) -> Boolean, + val comparator: Comparator = compareBy { it.rank } +) { + @ContainerSelectionMarker + fun bestMatch(containers: Iterable) = filter(containers).firstOrNull() - /** - * Tests whether the provided container matches this selection. - */ - @ContainerSelectionDsl + @ContainerSelectionMarker fun matches(container: Container): Boolean = selector(container) - /** - * Returns a function that matches containers having at least one stack - * which matches the given StackSelection. - */ - @ContainerSelectionDsl - context(_: SafeContext) - fun matches(stackSelection: StackSelection): (Container) -> Boolean = - { container -> container.matchingSlots(stackSelection).isNotEmpty() } - - /** - * Returns a function that checks whether a given MaterialContainer matches the criteria - * defined in the provided ContainerSelection. - */ - @ContainerSelectionDsl - fun matches(containerSelection: ContainerSelection): (Container) -> Boolean = - { container -> containerSelection.matches(container) } - - /** - * Returns a function that matches containers whose rank is any of the types provided. - */ - @ContainerSelectionDsl - fun ofAnyType(vararg types: Container.Rank): (Container) -> Boolean = - { container -> types.contains(container.rank) } - - /** - * Returns a function that matches containers whose rank is not any of the types provided. - */ - @ContainerSelectionDsl - fun noneOfType(vararg types: Container.Rank): (Container) -> Boolean = - { container -> !types.contains(container.rank) } - - /** - * Returns a function that combines two container predicates using logical AND. - */ - @ContainerSelectionDsl - infix fun ((Container) -> Boolean).and(other: (Container) -> Boolean): (Container) -> Boolean = - { container -> this(container) && other(container) } - - /** - * Returns a function that combines two container predicates using logical OR. - */ - @ContainerSelectionDsl - infix fun ((Container) -> Boolean).or(other: (Container) -> Boolean): (Container) -> Boolean = - { container -> this(container) || other(container) } - - /** - * Returns a function that negates the current selection predicate. - */ - @ContainerSelectionDsl - fun ((Container) -> Boolean).negate(): (Container) -> Boolean = - { container -> !this(container) } + @ContainerSelectionMarker + fun filter(containers: Iterable) = + containers + .filter(selector) + .sortedWith(comparator) companion object { - @DslMarker - annotation class ContainerSelectionDsl + val EVERYTHING = ContainerSelection({ true }) + val NOTHING = ContainerSelection({ false }) + } +} + +@DslMarker +annotation class ContainerSelectionMarker + +@Suppress("unused") +@ContainerSelectionMarker +class ContainerSelectionBuilder private constructor() { + private var selector: (Container) -> Boolean = { true } + private var comparator: Comparator = compareBy { it.rank } + private var invertNewSelectors = false + + fun ofAnyType(vararg types: Container.Rank) { + appendSelector { container -> types.contains(container.rank) } + } + + fun noneOfType(vararg types: Container.Rank) { + appendSelector { container -> !types.contains(container.rank) } + } + + fun matches(stackSelection: StackSelection) { + appendSelector { container -> container.matchingSlots(stackSelection).isNotEmpty() } + } + + fun matches(containerSelection: ContainerSelection) { + appendSelector { container -> containerSelection.matches(container) } + } - @ContainerSelectionDsl + fun custom(predicate: (Container) -> Boolean) { + appendSelector { predicate(it) } + } + + fun inverted(block: () -> Boolean) { + invertNewSelectors = true + block() + invertNewSelectors = false + } + + fun sortedWith(comparator: Comparator) { + this.comparator = comparator + } + + fun sortedWith(comparatorSupplier: () -> Comparator) { + this.comparator = comparatorSupplier() + } + + private fun appendSelector(selector: (Container) -> Boolean) { + val invert = invertNewSelectors + val currentSelector = this.selector + this.selector = { currentSelector(it) && selector(it) xor invert } + } + + private fun build() = ContainerSelection(selector, comparator) + + companion object { fun selectContainer( - block: ContainerSelection.() -> (Container) -> Boolean - ): ContainerSelection = ContainerSelection().apply { selector = block() } + builder: ContainerSelectionBuilder.() -> Unit + ) = ContainerSelectionBuilder().apply(builder).build() } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index 31534912f..81360e2f5 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -45,35 +45,32 @@ class StackSelection( val optimalStack = itemStack ?: item?.let { ItemStack(it, count) } @StackSelectionMarker - fun bestMatch(stacks: List) = filterStacks(stacks).firstOrNull() + fun bestMatch(stacks: Iterable) = filter(stacks).firstOrNull() @StackSelectionMarker - fun bestMatch(slots: List) = filterSlots(slots).firstOrNull() + fun bestMatch(slots: Iterable) = filter(slots).firstOrNull() @StackSelectionMarker - fun matches(stack: ItemStack) = filterStack(stack) - @StackSelectionMarker - fun matches(slot: Slot) = filterSlot(slot) - - @StackSelectionMarker - fun filterStack(stack: ItemStack) = + fun matches(stack: ItemStack) = if (inShulkerBox) stack.shulkerBoxStacks.any { selector(it, null) } else selector(stack, null) @StackSelectionMarker - fun filterSlot(slot: Slot): Boolean = + fun matches(slot: Slot): Boolean = if (inShulkerBox) slot.stack.shulkerBoxStacks.any { selector(it, null) } else selector(slot.stack, slot) @StackSelectionMarker - fun filterStacks(stacks: List): List = + @JvmName("filter1") + fun filter(stacks: Iterable) = stacks - .filter(::filterStack) + .filter(::matches) .map { StackAndSlot(it, null) } .sortedWith(comparator) .map { it.stack } @StackSelectionMarker - fun filterSlots(slots: List): List = + @JvmName("filter2") + fun filter(slots: Iterable) = slots - .filter(::filterSlot) + .filter(::matches) .map { StackAndSlot(it.stack, it) } .sortedWith(comparator) .map { it.slot } @@ -89,7 +86,7 @@ private annotation class StackSelectionMarker @Suppress("unused") @StackSelectionMarker -class StackSelectionBuilder(private val count: Int = 0) { +class StackSelectionBuilder private constructor(private val count: Int = 0) { private var selector: (ItemStack, Slot?) -> Boolean = { _, _ -> true } private var item: Item? = null private var stackByRef = false @@ -100,6 +97,7 @@ class StackSelectionBuilder(private val count: Int = 0) { fun isItem(item: Item) { this.item = item + appendSelector { stack, _ -> stack.item == item } } inline fun isItem() { @@ -190,16 +188,20 @@ class StackSelectionBuilder(private val count: Int = 0) { } } - fun inverted(block: () -> Unit) { - invertNewSelectors = true - block() - invertNewSelectors = false + fun isEmpty() { + appendSelector { stack, _ -> stack.isEmpty} } fun custom(predicate: (ItemStack, Slot?) -> Boolean) { appendSelector { stack, slot -> predicate(stack, slot) } } + fun inverted(block: () -> Unit) { + invertNewSelectors = true + block() + invertNewSelectors = false + } + fun sortedWith(comparator: Comparator>) { this.comparator = comparator } @@ -211,8 +213,9 @@ class StackSelectionBuilder(private val count: Int = 0) { @PublishedApi internal fun appendSelector(selector: (ItemStack, Slot?) -> Boolean) { val invert = invertNewSelectors + val currentSelector = this.selector this.selector = { stack, slot -> - this.selector(stack, slot) && (selector(stack, slot) xor invert) + currentSelector(stack, slot) && selector(stack, slot) xor invert } } @@ -227,7 +230,7 @@ class StackSelectionBuilder(private val count: Int = 0) { ) companion object { - private val efficientToolCache: MutableMap = Collections.synchronizedMap(mutableMapOf()) + private val efficientToolCache = Collections.synchronizedMap(mutableMapOf()) @StackSelectionMarker fun Item.select(count: Int = 0) = selectStack(count) { isItem(this@select) } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 46a0ad7e5..4375e43ba 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -24,8 +24,8 @@ import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.ShulkerBoxContainer -import com.lambda.interaction.managers.inventory.InventoryRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.tasks.ContainerTransferTask import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count @@ -49,7 +49,6 @@ import net.minecraft.text.Text abstract class Container( val rank: Rank ) : Nameable, Comparable { - context(_: SafeContext) abstract val slots: List abstract var stacks: List open val swapMethodPriority = 0 @@ -114,11 +113,11 @@ abstract class Container( this.stacks = slots } - context(_: SafeContext) - open fun InventoryRequest.InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { - if (fromHere.stack.isEmpty) pickupAndPlace(toSlot.id, fromHere.id) + context(safeContext: SafeContext) + open fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + if (fromHere.stack.isEmpty) moveSlot(toSlot.id, fromHere.id) else { - pickupAndPlace(fromHere.id, toSlot.id) + moveSlot(fromHere.id, toSlot.id) if (!toSlot.stack.isEmpty) pickup(fromHere.id) } } @@ -136,37 +135,24 @@ abstract class Container( }.submit().done } - context(automatedSafeContext: AutomatedSafeContext) + context(automated: Automated) fun transferByTask(stackSelection: StackSelection, destination: Container, failIfNoMaterial: Boolean = false) = - ContainerTransferTask(this, destination, stackSelection, automatedSafeContext, failIfNoMaterial) - - protected fun InventoryRequest.InvRequestBuilder.pickupAndPlace(fromId: Int, toId: Int) { - pickup(fromId) - pickup(toId) - } + ContainerTransferTask(this, destination, stackSelection, automated, failIfNoMaterial) - context(_: SafeContext) - open fun matchingStacks(selection: StackSelection) = - selection.filterStacks(stacks) - - context(_: SafeContext) - open fun matchingSlots(selection: StackSelection) = - selection.filterSlots(slots) + open fun matchingStacks(selection: StackSelection) = selection.filter(stacks) + open fun matchingSlots(selection: StackSelection) = selection.filter(slots) - context(_: SafeContext) open fun materialAvailable(selection: StackSelection) = matchingStacks(selection).count - context(_: SafeContext) open fun spaceAvailable(selection: StackSelection) = matchingStacks(selection).spaceLeft + stacks.empty * selection.count - context(_: AutomatedSafeContext) + context(_: Automated) open fun getReplaceableSlot() = slots.sortedWith(replaceSorter).firstOrNull() - context(_: SafeContext) open fun getSlot(stackSelection: StackSelection): Slot? = - stackSelection.filterSlots(slots).firstOrNull() + stackSelection.filter(slots).firstOrNull() enum class Rank { MainHand, @@ -183,8 +169,5 @@ abstract class Container( Stash } - override fun compareTo(other: Container) = - compareBy { - it.rank - }.compare(this, other) + override fun compareTo(other: Container) = compareBy { it.rank }.compare(this, other) } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt index 9d0bf3f14..da25cd005 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt @@ -19,9 +19,11 @@ package com.lambda.interaction.inventory.container import com.lambda.context.AutomatedSafeContext import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.TaskGenerator interface ExternalContainer { + @Ta5kBuilder context(_: AutomatedSafeContext) fun accessThen(exitAfter: Boolean = true, taskGenerator: TaskGenerator): Task<*>? } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt index 479ce919e..8222ae5d1 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt @@ -18,7 +18,6 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc -import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.armorSlots import com.lambda.util.player.SlotUtils.armorStacks @@ -28,9 +27,8 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot object ArmorContainer : Container(Rank.Armor) { - context(safeContext: SafeContext) override val slots: List - get() = safeContext.player.armorSlots + get() = mc.player?.armorSlots ?: emptyList() override var stacks: List get() = mc.player?.armorStacks ?: emptyList() set(_) {} diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt index dc2f69b1e..343b26cda 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt @@ -17,8 +17,8 @@ package com.lambda.interaction.inventory.container.containers +import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext -import com.lambda.context.SafeContext import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer @@ -39,12 +39,11 @@ data class ChestContainer( val blockPos: BlockPos, val containedInStash: StashContainer? = null ) : Container(Rank.Chest), ExternalContainer { - context(safeContext: SafeContext) override val slots get(): List = - if (ContainerHandler.lastInteractedBlockEntity is ChestBlockEntity) - safeContext.player.currentScreenHandler.containerSlots - else emptyList() + if (ContainerHandler.lastInteractedBlockEntity is ChestBlockEntity) { + mc.player?.currentScreenHandler?.containerSlots ?: emptyList() + } else emptyList() override val description = buildText { diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt index 9c9ff74db..eb8f6f0f3 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt @@ -17,10 +17,11 @@ package com.lambda.interaction.inventory.container.containers +import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen @@ -31,22 +32,19 @@ import net.minecraft.screen.PlayerScreenHandler import net.minecraft.screen.slot.Slot data object CreativeContainer : Container(Rank.Creative) { - context(_: SafeContext) - override val slots: List - get() = emptyList() + override val slots = emptyList() override var stacks = emptyList() override val swapMethodPriority = 11 override val description = buildText { literal("Creative") } - context(safeContext : SafeContext) - override fun InventoryRequest.InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + context(safeContext: SafeContext) + override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { clickCreativeStack(fromHere.stack, toSlot.id) - safeContext.player.currentScreenHandler.slots[toSlot.id].stack = fromHere.stack + safeContext.player.currentScreenHandler.slots.getOrNull(toSlot.id)?.stack = fromHere.stack } - context(safeContext: SafeContext) override fun getSlot(stackSelection: StackSelection) = stackSelection.optimalStack?.let { stack -> Slot( @@ -60,15 +58,12 @@ data object CreativeContainer : Container(Rank.Creative) { ) } - context(safeContext: SafeContext) override fun materialAvailable(selection: StackSelection): Int = - if (safeContext.player.isCreative && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 + if (mc.player?.isCreative == true && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 - context(safeContext: SafeContext) override fun spaceAvailable(selection: StackSelection): Int = - if (safeContext.player.isCreative && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 + if (mc.player?.isCreative == true && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 - context(safeContext: SafeContext) private val correctScreenHandler - get() = safeContext.player.currentScreenHandler is PlayerScreenHandler || safeContext.player.currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler + get() = mc.player?.currentScreenHandler is PlayerScreenHandler || mc.player?.currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt index 4b74135cf..627b31f77 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt @@ -17,8 +17,8 @@ package com.lambda.interaction.inventory.container.containers +import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext -import com.lambda.context.SafeContext import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select @@ -36,12 +36,11 @@ import net.minecraft.item.ItemStack import net.minecraft.item.Items object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { - context(safeContext: SafeContext) override val slots get() = - if (ContainerHandler.lastInteractedBlockEntity is EnderChestBlockEntity) - safeContext.player.currentScreenHandler.containerSlots - else emptyList() + if (ContainerHandler.lastInteractedBlockEntity is EnderChestBlockEntity) { + mc.player?.currentScreenHandler?.containerSlots ?: emptyList() + } else emptyList() override var stacks = emptyList() override val description = buildText { literal("Ender Chest") } @@ -49,14 +48,16 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { context(automatedSafeContext: AutomatedSafeContext) override fun accessThen(exitAfter: Boolean, taskGenerator: TaskGenerator) = Items.ENDER_CHEST - .select() + .select(1) .findSlotsWithMaterial() .firstOrNull()?.let { slot -> PlaceContainerTask(slot, automatedSafeContext).then { pos -> OpenContainerTask(pos, automatedSafeContext).then { taskGenerator.invoke(automatedSafeContext, Unit).thenOrNull { - if (exitAfter) automatedSafeContext.breakAndCollectBlock(pos, lifeMaintenance = false) - else null + if (exitAfter) { + player.closeHandledScreen() + automatedSafeContext.breakAndCollectBlock(pos, lifeMaintenance = false) + } else null } } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt index c2dc8c52c..b5998dbec 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt @@ -18,7 +18,6 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc -import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks @@ -28,9 +27,8 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot object HotbarAndInventoryContainer : Container(Rank.HotbarAndInventory) { - context(safeContext: SafeContext) override val slots: List - get() = safeContext.player.hotbarAndInventorySlots + get() = mc.player?.hotbarAndInventorySlots ?: emptyList() override var stacks: List get() = mc.player?.hotbarAndInventoryStacks ?: emptyList() set(_) {} diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt index f3db002c0..a4e2cd9fd 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.hotbarSlots import com.lambda.util.player.SlotUtils.hotbarStacks import com.lambda.util.text.buildText @@ -28,9 +28,8 @@ import com.lambda.util.text.literal import net.minecraft.screen.slot.Slot object HotbarContainer : Container(Rank.Hotbar) { - context(safeContext: SafeContext) override val slots: List - get() = safeContext.player.hotbarSlots + get() = mc.player?.hotbarSlots ?: emptyList() override var stacks get() = mc.player?.hotbarStacks ?: emptyList() set(_) {} @@ -40,7 +39,7 @@ object HotbarContainer : Container(Rank.Hotbar) { override val description = buildText { literal("Hotbar") } context(safeContext: SafeContext) - override fun InventoryRequest.InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { - swap(toSlot.id, safeContext.player.hotbarSlots.indexOf(fromHere)) + override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + swapWithHotbar(toSlot.id, safeContext.player.hotbarSlots.indexOf(fromHere)) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt index 7cc269548..c54b101e5 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt @@ -18,7 +18,6 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc -import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.inventorySlots import com.lambda.util.player.SlotUtils.inventoryStacks @@ -28,9 +27,8 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot object InventoryContainer : Container(Rank.Inventory) { - context(safeContext: SafeContext) override val slots: List - get() = safeContext.player.inventorySlots + get() = mc.player?.inventorySlots ?: emptyList() override var stacks: List get() = mc.player?.inventoryStacks ?: emptyList() set(_) {} diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt index 839c1fa6d..ecbdff3cf 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.mainHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal @@ -28,9 +28,8 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot object MainHandContainer : Container(Rank.MainHand) { - context(safeContext: SafeContext) override val slots: List - get() = safeContext.player.mainHandSlots + get() = mc.player?.mainHandSlots ?: emptyList() override var stacks: List get() = mc.player?.mainHandStack?.let { listOf(it) } ?: emptyList() set(_) {} @@ -40,7 +39,7 @@ object MainHandContainer : Container(Rank.MainHand) { override val description = buildText { literal("MainHand") } context(safeContext: SafeContext) - override fun InventoryRequest.InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { - swap(toSlot.id, safeContext.player.inventory.selectedSlot) + override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + swapWithHotbar(toSlot.id, safeContext.player.inventory.selectedSlot) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt index 74f9f252a..9746bb349 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.offHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal @@ -28,9 +28,8 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot object OffHandContainer : Container(Rank.OffHand) { - context(safeContext: SafeContext) override val slots: List - get() = safeContext.player.offHandSlots + get() = mc.player?.offHandSlots ?: emptyList() override var stacks: List get() = mc.player?.offHandStack?.let { listOf(it) } ?: emptyList() set(_) {} @@ -40,7 +39,7 @@ object OffHandContainer : Container(Rank.OffHand) { override val description = buildText { literal("OffHand") } context(_: SafeContext) - override fun InventoryRequest.InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { - swap(toSlot.id, 40) + override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + swapWithHotbar(toSlot.id, 40) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt index 1fbe889ec..f33a461a5 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt @@ -18,7 +18,6 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc -import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container import com.lambda.util.player.SlotUtils.allSlots import com.lambda.util.player.SlotUtils.allStacks @@ -29,9 +28,8 @@ import net.minecraft.screen.slot.Slot @Suppress("unused") object PlayerContainer : Container(Rank.Player) { - context(safeContext: SafeContext) override val slots: List - get() = safeContext.player.allSlots + get() = mc.player?.allSlots ?: emptyList() override var stacks: List get() = mc.player?.allStacks ?: emptyList() set(_) {} diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt index 8cb68f275..c3faed9fc 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt @@ -17,6 +17,7 @@ package com.lambda.interaction.inventory.container.containers +import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.interaction.handlers.ContainerHandler @@ -41,11 +42,10 @@ data class ShulkerBoxContainer( val containedIn: Container, val shulkerSlot: Slot, ) : Container(Rank.ShulkerBox), ExternalContainer { - context(safeContext: SafeContext) override val slots get(): List = if (ContainerHandler.lastInteractedBlockEntity is ShulkerBoxBlockEntity) - safeContext.player.currentScreenHandler.containerSlots + mc.player?.currentScreenHandler?.containerSlots ?: emptyList() else emptyList() override val description = diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt index 6c23b7d5b..1dc78c499 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt @@ -17,7 +17,6 @@ package com.lambda.interaction.inventory.container.containers -import com.lambda.context.SafeContext import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container import com.lambda.util.math.roundedBlockPos @@ -32,7 +31,6 @@ data class StashContainer( val chests: Set, val pos: Box, ) : Container(Rank.Stash) { - context(_: SafeContext) override val slots: List get() = chests.flatMap { it.slots } override var stacks: List @@ -44,7 +42,6 @@ data class StashContainer( highlighted(pos.center.roundedBlockPos.toShortString()) } - context(_: SafeContext) override fun materialAvailable(selection: StackSelection): Int = chests.sumOf { it.materialAvailable(selection) diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt index daae64b81..d8f35e129 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt @@ -72,6 +72,7 @@ import com.lambda.interaction.managers.breaking.BreakManager.updateBreakProgress import com.lambda.interaction.managers.breaking.BreakManager.updatePreProcessing import com.lambda.interaction.managers.breaking.SwapInfo.Companion.getSwapInfo import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.managers.interacting.InteractManager import com.lambda.interaction.managers.rotating.RotationRequest import com.lambda.threading.runGameScheduled @@ -447,12 +448,10 @@ object BreakManager : Manager( val serverSwapTicks = max(first.breakConfig.serverSwapTicks, last.breakConfig.serverSwapTicks) hotbarRequest = with(last) { - HotbarRequest( - context.hotbarIndex, - request, - request.hotbarConfig.keepTicks.coerceAtLeast(minKeepTicks), - request.hotbarConfig.swapPause.coerceAtLeast(serverSwapTicks - 1) - ).submit(false) + request.hotbarRequest(context.hotbarIndex) { + keepTicks(request.hotbarConfig.keepTicks.coerceAtLeast(minKeepTicks)) + swapPause(request.hotbarConfig.swapPause.coerceAtLeast(serverSwapTicks - 1)) + }.submit(false) } return @@ -474,7 +473,7 @@ object BreakManager : Manager( breaks.forEach { ctx -> if (breaksThisTick >= maxBreaksThisTick) return false - if (!currentStackSelection.filterStack(player.inventory.getStack(ctx.hotbarIndex))) return@forEach + if (!currentStackSelection.matches(player.inventory.getStack(ctx.hotbarIndex))) return@forEach initNewBreak(ctx, request) ?: return false breaks.remove(ctx) diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt index 312e473d5..2e160c1bb 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt @@ -28,7 +28,6 @@ import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.managers.Request -import com.lambda.interaction.managers.breaking.BreakRequest.BreakRequestMarker import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.isEmpty @@ -67,20 +66,21 @@ data class BreakRequest( override val done: Boolean get() = runSafe { contexts.all { blockState(it.blockPos).isEmpty } } == true - @DslMarker - annotation class BreakRequestMarker - @BreakRequestMarker override fun submit(queueIfMismatchedStage: Boolean) = BreakManager.request(this, queueIfMismatchedStage) companion object { var requestCount = 0 + private set } } +@DslMarker +annotation class BreakRequestMarker + @BreakRequestMarker -class BreakRequestBuilder( +class BreakRequestBuilder private constructor( private val contexts: Collection, private val pendingInteractions: MutableCollection, private val nowOrNothing: Boolean, @@ -122,7 +122,6 @@ class BreakRequestBuilder( onReBreak = callback } - @BreakRequestMarker private fun build() = BreakRequest( contexts, @@ -139,7 +138,6 @@ class BreakRequestBuilder( ) companion object { - @BreakRequestMarker @JvmName("breakRequest1") fun AutomatedSafeContext.breakRequest( positions: Collection, @@ -151,7 +149,6 @@ class BreakRequestBuilder( .simulate() .breakRequest(pendingInteractions, nowOrNothing, builder) - @BreakRequestMarker @JvmName("breakRequest2") context(automated: Automated) fun Collection.breakRequest( @@ -161,7 +158,6 @@ class BreakRequestBuilder( ) = asSequence() .breakRequest(pendingInteractions, nowOrNothing, builder) - @BreakRequestMarker @JvmName("breakRequest3") context(automated: Automated) fun Sequence.breakRequest( @@ -176,7 +172,6 @@ class BreakRequestBuilder( .takeIf { it.isNotEmpty() } ?.let { automated.breakRequest(it, pendingInteractions, nowOrNothing, builder) } - @BreakRequestMarker @JvmName("breakRequest4") fun Automated.breakRequest( contexts: Collection, diff --git a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarManager.kt b/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarManager.kt index ab53fe97c..3feb3275c 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarManager.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarManager.kt @@ -41,11 +41,7 @@ import net.minecraft.item.ItemStack */ object HotbarManager : Manager( 1, - onOpen = { - if (activeRequest != null) { - setActiveSlot() - } - }, + onOpen = { if (activeRequest != null) setActiveSlot() }, onClose = { checkResetSwap() } ) { private var activeRequest: HotbarRequest? = null diff --git a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarRequest.kt index 331086e9e..f16a1d6f3 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarRequest.kt @@ -22,10 +22,10 @@ import com.lambda.interaction.managers.Request class HotbarRequest( val slot: Int, - automated: Automated, var keepTicks: Int = automated.hotbarConfig.keepTicks, val swapPause: Int = automated.hotbarConfig.swapPause, - override val nowOrNothing: Boolean = true + override val nowOrNothing: Boolean = true, + automated: Automated ) : Request(), Automated by automated { override val requestId = ++requestCount override val tickStageMask get() = hotbarConfig.tickStageMask @@ -36,10 +36,41 @@ class HotbarRequest( override val done: Boolean get() = slot == HotbarManager.activeSlot && swapPauseAge >= swapPause + @HotbarRequestMarker override fun submit(queueIfMismatchedStage: Boolean) = HotbarManager.request(this, queueIfMismatchedStage) companion object { var requestCount = 0 + private set } } + +@DslMarker +private annotation class HotbarRequestMarker + +@Suppress("unused") +@HotbarRequestMarker +class HotbarRequestBuilder private constructor( + private val slot: Int, + private val nowOrNothing: Boolean, + private val automated: Automated, +) { + private var keepTicks: Int = automated.hotbarConfig.keepTicks + private var swapPause: Int = automated.hotbarConfig.swapPause + + fun keepTicks(keepTicks: Int) { + this.keepTicks = keepTicks + } + + fun swapPause(swapPause: Int) { + this.swapPause = swapPause + } + + private fun build() = HotbarRequest(slot, keepTicks, swapPause, nowOrNothing, automated) + + companion object { + fun Automated.hotbarRequest(slot: Int, nowOrNothing: Boolean = false, builder: (HotbarRequestBuilder.() -> Unit)? = null) = + HotbarRequestBuilder(slot, nowOrNothing, this).apply { builder?.invoke(this) }.build() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt index b016527b6..56fa03e4e 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt @@ -38,13 +38,13 @@ import com.lambda.interaction.managers.Manager import com.lambda.interaction.managers.ManagerUtils.isPosBlocked import com.lambda.interaction.managers.PositionBlocking import com.lambda.interaction.managers.breaking.BreakManager -import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.managers.interacting.InteractManager.activeRequest import com.lambda.interaction.managers.interacting.InteractManager.maxInteractionsThisTick import com.lambda.interaction.managers.interacting.InteractManager.populateFrom import com.lambda.interaction.managers.interacting.InteractManager.potentialInteractions import com.lambda.interaction.managers.interacting.InteractManager.processRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.modules.world.AutoSign.signWriteDelay import com.lambda.threading.runConcurrent import com.lambda.threading.runSafeAutomated @@ -162,10 +162,7 @@ object InteractManager : Manager( if (!canInteractThisTick()) break val firstInteraction = potentialInteractions.first() if (player.inventory.selectedSlot != firstInteraction.hotbarIndex) { - val hotbarRequest = HotbarRequest( - firstInteraction.hotbarIndex, - this - ).submit(queueIfMismatchedStage = false) + val hotbarRequest = hotbarRequest(firstInteraction.hotbarIndex).submit(false) if (!hotbarRequest.done) break } var interactResult: InteractResult? = null diff --git a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt index b5baa4a98..3132cda20 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt @@ -25,7 +25,6 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.managers.Request -import com.lambda.interaction.managers.interacting.InteractRequest.PlaceRequestMarker import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.matches @@ -46,20 +45,21 @@ data class InteractRequest( contexts.all { it.expectedState.matches(blockState(it.blockPos)) } } == true - @DslMarker - annotation class PlaceRequestMarker - - @PlaceRequestMarker + @InteractRequestMarker override fun submit(queueIfMismatchedStage: Boolean) = InteractManager.request(this, queueIfMismatchedStage) companion object { var requestCount = 0 + private set } } -@PlaceRequestMarker -class PlaceRequestBuilder( +@DslMarker +annotation class InteractRequestMarker + +@InteractRequestMarker +class PlaceRequestBuilder private constructor( private val contexts: Collection, private val pendingInteractions: MutableCollection, private val nowOrNothing: Boolean, @@ -71,7 +71,6 @@ class PlaceRequestBuilder( onPlace = callback } - @PlaceRequestMarker private fun build() = InteractRequest( contexts, diff --git a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryRequest.kt index 277eb2faf..5e3c84e92 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryRequest.kt @@ -39,7 +39,7 @@ import net.minecraft.util.math.Direction * @property settleForLess A flag indicating whether to settle for partial completion of the request. * @property mustPerform A flag indicating whether the request must be performed regardless of conditions as long as the tick stage is valid. */ -class InventoryRequest private constructor( +class InventoryRequest( val actions: List, val settleForLess: Boolean, val mustPerform: Boolean, @@ -55,128 +55,124 @@ class InventoryRequest private constructor( override fun submit(queueIfMismatchedStage: Boolean) = InventoryManager.request(this, queueIfMismatchedStage) - @DslMarker - private annotation class InvRequestDsl + companion object { + var requestCount = 0 + private set + } +} - @Suppress("unused") - @InvRequestDsl - class InvRequestBuilder(val settleForLess: Boolean, val mustPerform: Boolean) { - val actions = mutableListOf() - var onComplete: (SafeContext.() -> Unit)? = null - - fun click(slotId: Int, button: Int, actionType: SlotActionType) { - InventoryAction.Inventory { clickSlot(slotId, button, actionType) }.addToActions() - } - - fun resyncInventory() { - InventoryAction.Inventory { - connection.sendPacket { - val sh = player.currentScreenHandler - ClickSlotC2SPacket( - sh.syncId, - -1, -1, 0, - SlotActionType.CLONE, - Int2ObjectOpenHashMap(), - ItemStackHash.fromItemStack(sh.cursorStack, connection.componentHasher) - ) - } - }.addToActions() - } - - fun pickFromInventory(slotId: Int) { - InventoryAction.Inventory { - clickSlot(slotId, player.inventory.selectedSlot, SlotActionType.SWAP) - }.addToActions() - } - - fun dropItemInHand(entireStack: Boolean = true) { - InventoryAction.Inventory { player.dropSelectedItem(entireStack) }.addToActions() - } - - fun swapHands() { - InventoryAction.Player { - val offhandStack = player.getStackInHand(Hand.OFF_HAND) - player.setStackInHand(Hand.OFF_HAND, player.getStackInHand(Hand.MAIN_HAND)) - player.setStackInHand(Hand.MAIN_HAND, offhandStack) - connection.sendPacket { - PlayerActionC2SPacket( - PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, - BlockPos.ORIGIN, - Direction.DOWN - ) - } - }.addToActions() - } - - fun clickCreativeStack(stack: ItemStack, slotId: Int) { - InventoryAction.Inventory { interaction.clickCreativeStack(stack, slotId) }.addToActions() - } - - fun pickup(slotId: Int, button: Int = 0) = click(slotId, button, SlotActionType.PICKUP) - - // Quick move action (Shift-click) - fun quickMove(slotId: Int) = click(slotId, 0, SlotActionType.QUICK_MOVE) - - fun swap(slotId: Int, hotbarSlot: Int) = click(slotId, hotbarSlot, SlotActionType.SWAP) - - // Clone action (Creative mode) - fun clone(slotId: Int) = click(slotId, 2, SlotActionType.CLONE) - - // Throw stack or single item - fun throwStack(slotId: Int) = click(slotId, 1, SlotActionType.THROW) - - fun throwSingle(slotId: Int) = click(slotId, 0, SlotActionType.THROW) - - // Quick craft action - fun quickCraftStart(slotId: Int) = click(slotId, 0, SlotActionType.QUICK_CRAFT) - - fun quickCraftDrag(slotId: Int) = click(slotId, 1, SlotActionType.QUICK_CRAFT) - - fun quickCraftEnd(slotId: Int) = click(slotId, 2, SlotActionType.QUICK_CRAFT) - - // Pickup all items (double-click) - fun pickupAll(slotId: Int) = click(slotId, 0, SlotActionType.PICKUP_ALL) - - // Helper function: Move items from one slot to another - fun moveSlot(fromSlotId: Int, toSlotId: Int, button: Int = 0) { - pickup(fromSlotId, button) - pickup(toSlotId, button) - } - - // Helper function: Split a stack into two - fun splitStack(slotId: Int, targetSlotId: Int) { - pickup(slotId, 1) // Pickup half the stack - pickup(targetSlotId, 0) // Place it in the target slot - } - - // Helper function: Merge stacks - fun mergeStacks(sourceSlotId: Int, targetSlotId: Int) { - pickup(sourceSlotId, 0) - pickup(targetSlotId, 0) - } - - fun action(action: SafeContext.() -> Unit) { - InventoryAction.Other(action).addToActions() - } - - fun onComplete(callback: SafeContext.() -> Unit) { - onComplete = callback - } - - private fun InventoryAction.addToActions() { - actions.add(this) - } +@DslMarker +annotation class InvRequestDsl + +@Suppress("unused") +@InvRequestDsl +class InvRequestBuilder private constructor( + private val settleForLess: Boolean, + private val mustPerform: Boolean +) { + private val actions = mutableListOf() + private var onComplete: (SafeContext.() -> Unit)? = null + + fun click(slotId: Int, button: Int, actionType: SlotActionType) { + InventoryAction.Inventory { clickSlot(slotId, button, actionType) }.addToActions() } - companion object { - var requestCount = 0 + fun resyncInventory() { + InventoryAction.Inventory { + connection.sendPacket { + val sh = player.currentScreenHandler + ClickSlotC2SPacket( + sh.syncId, + -1, -1, 0, + SlotActionType.CLONE, + Int2ObjectOpenHashMap(), + ItemStackHash.fromItemStack(sh.cursorStack, connection.componentHasher) + ) + } + }.addToActions() + } + + fun pickFromInventory(slotId: Int) { + InventoryAction.Inventory { + clickSlot(slotId, player.inventory.selectedSlot, SlotActionType.SWAP) + }.addToActions() + } + + fun dropItemInHand(entireStack: Boolean = true) { + InventoryAction.Inventory { player.dropSelectedItem(entireStack) }.addToActions() + } + + fun swapHands() { + InventoryAction.Player { + val offhandStack = player.getStackInHand(Hand.OFF_HAND) + player.setStackInHand(Hand.OFF_HAND, player.getStackInHand(Hand.MAIN_HAND)) + player.setStackInHand(Hand.MAIN_HAND, offhandStack) + connection.sendPacket { + PlayerActionC2SPacket( + PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, + BlockPos.ORIGIN, + Direction.DOWN + ) + } + }.addToActions() + } + + fun clickCreativeStack(stack: ItemStack, slotId: Int) { + InventoryAction.Inventory { interaction.clickCreativeStack(stack, slotId) }.addToActions() + } + + fun pickup(slotId: Int, button: Int = 0) = click(slotId, button, SlotActionType.PICKUP) + + fun quickMove(slotId: Int) = click(slotId, 0, SlotActionType.QUICK_MOVE) + + fun swapWithHotbar(slotId: Int, hotbarSlot: Int) = click(slotId, hotbarSlot, SlotActionType.SWAP) + + fun clone(slotId: Int) = click(slotId, 2, SlotActionType.CLONE) - @InvRequestDsl + fun throwStack(slotId: Int) = click(slotId, 1, SlotActionType.THROW) + + fun throwSingle(slotId: Int) = click(slotId, 0, SlotActionType.THROW) + + fun quickCraftStart(slotId: Int) = click(slotId, 0, SlotActionType.QUICK_CRAFT) + + fun quickCraftDrag(slotId: Int) = click(slotId, 1, SlotActionType.QUICK_CRAFT) + + fun quickCraftEnd(slotId: Int) = click(slotId, 2, SlotActionType.QUICK_CRAFT) + + fun pickupAll(slotId: Int) = click(slotId, 0, SlotActionType.PICKUP_ALL) + + fun moveSlot(fromSlotId: Int, toSlotId: Int, button: Int = 0) { + pickup(fromSlotId, button) + pickup(toSlotId, button) + } + + fun splitStack(slotId: Int, targetSlotId: Int) { + pickup(slotId, 1) + pickup(targetSlotId, 0) + } + + fun mergeStacks(sourceSlotId: Int, targetSlotId: Int) { + pickup(sourceSlotId, 0) + pickup(targetSlotId, 0) + } + + fun action(action: SafeContext.() -> Unit) { + InventoryAction.Other(action).addToActions() + } + + fun onComplete(callback: SafeContext.() -> Unit) { + onComplete = callback + } + + private fun InventoryAction.addToActions() { + actions.add(this) + } + + context(automated: Automated) + private fun build() = InventoryRequest(actions, settleForLess, mustPerform, automated, onComplete = onComplete) + + companion object { fun Automated.inventoryRequest(settleForLess: Boolean = false, mustPerform: Boolean = false, builder: InvRequestBuilder.() -> Unit) = InvRequestBuilder(settleForLess, mustPerform).apply(builder).build() - - @InvRequestDsl - context(automated: Automated) - private fun InvRequestBuilder.build() = InventoryRequest(actions, settleForLess, mustPerform, automated, onComplete = onComplete) } } diff --git a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt b/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt index 46b385b1e..518c98465 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt @@ -21,14 +21,12 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.managers.Request -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.requestCount import com.lambda.interaction.managers.rotating.IRotationRequest.Full import com.lambda.interaction.managers.rotating.IRotationRequest.Pitch import com.lambda.interaction.managers.rotating.IRotationRequest.Yaw import com.lambda.interaction.managers.rotating.Rotation.Companion.dist import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation import com.lambda.interaction.managers.rotating.Rotation.Companion.wrap -import com.lambda.interaction.managers.rotating.RotationRequest.RotationRequestMarker import com.lambda.threading.runSafe import com.lambda.util.collections.UpdatableLazy import com.lambda.util.collections.updatableLazy @@ -42,14 +40,19 @@ abstract class RotationRequest(automated: Automated) : Request(), Automated by a abstract infix fun dist(rotation: Rotation): Double - @DslMarker - annotation class RotationRequestMarker - @RotationRequestMarker override fun submit(queueIfMismatchedStage: Boolean) = RotationManager.request(this, queueIfMismatchedStage) + + companion object { + var requestCount = 0 + private set + } } +@DslMarker +annotation class RotationRequestMarker + interface IRotationRequest : Automated { var keepTicks: Int var decayTicks: Int @@ -139,14 +142,10 @@ interface IRotationRequest : Automated { interface YawRot : IRotationRequest { val yaw: UpdatableLazy } interface PitchRot : IRotationRequest { val pitch: UpdatableLazy } interface FullRot : YawRot, PitchRot { val rotation: UpdatableLazy } - - companion object { - var requestCount = 0 - } } @RotationRequestMarker -class RotationRequestBuilder { +class RotationRequestBuilder private constructor() { private var pitchBuilder: (SafeContext.() -> Double)? = null private var yawBuilder: (SafeContext.() -> Double)? = null private var rotationBuilder: (SafeContext.() -> Rotation)? = null diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt index dc827d9be..aa0a248a2 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt @@ -27,7 +27,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.ArmorContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.EnchantmentUtils.getEnchantment diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index 348045061..3ca0ee386 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -25,7 +25,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.FriendHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.combat.CombatUtils.hasDeadlyCrystal @@ -66,7 +66,7 @@ object AutoTotem : Module( if ((!ignoreWhenHolding || !player.isHolding(Items.TOTEM_OF_UNDYING)) && player.offHandStack.item != Items.TOTEM_OF_UNDYING) { Items.TOTEM_OF_UNDYING.select() - .filterSlots(player.currentScreenHandler.slots) + .filter(player.currentScreenHandler.slots) .takeIf { it.isNotEmpty() } ?.let { totems -> val cursor = player.currentScreenHandler.cursorStack @@ -75,7 +75,7 @@ object AutoTotem : Module( inventoryRequest { targetSlot?.let { pickup(it.id, 0) } - swap(totems.first().id, 40) + swapWithHotbar(totems.first().id, 40) }.submit() } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index f5b071e0b..d20b8b8a8 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -31,7 +31,7 @@ import com.lambda.interaction.handlers.ContainerHandler.transfer import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer -import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo import com.lambda.interaction.managers.rotating.RotationManager import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest @@ -486,16 +486,16 @@ object CrystalAura : Module( (swapHand == Hand.OFF_HAND && player.offHandStack.item != selection.item) ) runSafeAutomated { if (!swap) return@runSafe - var crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.filterStack(it) } + var crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.matches(it) } if (crystalSlot < 0) { val swapTo = when (swapHand) { Hand.MAIN_HAND -> HotbarContainer Hand.OFF_HAND -> OffHandContainer } if (!selection.transfer(swapTo)) return@runSafe - crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.filterStack(it) } + crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.matches(it) } } - if (!HotbarRequest(crystalSlot, this).submit().done) return@runSafe + if (!hotbarRequest(crystalSlot).submit().done) return@runSafe } placeTimer.runSafeIfPassed(placeDelay.milliseconds) { diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index bc64a3c70..8ed274c82 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -30,7 +30,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag @@ -130,7 +130,7 @@ object KillAura : Module( selection.bestMatch(HotbarContainer.stacks)?.let { bestStack -> val slotId = HotbarContainer.stacks.indexOf(bestStack) - if (!HotbarRequest(slotId, this@KillAura, nowOrNothing = false).submit().done) return@listen + if (!hotbarRequest(slotId).submit().done) return@listen } } diff --git a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt index a475f0c58..17a70165e 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt @@ -22,7 +22,7 @@ import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomat import com.lambda.config.withEdits import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.CommunicationUtils.info @@ -39,7 +39,7 @@ object SilentSwap : Module( } listen { - if (!HotbarRequest(0, this@SilentSwap).submit().done) { + if (!hotbarRequest(0).submit().done) { it.cancel() return@listen } diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 35bec0adf..05118f58b 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -33,8 +33,9 @@ import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.managers.hotbar.HotbarRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe @@ -85,7 +86,7 @@ object BetterFirework : Module( val ClientPlayerEntity.hasFireworks: Boolean get() = Items.FIREWORK_ROCKET.select() - .filterStacks(HotbarAndInventoryContainer.stacks) + .filter(HotbarAndInventoryContainer.stacks) .isNotEmpty() || offHandStack.item == Items.FIREWORK_ROCKET context(_: SafeContext) @@ -156,39 +157,35 @@ object BetterFirework : Module( * Return true if a firework has been used */ fun SafeContext.startFirework(inventory: Boolean) { - val stack = selectStack(1) { isItem(Items.FIREWORK_ROCKET) } - - stack.bestMatch(HotbarContainer.stacks) - ?.let { - val request = HotbarRequest(HotbarContainer.stacks.indexOf(it), this@BetterFirework, keepTicks = 0) - .submit(queueIfMismatchedStage = false) - if (request.done) { - interaction.interactItem(player, Hand.MAIN_HAND) - sendSwing() - } - return - } + val selection = Items.FIREWORK_ROCKET.select(1) + + val hotbarMatch = selection.bestMatch(HotbarContainer.slots) + if (hotbarMatch != null) { + swapAndFirework(hotbarMatch.index) + return + } if (!inventory) return - stack.bestMatch(HotbarContainer.stacks) - ?.let { - val swapSlotId = HotbarAndInventoryContainer.stacks.indexOf(it) - val hotbarSlotToSwapWith = HotbarContainer.stacks.find { slot -> slot.isEmpty }?.let { slot -> HotbarContainer.stacks.indexOf(slot) } ?: 8 - - inventoryRequest { - swap(swapSlotId, hotbarSlotToSwapWith) - action { - val request = HotbarRequest(hotbarSlotToSwapWith, this@BetterFirework, keepTicks = 0, nowOrNothing = true) - .submit(queueIfMismatchedStage = false) - if (request.done) { - interaction.interactItem(player, Hand.MAIN_HAND) - sendSwing() - } - } - swap(swapSlotId, hotbarSlotToSwapWith) - }.submit() - } + val inventoryMatch = selection.bestMatch(InventoryContainer.slots) ?: return + val hotbarSlot = selectStack { isEmpty() }.bestMatch(HotbarContainer.slots)?.index ?: 8 + + inventoryRequest { + swapWithHotbar(inventoryMatch.id, hotbarSlot) + action { swapAndFirework(hotbarSlot) } + swapWithHotbar(inventoryMatch.id, hotbarSlot) + }.submit() + } + + private fun SafeContext.swapAndFirework(hotbarSlot: Int) { + val request = + hotbarRequest(hotbarSlot, true) { + keepTicks(0) + }.submit(false) + if (request.done) { + interaction.interactItem(player, Hand.MAIN_HAND) + sendSwing() + } } enum class TakeoffState { diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt index 640ef95e7..edc0e2bc0 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt @@ -27,10 +27,10 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handlers.GlideHandler.ELYTRA_SELECTION import com.lambda.interaction.inventory.container.containers.ArmorContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.interaction.managers.inventory.InventoryManager -import com.lambda.interaction.managers.inventory.InventoryRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFly.fakeFly import com.lambda.threading.runSafe @@ -96,15 +96,13 @@ abstract class ElytraFlyMode( val chestSlot = ArmorContainer.slots.getOrNull(1) ?: return false if (elytraInHotbar) { - val hotbarRequest = HotbarRequest( - elytraSlot.index, - ElytraFly, - keepTicks = 0, - nowOrNothing = true - ).submit() + val hotbarRequest = + hotbarRequest(elytraSlot.index) { + keepTicks(0) + }.submit() if (!hotbarRequest.done) return false } - fun InventoryRequest.InvRequestBuilder.swapChest() { + fun InvRequestBuilder.swapChest() { if (elytraInHotbar) { interaction.interactItem(player, Hand.MAIN_HAND) InventoryManager.indexInventoryChanges() @@ -125,8 +123,7 @@ abstract class ElytraFlyMode( open fun interrupt() {} - fun SafeContext.findElytra(): Slot? = - ELYTRA_SELECTION.filterSlots(HotbarAndInventoryContainer.slots).minByOrNull { it.index } + fun findElytra(): Slot? = ELYTRA_SELECTION.filter(HotbarAndInventoryContainer.slots).minByOrNull { it.index } protected fun SafeContext.startFly() { player.setFlag(Entity.GLIDING_FLAG_INDEX, true) diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt index 22b8e3048..7c3875b0b 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt @@ -121,11 +121,22 @@ class GrimControlElytraFly( val rot = RotationManager.activeRotation val flipFlop = rotFlipFlop.toFloat() * 0.0001f rotFlipFlop = !rotFlipFlop - event.packet = PlayerMoveC2SPacket.Full(player.pos, rot.yawF + flipFlop, rot.pitchF, player.isOnGround, player.horizontalCollision) + event.packet = + PlayerMoveC2SPacket.Full( + player.pos, + rot.yawF + flipFlop, + rot.pitchF, + player.isOnGround, + player.horizontalCollision + ) } listen { event -> - if (event.packet !is PlayerMoveC2SPacket || !player.isGliding || flipFlopMode.isFlipFlopping(hasFirework) || moving) return@listen + if (event.packet !is PlayerMoveC2SPacket || + !player.isGliding || + flipFlopMode.isFlipFlopping(hasFirework) || + moving + ) return@listen if (stillTickTimer.hasSurpassed(packetGap)) { stillTickTimer.reset() return@listen diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt index b912ec751..407de5e5d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt @@ -24,7 +24,7 @@ import com.lambda.interaction.handlers.GlideHandler.manuallySwapped import com.lambda.interaction.handlers.GlideHandler.swapped import com.lambda.interaction.inventory.container.containers.ArmorContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.tag.ModuleTag @@ -44,24 +44,23 @@ object AutoElytraSwap : Module( onDisable { restore() } } - context(safeContext: SafeContext) fun manualSwap(elytra: Boolean): Boolean { val swapSlot = HotbarAndInventoryContainer.slots.let { slots -> - if (elytra) ELYTRA_SELECTION.filterSlots(slots) - else CHESTPLATE_SELECTION.filterSlots(slots) + if (elytra) ELYTRA_SELECTION.filter(slots) + else CHESTPLATE_SELECTION.filter(slots) }.minByOrNull { it.index } ?: run { AutoElytraSwap.warn("The required armor piece was not found for AutoElytraSwap to work.") return false } - return safeContext.swapWithChestplate(swapSlot) + return swapWithChestplate(swapSlot) } - private fun SafeContext.swapWithChestplate(swapSlot: Slot): Boolean { + private fun swapWithChestplate(swapSlot: Slot): Boolean { val chestplateSlot = ArmorContainer.slots.getOrNull(1) ?: return false return AutoElytraSwap.inventoryRequest { - if (swapSlot.index in 0..8) swap(chestplateSlot.id, swapSlot.index) + if (swapSlot.index in 0..8) swapWithHotbar(chestplateSlot.id, swapSlot.index) else { moveSlot(swapSlot.id, chestplateSlot.id) if (!chestplateSlot.stack.isEmpty) pickup(swapSlot.id) diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt index c432a001d..ba421be95 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.player import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.TickTimer diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index 664e7363d..3a2ba080c 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -26,7 +26,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.item.ItemStackUtils.slotId diff --git a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt index a9984aa86..6df4bcb7d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt @@ -25,7 +25,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.EnchantmentUtils.forEachEnchantment diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 7335d5399..6e2970b72 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -39,8 +39,8 @@ import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.managers.hotbar.HotbarRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.modules.world.AutoPortal.PosHandler.currAnchorPos import com.lambda.module.modules.world.AutoPortal.PosHandler.obiPositions @@ -326,19 +326,18 @@ object AutoPortal : Module( val sel = selectStack(1) { isItem() } - val hotbarStack = sel.filterSlots(HotbarContainer.slots).firstOrNull() + val hotbarStack = sel.filter(HotbarContainer.slots).firstOrNull() if (hotbarStack != null) { - val request = HotbarRequest( - hotbarStack.index, - this@AutoPortal, - keepTicks = 0 - ).submit(queueIfMismatchedStage = false) + val request = + hotbarRequest(hotbarStack.index) { + keepTicks(0) + }.submit(false) if (request.done) block() return } val invSlot = - if (inventory) sel.filterSlots(HotbarAndInventoryContainer.slots).firstOrNull() + if (inventory) sel.filter(HotbarAndInventoryContainer.slots).firstOrNull() else null if (invSlot == null) { failure("No Flint and Steel!") @@ -350,19 +349,15 @@ object AutoPortal : Module( }?.index ?: 8 inventoryRequest { - swap(invSlot.id, hotbarSlotToSwapWith) + swapWithHotbar(invSlot.id, hotbarSlotToSwapWith) action { - val request = HotbarRequest( - hotbarSlotToSwapWith, - this@AutoPortal, - keepTicks = 0, - nowOrNothing = true - ).submit(queueIfMismatchedStage = false) - if (request.done) { - block() - } + val request = + hotbarRequest(hotbarSlotToSwapWith) { + keepTicks(0) + }.submit(false) + if (request.done) block() } - swap(invSlot.id, hotbarSlotToSwapWith) + swapWithHotbar(invSlot.id, hotbarSlotToSwapWith) }.submit() } } diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index 07fc716de..1708ba5c4 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -86,8 +86,8 @@ object Scaffold : Module( stack.blockItem.let { blockItem -> blockItem != null && blockItem.block !in blacklistedBlocks } } } - val stack = player.mainHandStack.takeIf { selection.filterStack(it) } - ?: selection.filterStacks(HotbarContainer.stacks).firstOrNull() ?: return@listen + val stack = player.mainHandStack.takeIf { selection.matches(it) } + ?: selection.filter(HotbarContainer.stacks).firstOrNull() ?: return@listen val playerSupport = player.blockPos.down() val alreadySupported = blockState(playerSupport).hasSolidTopSurface(world, playerSupport, player) if (alreadySupported) return@listen diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index cb38bb2a3..814e556bb 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -46,8 +46,8 @@ import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryC import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer -import com.lambda.interaction.managers.hotbar.HotbarRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.interaction.managers.rotating.Rotation import com.lambda.interaction.managers.rotating.Rotation.Companion.dist import com.lambda.interaction.managers.rotating.RotationManager @@ -639,7 +639,7 @@ object StashMover : Module( inventoryRequest { quickMove(firstSlot.id) }.submit() return } else if (player.offHandStack.isEmpty) { - inventoryRequest { swap(firstSlot.id, 40) }.submit() + inventoryRequest { swapWithHotbar(firstSlot.id, 40) }.submit() return } failWithLog("No free slots for an ender pearl!") @@ -683,7 +683,7 @@ object StashMover : Module( if (player.mainHandStack.item != Items.ENDER_PEARL) { val hotbarSlot = HotbarContainer.slots.firstOrNull { it.stack.item === Items.ENDER_PEARL } if (hotbarSlot != null) { - val hotbarRequest = HotbarRequest(hotbarSlot.index, StashMover, nowOrNothing = false).submit() + val hotbarRequest = hotbarRequest(hotbarSlot.index).submit() if (!hotbarRequest.done) return } else { val inventorySlot = player.allSlots.firstOrNull { it.stack.item === Items.ENDER_PEARL } @@ -691,7 +691,7 @@ object StashMover : Module( failWithLog("No pearl in inventory!") return } - inventoryRequest { swap(inventorySlot.id, 0) }.submit() + inventoryRequest { swapWithHotbar(inventorySlot.id, 0) }.submit() return } } diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index 044ecd6bf..31888b729 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -50,7 +50,7 @@ import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.interaction.managers.interacting.PlaceRequestBuilder.Companion.interactRequest -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.modules.client.Client import com.lambda.task.Task import com.lambda.task.tasks.EatTask.Companion.eat diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index e71aa3f42..c06883dee 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -25,8 +25,8 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.inventory.InventoryRequest.Companion.inventoryRequest +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated @@ -39,40 +39,30 @@ class ContainerTransferTask( ) : Task(), Automated by automated { override val name = "Transferring $stackSelection from $fromContainer to $toContainer" - private var delegateTask: Task<*>? = null - init { listen { - if (delegateTask?.isCompleted == true) { - success() - return@listen - } runSafeAutomated { - val fromExternal = fromContainer as? ExternalContainer val slots = fromContainer.slots val toSlots = toContainer.slots - fromExternal.takeIf { slots.isEmpty() }?.let { fromExternal -> + if (fromContainer is ExternalContainer && slots.isEmpty()) { if (toContainer is ExternalContainer && toSlots.isEmpty()) { - fromContainer.transferByTask(stackSelection, InventoryContainer).finally { - fromContainer = InventoryContainer - }.execute(this@ContainerTransferTask) - return@listen - } - delegateTask = fromExternal.accessThen { - fromContainer.transferByTask(stackSelection, toContainer) - }?.execute(this@ContainerTransferTask) ?: run { - checkFail() + fromContainer + .transferByTask(stackSelection, HotbarAndInventoryContainer) + .finally { fromContainer = HotbarAndInventoryContainer } + .execute(this@ContainerTransferTask) return@listen } return@listen } if (toContainer is ExternalContainer && toSlots.isEmpty()) { - delegateTask = toContainer.accessThen { - fromContainer.transferByTask(stackSelection, toContainer) - }?.execute(this@ContainerTransferTask) ?: run { - checkFail() - return@listen - } + toContainer + .accessThen { + fromContainer.transferByTask(stackSelection, toContainer) + }?.finally { success() } + ?.execute(this@ContainerTransferTask) ?: run { + checkFail() + return@listen + } return@listen } @@ -97,9 +87,10 @@ class ContainerTransferTask( private fun checkFail(): Boolean = - failIfNoMaterial.also { + if (failIfNoMaterial) { failure(NoMaterialAccessException(stackSelection)) - } + true + } else false private class NoMaterialAccessException(stackSelection: StackSelection) : IllegalStateException("Unable to access $stackSelection.") } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index 3ab6bf685..d09163dc6 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -25,7 +25,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.hotbar.HotbarRequest +import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated import net.minecraft.item.ItemStack @@ -57,17 +57,15 @@ class EatTask @Ta5kBuilder constructor( } val foodFinder = reason.selector() - val hotbarSlot = foodFinder.filterSlots(HotbarContainer.slots).firstOrNull() + val hotbarSlot = foodFinder.filter(HotbarContainer.slots).firstOrNull() if (hotbarSlot != null) { - val request = HotbarRequest( - hotbarSlot.index, - this@EatTask, - keepTicks = hotbarConfig.keepTicks.coerceAtLeast(1), - nowOrNothing = false - ).submit() + val request = + hotbarRequest(hotbarSlot.index) { + keepTicks(hotbarConfig.keepTicks.coerceAtLeast(1)) + }.submit() if (!request.done) return@listen } else { - val inventorySlot = foodFinder.filterSlots(InventoryContainer.slots).firstOrNull() + val inventorySlot = foodFinder.filter(InventoryContainer.slots).firstOrNull() if (inventorySlot != null) runSafeAutomated { InventoryContainer.transfer(foodFinder, HotbarContainer) } diff --git a/src/main/kotlin/com/lambda/util/PacketUtils.kt b/src/main/kotlin/com/lambda/util/PacketUtils.kt index 22d95044a..2d8652302 100644 --- a/src/main/kotlin/com/lambda/util/PacketUtils.kt +++ b/src/main/kotlin/com/lambda/util/PacketUtils.kt @@ -27,7 +27,7 @@ object PacketUtils { /** * Sends a packet through the regular packet pipeline */ - fun ClientPlayNetworkHandler.sendPacket(block: () -> Packet<*>) = connection.send(block()) + fun ClientPlayNetworkHandler.sendPacket(packetSupplier: () -> Packet<*>) = connection.send(packetSupplier()) /** * Sends a packet to the server without notifying the client. From a38c0bf547e66b38fa18d16552c0228f272fbaf0 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sun, 12 Jul 2026 22:37:23 +0100 Subject: [PATCH 04/18] should be finished container transfer task setup. Need to finish external container stuff. placed shulker boxes, single chests, double chests, maybe bundles, etc --- .../lambda/config/blocks/InventoryConfig.kt | 4 +- .../simulation/checks/BreakSim.kt | 6 +- .../construction/verify/StateMatcher.kt | 2 + .../construction/verify/TargetState.kt | 25 +++++- .../interaction/handlers/ContainerHandler.kt | 10 +-- .../inventory/ContainerSelection.kt | 2 +- .../inventory/container/Container.kt | 66 +++++++++++----- .../inventory/container/ExternalContainer.kt | 8 -- .../container/containers/ArmorContainer.kt | 2 + .../container/containers/CreativeContainer.kt | 6 +- .../{ => external}/ChestContainer.kt | 55 +++++++------ .../{ => external}/EnderChestContainer.kt | 39 +++++----- .../external/PlacedShulkerBoxContainer.kt | 37 +++++++++ .../{ => external}/ShulkerBoxContainer.kt | 29 +++---- .../{ => external}/StashContainer.kt | 6 +- .../module/modules/debug/ContainerTest.kt | 2 +- .../module/modules/render/ContainerPreview.kt | 2 +- .../lambda/module/modules/world/AutoPortal.kt | 6 +- .../lambda/module/modules/world/StashMover.kt | 2 +- src/main/kotlin/com/lambda/task/Task.kt | 28 +++---- .../task/tasks/AcquirePlacedBlockTask.kt | 74 ++++++++++++++++++ ...AcquireMaterialTask.kt => AcquireStack.kt} | 6 +- .../task/tasks/ContainerTransferTask.kt | 77 ++++++++----------- .../kotlin/com/lambda/task/tasks/NoopTask.kt | 34 ++++++++ 24 files changed, 355 insertions(+), 173 deletions(-) rename src/main/kotlin/com/lambda/interaction/inventory/container/containers/{ => external}/ChestContainer.kt (56%) rename src/main/kotlin/com/lambda/interaction/inventory/container/containers/{ => external}/EnderChestContainer.kt (67%) create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt rename src/main/kotlin/com/lambda/interaction/inventory/container/containers/{ => external}/ShulkerBoxContainer.kt (70%) rename src/main/kotlin/com/lambda/interaction/inventory/container/containers/{ => external}/StashContainer.kt (89%) create mode 100644 src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt rename src/main/kotlin/com/lambda/task/tasks/{AcquireMaterialTask.kt => AcquireStack.kt} (92%) create mode 100644 src/main/kotlin/com/lambda/task/tasks/NoopTask.kt diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 18be96b21..a24a0db62 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -62,11 +62,11 @@ interface InventoryConfig { fun materialComparator(selection: StackSelection) = when (this) { WithMaxItems -> compareBy { it.rank } - .thenByDescending { it.materialAvailable(selection) } + .thenByDescending { it.stackCount(selection) } .thenBy { it.name } WithMinItems -> compareBy { it.rank } - .thenBy { it.materialAvailable(selection) } + .thenBy { it.stackCount(selection) } .thenBy { it.name } } diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt index 0fe648ead..2b15101ad 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt @@ -161,13 +161,13 @@ class BreakSim private constructor(simInfo: SimInfo) } } - val silentSwapSelection = selectContainer { + val containerSelection = selectContainer { ofAnyType(Container.Rank.Hotbar) } val hotbarCandidates = stackSelection - .findContainersWithMaterial(silentSwapSelection) - .flatMap { it.matchingStacks(stackSelection) } + .findContainersWithMaterial(containerSelection) + .flatMap { stackSelection.filter(it.stacks) } if (hotbarCandidates.isEmpty()) { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt index 9f30d19e2..7c5d72c22 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/verify/StateMatcher.kt @@ -34,7 +34,9 @@ interface StateMatcher { context(automatedSafeContext: AutomatedSafeContext) fun getStack(pos: BlockPos): ItemStack + context(automatedSafeContext: AutomatedSafeContext) fun getState(pos: BlockPos): BlockState + fun isEmpty(): Boolean } diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index 91cb32184..1ac813f5f 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -176,12 +176,33 @@ sealed class TargetState : StateMatcher { ignoredProperties: Collection> ) = state.block == block - context(automatedSafeContext: AutomatedSafeContext) + context(_: AutomatedSafeContext) override fun getStack(pos: BlockPos): ItemStack = itemStack context(_: AutomatedSafeContext) override fun getState(pos: BlockPos): BlockState = block.defaultState - override fun isEmpty() = false + override fun isEmpty() = block.defaultState.isEmpty + } + + data class SpecificStack(val itemStack: ItemStack) : TargetState() { + override fun toString() = "Specific stack of ${itemStack.item.name.string.capitalize()}" + + private val block = itemStack.item.block + + context(safeContext: SafeContext) + override fun matches( + state: BlockState, + pos: BlockPos, + ignoredProperties: Collection> + ) = state.block == block + + context(_: AutomatedSafeContext) + override fun getStack(pos: BlockPos) = itemStack + + context(_: AutomatedSafeContext) + override fun getState(pos: BlockPos): BlockState = block.defaultState + + override fun isEmpty() = block.defaultState.isEmpty } } diff --git a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt index b71db2c36..e1db759de 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt @@ -27,8 +27,8 @@ import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.containers.ChestContainer -import com.lambda.interaction.inventory.container.containers.EnderChestContainer +import com.lambda.interaction.inventory.container.containers.external.ChestContainer +import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.ReflectionUtils import com.lambda.util.extension.containerStacks @@ -86,7 +86,7 @@ object ContainerHandler : Loadable { } context(_: SafeContext) - fun containers() = containers.flatMap { setOf(it) + it.shulkerContainer }.sorted() + fun containers() = containers.flatMap { setOf(it) + it.shulkerContainers }.sorted() context(automatedSafeContext: AutomatedSafeContext) fun StackSelection.transfer(destination: Container) = @@ -119,7 +119,7 @@ object ContainerHandler : Loadable { ): List = containers() .filter { containerSelection.matches(it) } - .filter { it.materialAvailable(this) >= count } + .filter { it.stackCount(this) >= count } .sortedWith(automatedSafeContext.inventoryConfig.providerPriority.materialComparator(this)) context(automatedSafeContext: AutomatedSafeContext) @@ -151,7 +151,7 @@ object ContainerHandler : Loadable { context(automatedSafeContext: AutomatedSafeContext) fun findDisposable() = containers().find { container -> - automatedSafeContext.inventoryConfig.disposables.any { container.materialAvailable(it.asItem().select()) > 0 } + automatedSafeContext.inventoryConfig.disposables.any { container.stackCount(it.asItem().select()) > 0 } } class NoContainerFound(selection: StackSelection) : Exception("No container found matching $selection") diff --git a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt index f0e405e92..328255230 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt @@ -64,7 +64,7 @@ class ContainerSelectionBuilder private constructor() { } fun matches(stackSelection: StackSelection) { - appendSelector { container -> container.matchingSlots(stackSelection).isNotEmpty() } + appendSelector { container -> stackSelection.filter(container.slots).isNotEmpty() } } fun matches(containerSelection: ContainerSelection) { diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 4375e43ba..666442a33 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -23,10 +23,14 @@ import com.lambda.context.SafeContext import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.containers.ShulkerBoxContainer +import com.lambda.interaction.inventory.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.managers.inventory.InvRequestBuilder import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.ContainerTransferTask +import com.lambda.task.tasks.NoopTask.Companion.noop import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.empty @@ -74,7 +78,7 @@ abstract class Container( fun TextBuilder.stock(selection: StackSelection) { literal("\n") literal("Contains ") - val available = materialAvailable(selection) + val available = stackCount(selection) highlighted(if (available == Int.MAX_VALUE) "∞" else available.toItemCount()) literal(" of ") highlighted("${selection.optimalStack?.name?.string}") @@ -96,23 +100,48 @@ abstract class Container( override val name: String get() = buildText { text(description) }.string - context(_: SafeContext) - val shulkerContainer + //ToDo: Bundles + val shulkerContainers get() = - slots.filter { + slots.takeIf { + it.isEmpty() + }?.filter { it.stack.item in ItemUtils.shulkerBoxes - }.map { slot -> + }?.map { slot -> ShulkerBoxContainer( slot.stack.shulkerBoxStacks, containedIn = this@Container, shulkerSlot = slot ) - }.toSet() + }?.toSet() + ?: stacks.map { stack -> + ShulkerBoxContainer( + stack.shulkerBoxStacks, + containedIn = this@Container, + shulkerSlot = null + ) + }.toSet() + + open val isAccessed get() = true fun update(slots: List) { this.stacks = slots } + @Ta5kBuilder + context(automatedSafeContext: AutomatedSafeContext) + open fun accessThen( + closeAfter: Boolean = true, + afterClose: TaskOrNullGenerator? = null, + afterOpen: TaskGenerator = { noop() } + ) = with(automatedSafeContext) { + afterOpen(Unit).also { + if (closeAfter && afterClose != null) { + it.thenOrNull { afterClose(Unit) } + } + } + } + context(safeContext: SafeContext) open fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { if (fromHere.stack.isEmpty) moveSlot(toSlot.id, fromHere.id) @@ -123,10 +152,10 @@ abstract class Container( } context(automatedSafeContext: AutomatedSafeContext) - fun transfer(stackSelection: StackSelection, destination: Container): Boolean = + fun transfer(selection: StackSelection, destination: Container): Boolean = with(automatedSafeContext) { - val fromSlot = getSlot(stackSelection) ?: return false - val toSlot = destination.getReplaceableSlot() ?: return false + val fromSlot = getSlot(selection) ?: return false + val toSlot = destination.getReplaceSlot() ?: return false val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@Container, destination) if (transferEvent.post().isCanceled()) return false return inventoryRequest { @@ -137,22 +166,18 @@ abstract class Container( context(automated: Automated) fun transferByTask(stackSelection: StackSelection, destination: Container, failIfNoMaterial: Boolean = false) = - ContainerTransferTask(this, destination, stackSelection, automated, failIfNoMaterial) - - open fun matchingStacks(selection: StackSelection) = selection.filter(stacks) - open fun matchingSlots(selection: StackSelection) = selection.filter(slots) + ContainerTransferTask(this, destination, stackSelection, failIfNoMaterial, automated) - open fun materialAvailable(selection: StackSelection) = - matchingStacks(selection).count + open fun stackCount(selection: StackSelection) = + selection.filter(stacks).count open fun spaceAvailable(selection: StackSelection) = - matchingStacks(selection).spaceLeft + stacks.empty * selection.count + selection.filter(stacks).spaceLeft + stacks.empty context(_: Automated) - open fun getReplaceableSlot() = slots.sortedWith(replaceSorter).firstOrNull() + open fun getReplaceSlot() = slots.sortedWith(replaceSorter).firstOrNull() - open fun getSlot(stackSelection: StackSelection): Slot? = - stackSelection.filter(slots).firstOrNull() + open fun getSlot(selection: StackSelection) = selection.bestMatch(slots) enum class Rank { MainHand, @@ -165,6 +190,7 @@ abstract class Container( Creative, ShulkerBox, EnderChest, + PlacedShulkerBox, Chest, Stash } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt index da25cd005..0e395e9bc 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt @@ -17,13 +17,5 @@ package com.lambda.interaction.inventory.container -import com.lambda.context.AutomatedSafeContext -import com.lambda.task.Task -import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.TaskGenerator - interface ExternalContainer { - @Ta5kBuilder - context(_: AutomatedSafeContext) - fun accessThen(exitAfter: Boolean = true, taskGenerator: TaskGenerator): Task<*>? } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt index 8222ae5d1..b0bafe110 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt @@ -34,4 +34,6 @@ object ArmorContainer : Container(Rank.Armor) { set(_) {} override val description = buildText { literal("Armor") } + + override val isAccessed get() = mc.player?.currentScreenHandler?.syncId == 0 } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt index eb8f6f0f3..dc115fe6d 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt @@ -45,8 +45,8 @@ data object CreativeContainer : Container(Rank.Creative) { safeContext.player.currentScreenHandler.slots.getOrNull(toSlot.id)?.stack = fromHere.stack } - override fun getSlot(stackSelection: StackSelection) = - stackSelection.optimalStack?.let { stack -> + override fun getSlot(selection: StackSelection) = + selection.optimalStack?.let { stack -> Slot( object : SingleStackInventory { override fun getStack() = stack @@ -58,7 +58,7 @@ data object CreativeContainer : Container(Rank.Creative) { ) } - override fun materialAvailable(selection: StackSelection): Int = + override fun stackCount(selection: StackSelection): Int = if (mc.player?.isCreative == true && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 override fun spaceAvailable(selection: StackSelection): Int = diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt similarity index 56% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt index 343b26cda..586b77644 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt @@ -15,15 +15,15 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.inventory.container.containers.external -import com.lambda.Lambda.mc +import com.lambda.Lambda import com.lambda.context.AutomatedSafeContext import com.lambda.interaction.handlers.ContainerHandler import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.task.Task -import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.OpenContainerTask import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText @@ -31,36 +31,41 @@ import com.lambda.util.text.highlighted import com.lambda.util.text.literal import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.item.ItemStack +import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos data class ChestContainer( - override var stacks: List, - val blockPos: BlockPos, - val containedInStash: StashContainer? = null + override var stacks: List, + val blockPos: BlockPos, + val containedInStash: StashContainer? = null ) : Container(Rank.Chest), ExternalContainer { override val slots get(): List = - if (ContainerHandler.lastInteractedBlockEntity is ChestBlockEntity) { - mc.player?.currentScreenHandler?.containerSlots ?: emptyList() - } else emptyList() + ContainerHandler.lastInteractedBlockEntity?.let { blockEntity -> + if (blockEntity is ChestBlockEntity && blockEntity.pos == blockPos) { + Lambda.mc.player?.currentScreenHandler?.containerSlots + } else emptyList() + } ?: emptyList() override val description = - buildText { - literal("Chest at ") - highlighted(blockPos.toShortString()) - containedInStash?.let { stash -> - literal(" (contained in ") - highlighted(stash.name) - literal(")") - } - } + buildText { + literal("Chest at ") + highlighted(blockPos.toShortString()) + containedInStash?.let { stash -> + literal(" (contained in ") + highlighted(stash.name) + literal(")") + } + } context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen(exitAfter: Boolean, taskGenerator: TaskGenerator): Task<*> = - OpenContainerTask(blockPos, automatedSafeContext).then { - taskGenerator.invoke(automatedSafeContext, Unit).finally { - if (exitAfter) automatedSafeContext.player.closeHandledScreen() - } - } -} + override fun accessThen( + exitAfter: Boolean, + afterOpen: TaskOrNullGenerator = { null }, + afterClose: TaskOrNullGenerator = { null } + ): Task<*> = + OpenContainerTask(blockPos, automatedSafeContext) + .thenOrNull(afterOpen) + .then { if (exitAfter) automatedSafeContext.player.closeHandledScreen() } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt similarity index 67% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt index 627b31f77..f769bd802 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt @@ -15,25 +15,24 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext import com.lambda.interaction.handlers.ContainerHandler -import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator +import com.lambda.task.tasks.AcquirePlacedBlockTask import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainerTask -import com.lambda.task.tasks.PlaceContainerTask import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal +import net.minecraft.block.Blocks import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.item.ItemStack -import net.minecraft.item.Items object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { override val slots @@ -46,20 +45,22 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { override val description = buildText { literal("Ender Chest") } context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen(exitAfter: Boolean, taskGenerator: TaskGenerator) = - Items.ENDER_CHEST - .select(1) - .findSlotsWithMaterial() - .firstOrNull()?.let { slot -> - PlaceContainerTask(slot, automatedSafeContext).then { pos -> - OpenContainerTask(pos, automatedSafeContext).then { - taskGenerator.invoke(automatedSafeContext, Unit).thenOrNull { - if (exitAfter) { - player.closeHandledScreen() - automatedSafeContext.breakAndCollectBlock(pos, lifeMaintenance = false) - } else null - } - } + override fun accessThen( + closeAfter: Boolean, + afterClose: TaskOrNullGenerator?, + afterOpen: TaskGenerator + ) = + AcquirePlacedBlockTask( + Blocks.ENDER_CHEST, + automated = automatedSafeContext + ).then { pos -> + OpenContainerTask(pos, automatedSafeContext).then { + afterOpen.invoke(automatedSafeContext, Unit).thenOrNull { + if (closeAfter) { + player.closeHandledScreen() + automatedSafeContext.breakAndCollectBlock(pos, lifeMaintenance = false) + } else null } } + } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt new file mode 100644 index 000000000..d4f1cca4e --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container.containers.external + +import com.lambda.interaction.inventory.container.Container +import net.minecraft.item.ItemStack +import net.minecraft.screen.slot.Slot +import net.minecraft.text.Text +import net.minecraft.util.math.BlockPos + +class PlacedShulkerBoxContainer( + val blockPos: BlockPos, + val +) : Container(Rank.PlacedShulkerBox) { + override val slots: List + get() = TODO("Not yet implemented") + override var stacks: List + get() = TODO("Not yet implemented") + set(value) {} + override val description: Text + get() = TODO("Not yet implemented") +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt similarity index 70% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index c3faed9fc..eace9fcb3 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -15,15 +15,17 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.ContainerHandler +import com.lambda.interaction.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.task.Task import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock import com.lambda.task.tasks.OpenContainerTask import com.lambda.task.tasks.PlaceContainerTask @@ -35,22 +37,21 @@ import com.lambda.util.text.literal import net.minecraft.block.entity.ShulkerBoxBlockEntity import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -import net.minecraft.util.math.BlockPos data class ShulkerBoxContainer( override var stacks: List, val containedIn: Container, - val shulkerSlot: Slot, + val shulkerSlot: Slot?, ) : Container(Rank.ShulkerBox), ExternalContainer { override val slots get(): List = - if (ContainerHandler.lastInteractedBlockEntity is ShulkerBoxBlockEntity) + if (lastInteractedBlockEntity is ShulkerBoxBlockEntity) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() else emptyList() override val description = buildText { - highlighted(shulkerSlot.stack.name.string) + highlighted(shulkerSlot?.stack?.name?.string ?: "Shulker Box") literal(" in ") highlighted(containedIn.name) literal(" in slot ") @@ -60,17 +61,19 @@ data class ShulkerBoxContainer( context(_: SafeContext) private val slotInContainer: Int get() = containedIn.slots.indexOf(shulkerSlot) - private var placePos = BlockPos.ORIGIN + override val isAccessed get() = lastInteractedBlockEntity is ShulkerBoxBlockEntity context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen(exitAfter: Boolean, taskGenerator: TaskGenerator) = - PlaceContainerTask(shulkerSlot, automatedSafeContext).then { pos -> - placePos = pos + override fun accessThen(closeAfter: Boolean, afterClose: TaskOrNullGenerator?, afterOpen: TaskGenerator): Task<*> { + return PlaceContainerTask(shulkerSlot, automatedSafeContext).then { pos -> OpenContainerTask(pos, automatedSafeContext).then { - taskGenerator.invoke(automatedSafeContext, Unit).thenOrNull { - if (exitAfter) automatedSafeContext.breakAndCollectBlock(placePos) - else null + afterOpen.invoke(automatedSafeContext, Unit).thenOrNull { + if (closeAfter) { + player.closeHandledScreen() + automatedSafeContext.breakAndCollectBlock(pos) + } else null } } } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt similarity index 89% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt index 1dc78c499..b425a7e66 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/StashContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.inventory.container.containers.external import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container @@ -42,8 +42,8 @@ data class StashContainer( highlighted(pos.center.roundedBlockPos.toShortString()) } - override fun materialAvailable(selection: StackSelection): Int = + override fun stackCount(selection: StackSelection): Int = chests.sumOf { - it.materialAvailable(selection) + it.stackCount(selection) } } diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index 955694f8c..898e5b046 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -23,7 +23,7 @@ import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run -import com.lambda.task.tasks.AcquireMaterialTask.Companion.acquire +import com.lambda.task.tasks.AcquireStack.Companion.acquire import net.minecraft.item.Items @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt index 2712076b1..deef6f9ce 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt @@ -21,7 +21,7 @@ import com.lambda.Lambda.mc import com.lambda.config.Tab import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.config.settings.complex.Bind -import com.lambda.interaction.inventory.container.containers.EnderChestContainer +import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 6e2970b72..d36d5d538 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -102,11 +102,9 @@ object AutoPortal : Module( .thenOrNull { if (light) LightTask(currAnchorPos.up(), walkIn) else null - } - .finally { + }.finally { buildTask = null - } - .run() + }.run() } private val corners by setting("Corners", false) private val light by setting("Light", true, "Attempts to automatically light the portal after building") diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index 814e556bb..92304d9a5 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -41,7 +41,7 @@ import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.inventory.container.containers.EnderChestContainer +import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index 764e13a91..bd2f0dbaa 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -34,8 +34,8 @@ import kotlin.time.DurationUnit import kotlin.time.toDuration typealias TaskGenerator = SafeContext.(R) -> Task<*> -typealias TaskGeneratorOrNull = SafeContext.(R) -> Task<*>? -typealias TaskGeneratorUnit = SafeContext.(R) -> Unit +typealias TaskOrNullGenerator = SafeContext.(R) -> Task<*>? +typealias TaskUnitGenerator = SafeContext.(R) -> Unit @Suppress("unused") abstract class Task : Nameable, Muteable { @@ -50,11 +50,11 @@ abstract class Task : Nameable, Muteable { val size: Int get() = subTasks.sumOf { it.size } + 1 private var nextTask: TaskGenerator? = null - private var nextTaskOrNull: TaskGeneratorOrNull? = null - private var onFinish: TaskGeneratorUnit? = null + private var nextTaskOrNull: TaskOrNullGenerator? = null + private var onFinish: TaskUnitGenerator? = null private var onFail: TaskGenerator? = null - private var onFailOrNull: TaskGeneratorOrNull? = null + private var onFailOrNull: TaskOrNullGenerator? = null private var softFail = false enum class State { @@ -249,7 +249,7 @@ abstract class Task : Nameable, Muteable { @Ta5kBuilder infix fun then(task: Task<*>): Task { require(task != this) { "Cannot link a task to itself" } - nextTask = { task } + then { task } return this } @@ -287,7 +287,7 @@ abstract class Task : Nameable, Muteable { */ @Ta5kBuilder fun then(taskGenerator: TaskGenerator): Task { - require(nextTask == null) { "Cannot link multiple tasks to a single task" } + require(nextTask == null && nextTaskOrNull == null) { "Cannot link multiple tasks to a single task" } nextTask = taskGenerator return this } @@ -297,7 +297,7 @@ abstract class Task : Nameable, Muteable { * * This method specifies the next task to be executed after the current task * completes successfully. The next task is generated dynamically using the provided - * [TaskGeneratorOrNull]. This allows chaining tasks together flexibly, + * [TaskOrNullGenerator]. This allows chaining tasks together flexibly, * where the next task is conditionally determined or null. * * @param taskGenerator A function that generates the next task based on the @@ -307,23 +307,23 @@ abstract class Task : Nameable, Muteable { * @return The current task instance (`Task`) to allow method chaining. */ @Ta5kBuilder - fun thenOrNull(taskGenerator: TaskGeneratorOrNull): Task { - require(nextTask == null) { "Cannot link multiple tasks to a single task" } + fun thenOrNull(taskGenerator: TaskOrNullGenerator): Task { + require(nextTask == null && nextTaskOrNull == null) { "Cannot link multiple tasks to a single task" } nextTaskOrNull = taskGenerator return this } @Ta5kBuilder fun onFail(taskGenerator: TaskGenerator): Task { - require(onFail == null) { "Cannot have multiple onFail callbacks on a single task" } + require(onFail == null && onFailOrNull == null) { "Cannot have multiple onFail callbacks on a single task" } onFail = taskGenerator softFail() return this } @Ta5kBuilder - fun onFailOrNull(taskGenerator: TaskGeneratorOrNull): Task { - require(onFailOrNull == null) { "Cannot have multiple onFailOrNull callbacks on a single task" } + fun onFailOrNull(taskGenerator: TaskOrNullGenerator): Task { + require(onFail == null && onFailOrNull == null) { "Cannot have multiple onFail callbacks on a single task" } onFailOrNull = taskGenerator softFail() return this @@ -347,7 +347,7 @@ abstract class Task : Nameable, Muteable { * @return The current task instance (`Task`) to allow method chaining. */ @Ta5kBuilder - fun finally(onFinish: TaskGeneratorUnit): Task { + fun finally(onFinish: TaskUnitGenerator): Task { require(this.onFinish == null) { "Cannot link multiple finally blocks to a single task" } this.onFinish = onFinish return this diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt new file mode 100644 index 000000000..086700731 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks + +import com.lambda.context.Automated +import com.lambda.context.SafeContext +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select +import com.lambda.task.Task +import com.lambda.threading.runSafeAutomated +import com.lambda.util.BlockUtils.blockPos +import com.lambda.util.BlockUtils.blockState +import net.minecraft.block.Block +import net.minecraft.item.Items +import net.minecraft.util.math.BlockPos + +class AcquirePlacedBlockTask @Ta5kBuilder constructor( + val block: Block, + val maxSearchRadius: Int = 10, + automated: Automated +) : Task(), Automated by automated { + override val name get() = "Acquiring placed ${block.name.string}" + + init { + listen { + runSafeAutomated { + Items.ENDER_CHEST + .select(1) + .findSlotsWithMaterial() + .firstOrNull()?.let { slot -> + PlaceContainerTask(slot, this).finally { + success(it) + }.execute(this@AcquirePlacedBlockTask) + return@listen + } + } + + failure("No ender chest found in range or hotbar/inventory!") + return@listen + } + } + + override fun SafeContext.onStart() { + checkInRange()?.let { success(it) } + } + + private fun SafeContext.checkInRange() = + BlockPos.iterateOutwards( + player.blockPos, + maxSearchRadius, + maxSearchRadius, + maxSearchRadius + ).map { it.blockPos } + .firstOrNull { blockPos -> + blockState(blockPos).block == block + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStack.kt similarity index 92% rename from src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt rename to src/main/kotlin/com/lambda/task/tasks/AcquireStack.kt index de9264b21..a28f1c336 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireMaterialTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStack.kt @@ -26,7 +26,7 @@ import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import com.lambda.threading.runSafeAutomated -class AcquireMaterialTask @Ta5kBuilder constructor( +class AcquireStack @Ta5kBuilder constructor( val selection: StackSelection, automated: Automated ) : Task(), Automated by automated { @@ -39,7 +39,7 @@ class AcquireMaterialTask @Ta5kBuilder constructor( ?.transferByTask(selection, HotbarContainer) ?.finally { success(selection) - }?.execute(this@AcquireMaterialTask) + }?.execute(this@AcquireStack) ?: failure(ContainerHandler.NoContainerFound(selection)) // ToDo: Create crafting path } } @@ -47,6 +47,6 @@ class AcquireMaterialTask @Ta5kBuilder constructor( companion object { @Ta5kBuilder fun Automated.acquire(selection: () -> StackSelection) = - AcquireMaterialTask(selection(), this) + AcquireStack(selection(), this) } } diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index c06883dee..03ce1c3ec 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -18,15 +18,12 @@ package com.lambda.task.tasks import com.lambda.context.Automated -import com.lambda.event.EventFlow.post -import com.lambda.event.events.ContainerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated @@ -34,63 +31,53 @@ class ContainerTransferTask( private var fromContainer: Container, private val toContainer: Container, private val stackSelection: StackSelection, - automated: Automated, - private val failIfNoMaterial: Boolean = false + private val failIfNoStack: Boolean = false, + automated: Automated ) : Task(), Automated by automated { override val name = "Transferring $stackSelection from $fromContainer to $toContainer" init { listen { runSafeAutomated { - val slots = fromContainer.slots - val toSlots = toContainer.slots - if (fromContainer is ExternalContainer && slots.isEmpty()) { - if (toContainer is ExternalContainer && toSlots.isEmpty()) { - fromContainer - .transferByTask(stackSelection, HotbarAndInventoryContainer) - .finally { fromContainer = HotbarAndInventoryContainer } - .execute(this@ContainerTransferTask) - return@listen - } - return@listen - } - if (toContainer is ExternalContainer && toSlots.isEmpty()) { - toContainer - .accessThen { - fromContainer.transferByTask(stackSelection, toContainer) - }?.finally { success() } - ?.execute(this@ContainerTransferTask) ?: run { - checkFail() - return@listen + if (fromContainer is ExternalContainer && toContainer is ExternalContainer) { + fromContainer.accessThen( + true, + { + HotbarAndInventoryContainer.transferByTask(stackSelection, toContainer) + .finally { success() } } + ) { + fromContainer.transferByTask(stackSelection, HotbarAndInventoryContainer) + }.execute(this@ContainerTransferTask) return@listen } - fromContainer.getSlot(stackSelection)?.let { fromSlot -> - toContainer.getReplaceableSlot()?.let { toSlot -> - val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, fromContainer, toContainer) - if (transferEvent.post().isCanceled()) failure("Transfer prevented by an internal interruption") - inventoryRequest { - if (fromContainer.swapMethodPriority > toContainer.swapMethodPriority) - with(fromContainer) { transfer(fromSlot, toSlot) } - else with(toContainer) { transfer(toSlot, fromSlot) } - onComplete { success() } - }.submit() - return@listen + fromContainer.accessThen { + toContainer.accessThen { + TransferTask() } - } - - checkFail() + }.execute(this@ContainerTransferTask) } } } + private inner class TransferTask : Task() { + override val name = "Transferring" - private fun checkFail(): Boolean = - if (failIfNoMaterial) { - failure(NoMaterialAccessException(stackSelection)) - true - } else false + init { + listen { + runSafeAutomated { + val transferSuccessful = fromContainer.transfer(stackSelection, toContainer) + if (transferSuccessful) success() + else checkFail() + } + } + } - private class NoMaterialAccessException(stackSelection: StackSelection) : IllegalStateException("Unable to access $stackSelection.") + private fun checkFail() { + if (failIfNoStack) failure(NoMaterialAccessException(stackSelection)) + } + + private inner class NoMaterialAccessException(stackSelection: StackSelection) : IllegalStateException("Unable to access $stackSelection.") + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt b/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt new file mode 100644 index 000000000..bc7b870c5 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks + +import com.lambda.context.SafeContext +import com.lambda.task.Task + +class NoopTask : Task() { + override val name = "No-operation task" + + override fun SafeContext.onStart() { + success() + } + + companion object { + @Ta5kBuilder + fun noop() = NoopTask() + } +} \ No newline at end of file From 401722735c1fcfc25b7e4efae3f3570b25c39bc3 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Wed, 15 Jul 2026 11:06:25 +0100 Subject: [PATCH 05/18] lotta changes, still a lotta broken stuff --- .../lambda/mixin/MinecraftClientMixin.java | 2 +- .../ClientPlayInteractionManagerMixin.java | 6 +- .../mixin/entity/ClientPlayerEntityMixin.java | 4 +- .../com/lambda/mixin/entity/EntityMixin.java | 4 +- .../mixin/entity/HandledScreensMixin.java | 2 +- .../mixin/entity/LivingEntityMixin.java | 6 +- .../mixin/entity/PlayerEntityMixin.java | 6 +- .../mixin/entity/PlayerInventoryMixin.java | 2 +- .../ClientPlayNetworkHandlerMixin.java | 2 +- .../com/lambda/mixin/render/CameraMixin.java | 2 +- .../render/LivingEntityRendererMixin.java | 4 +- .../mixin/render/PlayerListHudMixin.java | 2 +- .../lambda/mixin/world/DirectionMixin.java | 4 +- .../lambda/command/commands/FriendCommand.kt | 2 +- .../command/commands/TransferCommand.kt | 12 +- .../com/lambda/config/ConfigCategory.kt | 2 +- .../com/lambda/config/blocks/BuildConfig.kt | 4 +- .../config/blocks/EntityColorSettings.kt | 2 +- .../lambda/config/blocks/InventoryConfig.kt | 2 - .../lambda/config/blocks/RotationConfig.kt | 4 +- .../lambda/config/blocks/RotationSettings.kt | 2 +- .../lambda/config/blocks/TargetingSettings.kt | 8 +- .../com/lambda/event/events/RotationEvent.kt | 2 +- src/main/kotlin/com/lambda/gui/MenuBar.kt | 2 +- .../construction/simulation/Sim.kt | 2 +- .../simulation/checks/BreakSim.kt | 10 +- .../simulation/checks/InteractSim.kt | 12 +- .../simulation/context/BreakContext.kt | 2 +- .../simulation/context/BuildContext.kt | 2 +- .../simulation/context/InteractContext.kt | 4 +- .../simulation/result/Contextual.kt | 4 +- .../simulation/result/results/BreakResult.kt | 11 +- .../result/results/GenericResult.kt | 9 +- .../result/results/InteractResult.kt | 2 +- .../simulation/result/results/PreSimResult.kt | 2 +- .../construction/verify/TargetState.kt | 2 +- .../PostActionHandler.kt | 5 +- .../{ => handler}/handlers/BaritoneHandler.kt | 2 +- .../handlers/ContainerHandler.kt | 130 ++++++++++-------- .../{ => handler}/handlers/FriendHandler.kt | 2 +- .../{ => handler}/handlers/GlideHandler.kt | 2 +- .../{ => handler}/handlers/PingHandler.kt | 2 +- .../{ => handler}/handlers/TimerHandler.kt | 2 +- .../handlers/breaking/BrokenBlockHandler.kt | 12 +- .../handlers/breaking/RebreakHandler.kt | 22 +-- .../handlers/breaking/RebreakResult.kt | 4 +- .../interacting/InteractedBlockHandler.kt | 8 +- .../handlers/packet/PacketLimitHandler.kt | 2 +- .../interaction/inventory/ContainerMarker.kt | 21 +++ .../inventory/ContainerSelection.kt | 11 +- .../interaction/inventory/StackSelection.kt | 21 ++- .../inventory/container/Container.kt | 48 ++++--- .../inventory/container/NestedContainer.kt | 24 ++++ .../inventory/container/PlacedContainer.kt | 24 ++++ .../container/containers/CreativeContainer.kt | 2 +- .../container/containers/HotbarContainer.kt | 2 +- .../container/containers/MainHandContainer.kt | 2 +- .../container/containers/OffHandContainer.kt | 2 +- .../containers/external/ChestContainer.kt | 53 ++++--- .../external/EnderChestContainer.kt | 60 +++++--- .../external/PlacedShulkerBoxContainer.kt | 66 +++++++-- .../external/ShulkerBoxContainer.kt | 63 +++++---- .../{managers => manager}/ActionInfo.kt | 2 +- .../{managers => manager}/Manager.kt | 4 +- .../{managers => manager}/ManagerUtils.kt | 2 +- .../{managers => manager}/PositionBlocking.kt | 2 +- .../{managers => manager}/Request.kt | 2 +- .../managers/breaking/BreakInfo.kt | 16 +-- .../managers/breaking/BreakManager.kt | 82 +++++------ .../managers/breaking/BreakRequest.kt | 4 +- .../managers/breaking/SwapInfo.kt | 10 +- .../managers/hotbar/HotbarManager.kt | 14 +- .../managers/hotbar/HotbarRequest.kt | 5 +- .../managers/interacting/InteractInfo.kt | 4 +- .../managers/interacting/InteractManager.kt | 34 ++--- .../managers/interacting/InteractRequest.kt | 4 +- .../managers/inventory/InventoryAction.kt | 2 +- .../managers/inventory/InventoryManager.kt | 18 +-- .../managers/inventory/InventoryRequest.kt | 5 +- .../managers/rotating/Rotation.kt | 2 +- .../managers/rotating/RotationManager.kt | 14 +- .../managers/rotating/RotationMode.kt | 2 +- .../managers/rotating/RotationRequest.kt | 18 +-- .../kotlin/com/lambda/module/hud/Baritone.kt | 2 +- .../lambda/module/modules/chat/AntiSpam.kt | 2 +- .../lambda/module/modules/chat/CustomChat.kt | 2 +- .../lambda/module/modules/chat/FancyChat.kt | 2 +- .../module/modules/chat/FriendHighlight.kt | 2 +- .../lambda/module/modules/combat/AutoArmor.kt | 2 +- .../lambda/module/modules/combat/AutoTotem.kt | 4 +- .../lambda/module/modules/combat/Criticals.kt | 4 +- .../module/modules/combat/CrystalAura.kt | 10 +- .../lambda/module/modules/combat/KillAura.kt | 4 +- .../module/modules/combat/PlayerTrap.kt | 2 +- .../combat/autodisconnect/AutoDisconnect.kt | 10 +- .../module/modules/debug/BaritoneTest.kt | 2 +- .../module/modules/debug/ContainerTest.kt | 4 +- .../module/modules/debug/RotationTest.kt | 2 +- .../lambda/module/modules/debug/SilentSwap.kt | 2 +- .../module/modules/movement/AutoSpiral.kt | 4 +- .../module/modules/movement/BetterFirework.kt | 6 +- .../modules/movement/ElytraAltitudeControl.kt | 2 +- .../lambda/module/modules/movement/Speed.kt | 2 +- .../module/modules/movement/TargetStrafe.kt | 2 +- .../movement/elytrafly/ElytraFlyMode.kt | 10 +- .../movement/elytrafly/ObstaclePassingMode.kt | 2 +- .../elytrafly/modes/BounceElytraFly.kt | 8 +- .../elytrafly/modes/GrimControlElytraFly.kt | 4 +- .../lambda/module/modules/player/AntiAim.kt | 4 +- .../module/modules/player/AutoElytraSwap.kt | 10 +- .../module/modules/player/ClickFriend.kt | 8 +- .../lambda/module/modules/player/FastBreak.kt | 2 +- .../module/modules/player/InventoryMove.kt | 4 +- .../module/modules/player/InventoryResync.kt | 2 +- .../module/modules/player/InventoryTweaks.kt | 4 +- .../module/modules/player/PacketMine.kt | 2 +- .../lambda/module/modules/player/Replay.kt | 8 +- .../module/modules/player/RotationLock.kt | 4 +- .../module/modules/player/StackReplenish.kt | 2 +- .../lambda/module/modules/player/ToolSaver.kt | 2 +- .../lambda/module/modules/render/FreeLook.kt | 4 +- .../lambda/module/modules/render/Freecam.kt | 6 +- .../lambda/module/modules/render/Nametags.kt | 2 +- .../lambda/module/modules/render/Tracers.kt | 2 +- .../lambda/module/modules/world/AirPlace.kt | 6 +- .../lambda/module/modules/world/AutoPortal.kt | 6 +- .../module/modules/world/AutoVillagerCycle.kt | 2 +- .../module/modules/world/HighwayTools.kt | 2 +- .../lambda/module/modules/world/Scaffold.kt | 2 +- .../lambda/module/modules/world/StashMover.kt | 14 +- .../task/tasks/AcquirePlacedBlockTask.kt | 13 +- .../{AcquireStack.kt => AcquireStackTask.kt} | 26 ++-- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 15 +- .../task/tasks/ContainerTransferTask.kt | 57 +++++++- .../kotlin/com/lambda/task/tasks/EatTask.kt | 3 +- .../kotlin/com/lambda/task/tasks/NoopTask.kt | 2 +- .../lambda/task/tasks/OpenContainerTask.kt | 18 ++- .../lambda/task/tasks/PlaceContainerTask.kt | 12 +- .../com/lambda/task/tasks/SimpleActionTask.kt | 36 +++++ .../com/lambda/task/tasks/SlotByCacheTask.kt | 36 +++++ .../kotlin/com/lambda/util/PlaceDirection.kt | 2 +- .../com/lambda/util/PlayerBuildLayerUtils.kt | 2 +- .../com/lambda/util/extension/Entity.kt | 2 +- .../kotlin/com/lambda/util/math/Linear.kt | 2 +- .../com/lambda/util/player/MovementUtils.kt | 2 +- .../com/lambda/util/player/PlayerUtils.kt | 2 +- .../com/lambda/util/player/RotationUtils.kt | 6 +- .../com/lambda/util/player/SlotUtils.kt | 7 + .../player/prediction/PredictionEntity.kt | 2 +- .../util/player/prediction/PredictionTick.kt | 2 +- .../lambda/util/world/raycast/RayCastUtils.kt | 2 +- src/test/kotlin/PlaceDirectionTest.kt | 2 +- src/test/kotlin/RotationTest.kt | 12 +- 153 files changed, 899 insertions(+), 546 deletions(-) rename src/main/kotlin/com/lambda/interaction/{managers => handler}/PostActionHandler.kt (91%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/BaritoneHandler.kt (99%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/ContainerHandler.kt (57%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/FriendHandler.kt (99%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/GlideHandler.kt (99%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/PingHandler.kt (97%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/TimerHandler.kt (96%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/breaking/BrokenBlockHandler.kt (93%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/breaking/RebreakHandler.kt (83%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/breaking/RebreakResult.kt (87%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/interacting/InteractedBlockHandler.kt (91%) rename src/main/kotlin/com/lambda/interaction/{ => handler}/handlers/packet/PacketLimitHandler.kt (97%) create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/ContainerMarker.kt create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt rename src/main/kotlin/com/lambda/interaction/{managers => manager}/ActionInfo.kt (96%) rename src/main/kotlin/com/lambda/interaction/{managers => manager}/Manager.kt (97%) rename src/main/kotlin/com/lambda/interaction/{managers => manager}/ManagerUtils.kt (96%) rename src/main/kotlin/com/lambda/interaction/{managers => manager}/PositionBlocking.kt (96%) rename src/main/kotlin/com/lambda/interaction/{managers => manager}/Request.kt (97%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/breaking/BreakInfo.kt (89%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/breaking/BreakManager.kt (89%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/breaking/BreakRequest.kt (98%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/breaking/SwapInfo.kt (87%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/hotbar/HotbarManager.kt (91%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/hotbar/HotbarRequest.kt (93%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/interacting/InteractInfo.kt (91%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/interacting/InteractManager.kt (91%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/interacting/InteractRequest.kt (97%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/inventory/InventoryAction.kt (95%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/inventory/InventoryManager.kt (93%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/inventory/InventoryRequest.kt (97%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/rotating/Rotation.kt (99%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/rotating/RotationManager.kt (95%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/rotating/RotationMode.kt (96%) rename src/main/kotlin/com/lambda/interaction/{ => manager}/managers/rotating/RotationRequest.kt (90%) rename src/main/kotlin/com/lambda/task/tasks/{AcquireStack.kt => AcquireStackTask.kt} (66%) create mode 100644 src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt create mode 100644 src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt diff --git a/src/main/java/com/lambda/mixin/MinecraftClientMixin.java b/src/main/java/com/lambda/mixin/MinecraftClientMixin.java index 30a4dd4e5..a503297cf 100644 --- a/src/main/java/com/lambda/mixin/MinecraftClientMixin.java +++ b/src/main/java/com/lambda/mixin/MinecraftClientMixin.java @@ -17,7 +17,7 @@ package com.lambda.mixin; -import com.lambda.interaction.handlers.TimerHandler; +import com.lambda.interaction.handler.handlers.TimerHandler; import com.lambda.event.EventFlow; import com.lambda.event.events.*; import com.lambda.gui.DearImGui; diff --git a/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java b/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java index dbdb9a9d2..e13b3f459 100644 --- a/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java +++ b/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java @@ -20,9 +20,9 @@ import com.lambda.event.EventFlow; import com.lambda.event.events.InventoryEvent; import com.lambda.event.events.PlayerEvent; -import com.lambda.interaction.handlers.BaritoneHandler; -import com.lambda.interaction.managers.inventory.InventoryManager; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.handler.handlers.BaritoneHandler; +import com.lambda.interaction.manager.managers.inventory.InventoryManager; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; diff --git a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java index c6e112c36..1688ed7e8 100644 --- a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java @@ -19,8 +19,8 @@ import com.lambda.event.EventFlow; import com.lambda.event.events.*; -import com.lambda.interaction.handlers.BaritoneHandler; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.handler.handlers.BaritoneHandler; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.lambda.module.modules.movement.NoJumpCooldown; import com.lambda.module.modules.movement.elytrafly.ElytraFly; import com.lambda.module.modules.player.PortalGui; diff --git a/src/main/java/com/lambda/mixin/entity/EntityMixin.java b/src/main/java/com/lambda/mixin/entity/EntityMixin.java index 2c31d2ff8..99fb142f6 100644 --- a/src/main/java/com/lambda/mixin/entity/EntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/EntityMixin.java @@ -20,8 +20,8 @@ import com.lambda.event.EventFlow; import com.lambda.event.events.EntityEvent; import com.lambda.event.events.PlayerEvent; -import com.lambda.interaction.handlers.BaritoneHandler; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.handler.handlers.BaritoneHandler; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.lambda.module.modules.movement.elytrafly.ElytraFly; import com.lambda.module.modules.render.NoRender; import com.lambda.util.math.Vec2d; diff --git a/src/main/java/com/lambda/mixin/entity/HandledScreensMixin.java b/src/main/java/com/lambda/mixin/entity/HandledScreensMixin.java index 079ea9411..106e0bbb0 100644 --- a/src/main/java/com/lambda/mixin/entity/HandledScreensMixin.java +++ b/src/main/java/com/lambda/mixin/entity/HandledScreensMixin.java @@ -17,7 +17,7 @@ package com.lambda.mixin.entity; -import com.lambda.interaction.managers.inventory.InventoryManager; +import com.lambda.interaction.manager.managers.inventory.InventoryManager; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.HandledScreens; import net.minecraft.screen.ScreenHandler; diff --git a/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java b/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java index 64d1c93ff..10ab80259 100644 --- a/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java @@ -20,9 +20,9 @@ import com.lambda.Lambda; import com.lambda.event.EventFlow; import com.lambda.event.events.MovementEvent; -import com.lambda.interaction.handlers.BaritoneHandler; -import com.lambda.interaction.handlers.GlideHandler; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.handler.handlers.BaritoneHandler; +import com.lambda.interaction.handler.handlers.GlideHandler; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.lambda.module.modules.movement.Velocity; import com.lambda.module.modules.movement.elytrafly.ElytraFly; import com.lambda.module.modules.render.ViewModel; diff --git a/src/main/java/com/lambda/mixin/entity/PlayerEntityMixin.java b/src/main/java/com/lambda/mixin/entity/PlayerEntityMixin.java index 8a0fc6d0d..c7722b2bc 100644 --- a/src/main/java/com/lambda/mixin/entity/PlayerEntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/PlayerEntityMixin.java @@ -20,9 +20,9 @@ import com.lambda.Lambda; import com.lambda.event.EventFlow; import com.lambda.event.events.MovementEvent; -import com.lambda.interaction.handlers.BaritoneHandler; -import com.lambda.interaction.handlers.GlideHandler; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.handler.handlers.BaritoneHandler; +import com.lambda.interaction.handler.handlers.GlideHandler; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.lambda.module.modules.player.Reach; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; diff --git a/src/main/java/com/lambda/mixin/entity/PlayerInventoryMixin.java b/src/main/java/com/lambda/mixin/entity/PlayerInventoryMixin.java index 26c4c0a91..e538912bd 100644 --- a/src/main/java/com/lambda/mixin/entity/PlayerInventoryMixin.java +++ b/src/main/java/com/lambda/mixin/entity/PlayerInventoryMixin.java @@ -18,7 +18,7 @@ package com.lambda.mixin.entity; import com.lambda.Lambda; -import com.lambda.interaction.managers.hotbar.HotbarManager; +import com.lambda.interaction.manager.managers.hotbar.HotbarManager; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.entity.player.PlayerInventory; import org.objectweb.asm.Opcodes; diff --git a/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java b/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java index 8107b5e38..9a295f9eb 100644 --- a/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java @@ -22,7 +22,7 @@ import com.lambda.event.events.ChatEvent; import com.lambda.event.events.InventoryEvent; import com.lambda.event.events.WorldEvent; -import com.lambda.interaction.managers.inventory.InventoryManager; +import com.lambda.interaction.manager.managers.inventory.InventoryManager; import com.lambda.module.modules.movement.Velocity; import com.lambda.module.modules.player.NoForceRotate; import com.lambda.module.modules.render.NoRender; diff --git a/src/main/java/com/lambda/mixin/render/CameraMixin.java b/src/main/java/com/lambda/mixin/render/CameraMixin.java index 38f629489..e6ca7231f 100644 --- a/src/main/java/com/lambda/mixin/render/CameraMixin.java +++ b/src/main/java/com/lambda/mixin/render/CameraMixin.java @@ -17,7 +17,7 @@ package com.lambda.mixin.render; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.lambda.module.modules.render.CameraTweaks; import com.lambda.module.modules.render.FreeLook; import com.lambda.module.modules.render.Freecam; diff --git a/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java b/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java index dc18dc35a..86ffe2d5e 100644 --- a/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java +++ b/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java @@ -18,8 +18,8 @@ package com.lambda.mixin.render; import com.lambda.Lambda; -import com.lambda.interaction.handlers.BaritoneHandler; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.handler.handlers.BaritoneHandler; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.lambda.module.modules.render.Nametags; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; diff --git a/src/main/java/com/lambda/mixin/render/PlayerListHudMixin.java b/src/main/java/com/lambda/mixin/render/PlayerListHudMixin.java index eefaba6f1..f6e090956 100644 --- a/src/main/java/com/lambda/mixin/render/PlayerListHudMixin.java +++ b/src/main/java/com/lambda/mixin/render/PlayerListHudMixin.java @@ -17,7 +17,7 @@ package com.lambda.mixin.render; -import com.lambda.interaction.handlers.FriendHandler; +import com.lambda.interaction.handler.handlers.FriendHandler; import com.lambda.module.modules.render.ExtraTab; import com.lambda.util.text.TextBuilder; import com.lambda.util.text.TextDslKt; diff --git a/src/main/java/com/lambda/mixin/world/DirectionMixin.java b/src/main/java/com/lambda/mixin/world/DirectionMixin.java index 765248bb3..da8698f2e 100644 --- a/src/main/java/com/lambda/mixin/world/DirectionMixin.java +++ b/src/main/java/com/lambda/mixin/world/DirectionMixin.java @@ -17,8 +17,8 @@ package com.lambda.mixin.world; -import com.lambda.interaction.handlers.BaritoneHandler; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.handler.handlers.BaritoneHandler; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.entity.Entity; import net.minecraft.util.math.Direction; diff --git a/src/main/kotlin/com/lambda/command/commands/FriendCommand.kt b/src/main/kotlin/com/lambda/command/commands/FriendCommand.kt index 8d3a6e6af..3de171a5f 100644 --- a/src/main/kotlin/com/lambda/command/commands/FriendCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/FriendCommand.kt @@ -29,7 +29,7 @@ import com.lambda.brigadier.executeWithResult import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.categories.FriendCategory -import com.lambda.interaction.handlers.FriendHandler +import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.network.mojang.getProfile import com.lambda.threading.runIO import com.lambda.util.CommunicationUtils.info diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index 6027680c4..86db90836 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -28,9 +28,9 @@ import com.lambda.brigadier.executeWithResult import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig -import com.lambda.interaction.handlers.ContainerHandler -import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial -import com.lambda.interaction.handlers.ContainerHandler.findContainersWithSpace +import com.lambda.interaction.handler.handlers.ContainerHandler +import com.lambda.interaction.handler.handlers.ContainerHandler.findContainers +import com.lambda.interaction.handler.handlers.ContainerHandler.findContainersWithSpace import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.task.RootTask import com.lambda.task.Task @@ -55,7 +55,7 @@ object TransferCommand : LambdaCommand( isItem(stack(ctx).value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val containers = selection.findContainersWithMaterial() + val containers = selection.findContainers() val indexedContainers = containers.withIndex() suggestMatching( @@ -96,11 +96,11 @@ object TransferCommand : LambdaCommand( isItem(stack().value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val fromContainer = ContainerHandler.containers().find { + val fromContainer = ContainerHandler.filteredContainers().find { it.name == from().value().split(".").last().trim() } ?: return@executeWithResult failure("From container not found") - val toContainer = ContainerHandler.containers().find { + val toContainer = ContainerHandler.filteredContainers().find { it.name == to().value().split(".").last().trim() } ?: return@executeWithResult failure("To container not found") diff --git a/src/main/kotlin/com/lambda/config/ConfigCategory.kt b/src/main/kotlin/com/lambda/config/ConfigCategory.kt index 989cd5c31..fc181fc12 100644 --- a/src/main/kotlin/com/lambda/config/ConfigCategory.kt +++ b/src/main/kotlin/com/lambda/config/ConfigCategory.kt @@ -25,7 +25,7 @@ import com.lambda.config.migration.ConfigMigrationHandler import com.lambda.core.Loadable import com.lambda.event.events.ClientEvent import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe -import com.lambda.interaction.handlers.BaritoneHandler.primary +import com.lambda.interaction.handler.handlers.BaritoneHandler.primary import com.lambda.threading.runIO import com.lambda.util.CommunicationUtils.info import com.lambda.util.CommunicationUtils.logError diff --git a/src/main/kotlin/com/lambda/config/blocks/BuildConfig.kt b/src/main/kotlin/com/lambda/config/blocks/BuildConfig.kt index 7e98fc835..6e7922008 100644 --- a/src/main/kotlin/com/lambda/config/blocks/BuildConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/BuildConfig.kt @@ -17,8 +17,8 @@ package com.lambda.config.blocks -import com.lambda.interaction.managers.rotating.Rotation.Companion.dist -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.dist +import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.util.Describable import com.lambda.util.NamedEnum import com.lambda.util.math.distSq diff --git a/src/main/kotlin/com/lambda/config/blocks/EntityColorSettings.kt b/src/main/kotlin/com/lambda/config/blocks/EntityColorSettings.kt index 4545e7d1c..ea27b3e0b 100644 --- a/src/main/kotlin/com/lambda/config/blocks/EntityColorSettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/EntityColorSettings.kt @@ -20,7 +20,7 @@ package com.lambda.config.blocks import com.lambda.config.Config import com.lambda.config.ConfigBlock import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.FriendHandler.isFriend +import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.util.EntityUtils.EntityGroup import com.lambda.util.EntityUtils.entityGroup import com.lambda.util.extension.blockColor diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index a24a0db62..be5c27139 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -58,7 +58,6 @@ interface InventoryConfig { WithMinItems("With Min Items", "Pick containers with the fewest matching items (or least space) first; useful for topping off or clearing leftovers."), WithMaxItems("With Max Items", "Pick containers with the most matching items (or most space) first; ideal for bulk moves with fewer transfers."); - context(_: SafeContext) fun materialComparator(selection: StackSelection) = when (this) { WithMaxItems -> compareBy { it.rank } @@ -70,7 +69,6 @@ interface InventoryConfig { .thenBy { it.name } } - context(_: SafeContext) fun spaceComparator(selection: StackSelection) = when (this) { WithMaxItems -> compareBy { it.rank } diff --git a/src/main/kotlin/com/lambda/config/blocks/RotationConfig.kt b/src/main/kotlin/com/lambda/config/blocks/RotationConfig.kt index a20530cf4..3f13dfa0b 100644 --- a/src/main/kotlin/com/lambda/config/blocks/RotationConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/RotationConfig.kt @@ -18,8 +18,8 @@ package com.lambda.config.blocks import com.lambda.event.events.TickEvent -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationMode interface RotationConfig { /** diff --git a/src/main/kotlin/com/lambda/config/blocks/RotationSettings.kt b/src/main/kotlin/com/lambda/config/blocks/RotationSettings.kt index cdaaf397c..c927e65a5 100644 --- a/src/main/kotlin/com/lambda/config/blocks/RotationSettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/RotationSettings.kt @@ -21,7 +21,7 @@ import com.lambda.config.Config import com.lambda.config.ConfigBlock import com.lambda.event.events.TickEvent import com.lambda.event.events.TickEvent.Companion.ALL_STAGES -import com.lambda.interaction.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationMode import kotlin.math.PI import kotlin.math.abs import kotlin.math.cos diff --git a/src/main/kotlin/com/lambda/config/blocks/TargetingSettings.kt b/src/main/kotlin/com/lambda/config/blocks/TargetingSettings.kt index 9c75d3008..b5a96aa53 100644 --- a/src/main/kotlin/com/lambda/config/blocks/TargetingSettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/TargetingSettings.kt @@ -22,10 +22,10 @@ import com.lambda.config.ConfigBlock import com.lambda.config.ConfigEditor.hide import com.lambda.config.withEdits import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.FriendHandler.isFriend -import com.lambda.interaction.managers.rotating.Rotation.Companion.dist -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.handler.handlers.FriendHandler.isFriend +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.dist +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.threading.runSafe import com.lambda.util.extension.fullHealth import com.lambda.util.math.distSq diff --git a/src/main/kotlin/com/lambda/event/events/RotationEvent.kt b/src/main/kotlin/com/lambda/event/events/RotationEvent.kt index c6f6f2a8a..c807c825e 100644 --- a/src/main/kotlin/com/lambda/event/events/RotationEvent.kt +++ b/src/main/kotlin/com/lambda/event/events/RotationEvent.kt @@ -18,7 +18,7 @@ package com.lambda.event.events import com.lambda.event.Event -import com.lambda.interaction.managers.rotating.RotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequest import net.minecraft.client.input.Input sealed class RotationEvent { diff --git a/src/main/kotlin/com/lambda/gui/MenuBar.kt b/src/main/kotlin/com/lambda/gui/MenuBar.kt index 2b205382b..30c164420 100644 --- a/src/main/kotlin/com/lambda/gui/MenuBar.kt +++ b/src/main/kotlin/com/lambda/gui/MenuBar.kt @@ -41,7 +41,7 @@ import com.lambda.imgui.flag.ImGuiCol import com.lambda.imgui.flag.ImGuiStyleVar import com.lambda.imgui.flag.ImGuiWindowFlags import com.lambda.imgui.type.ImBoolean -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.ModuleRegistry import com.lambda.module.ModuleRegistry.moduleNameMap import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/Sim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/Sim.kt index 5c9532b84..2bcf25681 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/Sim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/Sim.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.construction.simulation import com.lambda.interaction.construction.simulation.processing.PreProcessingData import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.results.GenericResult -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.util.math.distSq import com.lambda.util.math.vec3d import com.lambda.util.player.CheckedHit diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt index 2b15101ad..a2ff2c62f 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/BreakSim.kt @@ -28,15 +28,15 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial +import com.lambda.interaction.handler.handlers.ContainerHandler.findContainers import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackAndSlot import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.hotbar.HotbarManager -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarManager +import com.lambda.interaction.manager.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta import com.lambda.util.BlockUtils.instantBreakable @@ -166,7 +166,7 @@ class BreakSim private constructor(simInfo: SimInfo) } val hotbarCandidates = stackSelection - .findContainersWithMaterial(containerSelection) + .findContainers(containerSelection) .flatMap { stackSelection.filter(it.stacks) } if (hotbarCandidates.isEmpty()) { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt index e81c88b73..46ea402dc 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/checks/InteractSim.kt @@ -27,15 +27,15 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.ContainerHandler.findContainersWithMaterial +import com.lambda.interaction.handler.handlers.ContainerHandler.findContainers import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation +import com.lambda.interaction.manager.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.util.BlockUtils.blockState import com.lambda.util.EntityUtils.getPositionsWithinHitboxXZ import com.lambda.util.PlaceDirection @@ -213,7 +213,7 @@ class InteractSim private constructor(simInfo: InteractSimInfo) val stackSelection = item?.select() ?: selectStack { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } val containerSelection = selectContainer { ofAnyType(Container.Rank.Hotbar) } - val container = stackSelection.findContainersWithMaterial(containerSelection).firstOrNull() ?: run { + val container = stackSelection.findContainers(containerSelection).firstOrNull() ?: run { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null } diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt index 5fbdb6fa7..a11a43628 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.construction.simulation.context import com.lambda.context.Automated import com.lambda.graphics.mc.RenderBuilder import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.managers.rotating.RotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequest import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.emptyState import net.minecraft.block.BlockState diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BuildContext.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BuildContext.kt index 676d99b47..de4669021 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BuildContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BuildContext.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.construction.simulation.context import com.lambda.config.blocks.ActionConfig import com.lambda.context.Automated import com.lambda.interaction.construction.simulation.result.Drawable -import com.lambda.interaction.managers.rotating.RotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequest import com.lambda.threading.runSafe import net.minecraft.block.BlockState import net.minecraft.util.hit.BlockHitResult diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/InteractContext.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/InteractContext.kt index a431da618..6ab4617b6 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/InteractContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/InteractContext.kt @@ -20,8 +20,8 @@ package com.lambda.interaction.construction.simulation.context import com.lambda.context.Automated import com.lambda.graphics.mc.RenderBuilder import com.lambda.interaction.construction.simulation.processing.PreProcessingInfo -import com.lambda.interaction.managers.interacting.InteractRequest -import com.lambda.interaction.managers.rotating.RotationRequest +import com.lambda.interaction.manager.managers.interacting.InteractRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequest import net.minecraft.block.BlockState import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.math.BlockPos diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Contextual.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Contextual.kt index 9f25ed94f..56a7395f3 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Contextual.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Contextual.kt @@ -21,8 +21,8 @@ import com.lambda.config.blocks.ActionConfig import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.context.InteractContext -import com.lambda.interaction.managers.hotbar.HotbarManager -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.hotbar.HotbarManager +import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.threading.runSafe import com.lambda.util.BlockUtils import net.minecraft.block.Blocks diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 1ac15b8ed..bbfda574b 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -31,11 +31,11 @@ import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable -import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.handlers.ContainerHandler.transferByTask +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task +import com.lambda.task.tasks.ContainerTransferTask.Companion.transfer import net.minecraft.block.BlockState import net.minecraft.item.Item import net.minecraft.util.math.BlockPos @@ -119,9 +119,10 @@ sealed class BreakResult : BuildResult() { context(task: Task<*>, _: AutomatedSafeContext) override fun resolve() { - selectStack { - inverted { isItem(badItem) } - }.transferByTask(HotbarContainer)?.softFail()?.execute(task) + selectStack { inverted { isItem(badItem) } } + .transfer(HotbarContainer) + ?.softFail() + ?.execute(task) } override fun compareResult(other: ComparableResult) = diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index 9762b191d..4918d61f5 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -26,11 +26,11 @@ import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable -import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.handlers.ContainerHandler.transferByTask +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task +import com.lambda.task.tasks.ContainerTransferTask.Companion.transfer import net.minecraft.client.data.TextureMap.side import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos @@ -100,7 +100,10 @@ sealed class GenericResult : BuildResult() { context(task: Task<*>, _: AutomatedSafeContext) override fun resolve() { - neededSelection.transferByTask(HotbarContainer)?.softFail()?.execute(task) + neededSelection + .transfer(HotbarContainer) + ?.softFail() + ?.execute(task) } override fun RenderBuilder.render() { diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt index a05e9f570..dccd49963 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/InteractResult.kt @@ -27,7 +27,7 @@ import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import net.minecraft.block.BlockState import net.minecraft.entity.Entity import net.minecraft.item.Item diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt index efa0cbaf6..62d15fb0f 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/PreSimResult.kt @@ -24,7 +24,7 @@ import com.lambda.interaction.construction.simulation.result.ComparableResult import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import net.minecraft.block.BlockState import net.minecraft.util.math.BlockPos import java.awt.Color diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index 1ac813f5f..f6ccb54ee 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.construction.verify import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.ContainerHandler.findDisposable +import com.lambda.interaction.handler.handlers.ContainerHandler.findDisposable import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.emptyState import com.lambda.util.BlockUtils.isEmpty diff --git a/src/main/kotlin/com/lambda/interaction/managers/PostActionHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/PostActionHandler.kt similarity index 91% rename from src/main/kotlin/com/lambda/interaction/managers/PostActionHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/PostActionHandler.kt index b1d2b7a44..5994bb01e 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/PostActionHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/PostActionHandler.kt @@ -15,14 +15,15 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers +package com.lambda.interaction.handler import com.lambda.context.Automated import com.lambda.event.events.ConnectionEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler +import com.lambda.interaction.manager.ActionInfo import com.lambda.util.collections.LimitedDecayQueue /** diff --git a/src/main/kotlin/com/lambda/interaction/handlers/BaritoneHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/BaritoneHandler.kt similarity index 99% rename from src/main/kotlin/com/lambda/interaction/handlers/BaritoneHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/BaritoneHandler.kt index ff939f26c..b0959604f 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/BaritoneHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/BaritoneHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers +package com.lambda.interaction.handler.handlers import baritone.api.BaritoneAPI import baritone.api.IBaritone diff --git a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt similarity index 57% rename from src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index e1db759de..e7b91ede3 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -15,29 +15,30 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers +package com.lambda.interaction.handler.handlers +import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext -import com.lambda.context.SafeContext import com.lambda.core.Loadable import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.inventory.ContainerMarker import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.containers.external.ChestContainer import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer +import com.lambda.task.Task.Ta5kBuilder import com.lambda.util.BlockUtils.blockEntity -import com.lambda.util.ReflectionUtils +import com.lambda.util.ReflectionUtils.getInstances import com.lambda.util.extension.containerStacks import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.screen.GenericContainerScreenHandler import net.minecraft.screen.ScreenHandlerType -import net.minecraft.screen.slot.Slot // ToDo: Make this a Configurable to save container caches. Should use a cached region based storage system. @Suppress("unused") @@ -45,9 +46,23 @@ object ContainerHandler : Loadable { private val containers: List get() = compileContainers + runtimeContainers - private val compileContainers = ReflectionUtils.getInstances() + private val compileContainers = getInstances() private val runtimeContainers = mutableSetOf() + context(automated: Automated) + val filteredContainers + get() = + containers + .flatMap { setOf(it) + it.shulkerContainers } + .filter { automated.inventoryConfig.containerSelection.matches(it) } + .sorted() + + val allContainers + get() = + containers + .flatMap { setOf(it) + it.shulkerContainers } + .sorted() + var lastInteractedBlockEntity: BlockEntity? = null override fun load() = "Loaded ${compileContainers.size} containers" @@ -78,81 +93,76 @@ object ContainerHandler : Loadable { .filterIsInstance() .find { it.blockPos == block.pos - }?.update(stacks) ?: runtimeContainers.add(ChestContainer(stacks, block.pos)) + }?.update(stacks) ?: runtimeContainers.add(ChestContainer(block.pos, stacks)) } } lastInteractedBlockEntity = null } } - context(_: SafeContext) - fun containers() = containers.flatMap { setOf(it) + it.shulkerContainers }.sorted() - + @ContainerMarker context(automatedSafeContext: AutomatedSafeContext) fun StackSelection.transfer(destination: Container) = with(automatedSafeContext) { - findContainerWithMaterial( - inventoryConfig.containerSelection - )?.transfer(this@transfer, destination) + findContainer(inventoryConfig.containerSelection) + ?.transfer(this@transfer, destination) ?: false } - context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.transferByTask(destination: Container) = - with(automatedSafeContext) { - findContainerWithMaterial()?.transferByTask(this@transferByTask, destination) - } - - context(_: SafeContext) - fun findContainer( - block: (Container) -> Boolean, - ): Container? = containers().find(block) - - context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.findContainerWithMaterial( - containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ): Container? = findContainersWithMaterial(containerSelection).firstOrNull() - - context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.findContainersWithMaterial( - containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection, - ): List = - containers() + @ContainerMarker + context(_: Automated) + fun findContainer(block: (Container) -> Boolean) = filteredContainers.find(block) + + @ContainerMarker + context(automated: Automated) + fun StackSelection.findContainer( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + ) = findContainers(containerSelection).firstOrNull() + + @ContainerMarker + context(automated: Automated) + fun StackSelection.findContainers( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + ) = + filteredContainers .filter { containerSelection.matches(it) } .filter { it.stackCount(this) >= count } - .sortedWith(automatedSafeContext.inventoryConfig.providerPriority.materialComparator(this)) + .sortedWith(automated.inventoryConfig.providerPriority.materialComparator(this)) - context(automatedSafeContext: AutomatedSafeContext) + @ContainerMarker + context(automated: Automated) fun StackSelection.findContainerWithSpace( - containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ): Container? = findContainersWithSpace(containerSelection).firstOrNull() + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + ) = findContainersWithSpace(containerSelection).firstOrNull() - context(automatedSafeContext: AutomatedSafeContext) + @ContainerMarker + context(automated: Automated) fun StackSelection.findContainersWithSpace( - containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ): List = - containers() + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + ) = + filteredContainers .filter { containerSelection.matches(it) } .filter { it.spaceAvailable(this) >= count } - .sortedWith(automatedSafeContext.inventoryConfig.providerPriority.spaceComparator(this)) - - context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.findSlotWithMaterial( - containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ) = findSlotsWithMaterial(containerSelection).firstOrNull() - - context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.findSlotsWithMaterial( - containerSelection: ContainerSelection = automatedSafeContext.inventoryConfig.containerSelection - ): List = - findContainersWithMaterial(containerSelection) - .flatMap { filter(it.slots) } - - - context(automatedSafeContext: AutomatedSafeContext) - fun findDisposable() = containers().find { container -> - automatedSafeContext.inventoryConfig.disposables.any { container.stackCount(it.asItem().select()) > 0 } - } + .sortedWith(automated.inventoryConfig.providerPriority.spaceComparator(this)) + + @ContainerMarker + context(automated: Automated) + fun StackSelection.findSlot( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + ) = findSlots(containerSelection).firstOrNull() + + @ContainerMarker + context(automated: Automated) + fun StackSelection.findSlots( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + ) = findContainers(containerSelection).flatMap { filter(it.slots) } + + @ContainerMarker + context(automated: Automated) + fun findDisposable() = + filteredContainers.find { container -> + automated.inventoryConfig.disposables.any { container.stackCount(it.asItem().select(1)) > 0 } + } class NoContainerFound(selection: StackSelection) : Exception("No container found matching $selection") } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/handlers/FriendHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/FriendHandler.kt similarity index 99% rename from src/main/kotlin/com/lambda/interaction/handlers/FriendHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/FriendHandler.kt index 9afa8a5d3..b2c02b37e 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/FriendHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/FriendHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers +package com.lambda.interaction.handler.handlers import com.lambda.Lambda import com.lambda.command.CommandRegistry diff --git a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt similarity index 99% rename from src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt index 73157e79f..56fe6eb36 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers +package com.lambda.interaction.handler.handlers import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent diff --git a/src/main/kotlin/com/lambda/interaction/handlers/PingHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/PingHandler.kt similarity index 97% rename from src/main/kotlin/com/lambda/interaction/handlers/PingHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/PingHandler.kt index 6913519a0..e8720a75e 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/PingHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/PingHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers +package com.lambda.interaction.handler.handlers import com.lambda.core.Loadable import com.lambda.event.events.PacketEvent diff --git a/src/main/kotlin/com/lambda/interaction/handlers/TimerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/TimerHandler.kt similarity index 96% rename from src/main/kotlin/com/lambda/interaction/handlers/TimerHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/TimerHandler.kt index 0bd755ea9..d9d620358 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/TimerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/TimerHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers +package com.lambda.interaction.handler.handlers import com.lambda.core.Loadable import com.lambda.event.EventFlow.post diff --git a/src/main/kotlin/com/lambda/interaction/handlers/breaking/BrokenBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt similarity index 93% rename from src/main/kotlin/com/lambda/interaction/handlers/breaking/BrokenBlockHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt index b34ccf2c6..3086d5130 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/breaking/BrokenBlockHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers.breaking +package com.lambda.interaction.handler.handlers.breaking import com.lambda.config.automation.AutomationConfig.Companion.DEFAULT import com.lambda.config.blocks.BreakConfig.BreakConfirmationMode @@ -24,11 +24,11 @@ import com.lambda.event.events.EntityEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.processing.ProcessorRegistry -import com.lambda.interaction.handlers.breaking.RebreakHandler.rebreak -import com.lambda.interaction.managers.PostActionHandler -import com.lambda.interaction.managers.breaking.BreakInfo -import com.lambda.interaction.managers.breaking.BreakManager.lastPosStarted -import com.lambda.interaction.managers.breaking.BreakManager.matchesBlockItem +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.rebreak +import com.lambda.interaction.handler.PostActionHandler +import com.lambda.interaction.manager.managers.breaking.BreakInfo +import com.lambda.interaction.manager.managers.breaking.BreakManager.lastPosStarted +import com.lambda.interaction.manager.managers.breaking.BreakManager.matchesBlockItem import com.lambda.module.modules.client.Client import com.lambda.module.modules.client.Client.verboseDebug import com.lambda.threading.runGameScheduled diff --git a/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt similarity index 83% rename from src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt index 122414983..4091947d9 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers.breaking +package com.lambda.interaction.handler.handlers.breaking import com.lambda.config.blocks.BreakConfig import com.lambda.context.SafeContext @@ -24,20 +24,20 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.BreakContext -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.destroyBlock -import com.lambda.interaction.handlers.breaking.RebreakHandler.rebreak -import com.lambda.interaction.handlers.packet.PacketLimitHandler -import com.lambda.interaction.handlers.packet.PacketType -import com.lambda.interaction.managers.breaking.BreakInfo -import com.lambda.interaction.managers.breaking.BreakManager -import com.lambda.interaction.managers.breaking.BreakManager.calcBreakDelta -import com.lambda.interaction.managers.breaking.BreakRequest +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.rebreak +import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler +import com.lambda.interaction.handler.handlers.packet.PacketType +import com.lambda.interaction.manager.managers.breaking.BreakInfo +import com.lambda.interaction.manager.managers.breaking.BreakManager +import com.lambda.interaction.manager.managers.breaking.BreakManager.calcBreakDelta +import com.lambda.interaction.manager.managers.breaking.BreakRequest import com.lambda.threading.runSafeAutomated import com.lambda.util.player.PlayerUtils.swingHand import net.minecraft.util.Hand /** - * Designed to track the latest primary-broken [com.lambda.interaction.managers.breaking.BreakInfo] in order to exploit a flaw in Minecraft's code that allows + * Designed to track the latest primary-broken [BreakInfo] in order to exploit a flaw in Minecraft's code that allows * the user to break any block placed in said position using the progress from the previously broken block. */ object RebreakHandler { @@ -60,7 +60,7 @@ object RebreakHandler { /** * Tests to see if the [BreakInfo] can be accepted. If not, nothing happens. Otherwise, - * the [rebreak] is set, and the [com.lambda.interaction.managers.breaking.BreakRequest.onReBreakStart] callback is invoked. + * the [rebreak] is set, and the [BreakRequest.onReBreakStart] callback is invoked. */ context(safeContext: SafeContext) fun offerRebreak(info: BreakInfo) { diff --git a/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakResult.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakResult.kt similarity index 87% rename from src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakResult.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakResult.kt index 27dc43bbb..c98b4a6bf 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/breaking/RebreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakResult.kt @@ -15,9 +15,9 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers.breaking +package com.lambda.interaction.handler.handlers.breaking -import com.lambda.interaction.managers.breaking.BreakInfo +import com.lambda.interaction.manager.managers.breaking.BreakInfo sealed class RebreakResult { data object Ignored : RebreakResult() diff --git a/src/main/kotlin/com/lambda/interaction/handlers/interacting/InteractedBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt similarity index 91% rename from src/main/kotlin/com/lambda/interaction/handlers/interacting/InteractedBlockHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt index b1c1db359..59aeaa843 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/interacting/InteractedBlockHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt @@ -15,15 +15,15 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers.interacting +package com.lambda.interaction.handler.handlers.interacting import com.lambda.config.automation.AutomationConfig import com.lambda.config.blocks.InteractConfig import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.PostActionHandler -import com.lambda.interaction.managers.interacting.InteractInfo -import com.lambda.interaction.managers.interacting.InteractManager.placeSound +import com.lambda.interaction.handler.PostActionHandler +import com.lambda.interaction.manager.managers.interacting.InteractInfo +import com.lambda.interaction.manager.managers.interacting.InteractManager.placeSound import com.lambda.module.modules.client.Client import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.matches diff --git a/src/main/kotlin/com/lambda/interaction/handlers/packet/PacketLimitHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt similarity index 97% rename from src/main/kotlin/com/lambda/interaction/handlers/packet/PacketLimitHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt index aa11a5d9e..2b6fdf428 100644 --- a/src/main/kotlin/com/lambda/interaction/handlers/packet/PacketLimitHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handlers.packet +package com.lambda.interaction.handler.handlers.packet import com.lambda.config.blocks.BuildConfig import com.lambda.context.Automated diff --git a/src/main/kotlin/com/lambda/interaction/inventory/ContainerMarker.kt b/src/main/kotlin/com/lambda/interaction/inventory/ContainerMarker.kt new file mode 100644 index 000000000..fa8982066 --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/ContainerMarker.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory + +@DslMarker +annotation class ContainerMarker \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt index 328255230..332783fd3 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt @@ -27,13 +27,13 @@ class ContainerSelection( val selector: (Container) -> Boolean, val comparator: Comparator = compareBy { it.rank } ) { - @ContainerSelectionMarker + @ContainerMarker fun bestMatch(containers: Iterable) = filter(containers).firstOrNull() - @ContainerSelectionMarker + @ContainerMarker fun matches(container: Container): Boolean = selector(container) - @ContainerSelectionMarker + @ContainerMarker fun filter(containers: Iterable) = containers .filter(selector) @@ -45,11 +45,8 @@ class ContainerSelection( } } -@DslMarker -annotation class ContainerSelectionMarker - @Suppress("unused") -@ContainerSelectionMarker +@ContainerMarker class ContainerSelectionBuilder private constructor() { private var selector: (Container) -> Boolean = { true } private var comparator: Comparator = compareBy { it.rank } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index 81360e2f5..9e59af8b7 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -44,21 +44,21 @@ class StackSelection( ) { val optimalStack = itemStack ?: item?.let { ItemStack(it, count) } - @StackSelectionMarker + @ContainerMarker fun bestMatch(stacks: Iterable) = filter(stacks).firstOrNull() - @StackSelectionMarker + @ContainerMarker fun bestMatch(slots: Iterable) = filter(slots).firstOrNull() - @StackSelectionMarker + @ContainerMarker fun matches(stack: ItemStack) = if (inShulkerBox) stack.shulkerBoxStacks.any { selector(it, null) } else selector(stack, null) - @StackSelectionMarker + @ContainerMarker fun matches(slot: Slot): Boolean = if (inShulkerBox) slot.stack.shulkerBoxStacks.any { selector(it, null) } else selector(slot.stack, slot) - @StackSelectionMarker + @ContainerMarker @JvmName("filter1") fun filter(stacks: Iterable) = stacks @@ -66,7 +66,7 @@ class StackSelection( .map { StackAndSlot(it, null) } .sortedWith(comparator) .map { it.stack } - @StackSelectionMarker + @ContainerMarker @JvmName("filter2") fun filter(slots: Iterable) = slots @@ -81,11 +81,8 @@ class StackSelection( } } -@DslMarker -private annotation class StackSelectionMarker - @Suppress("unused") -@StackSelectionMarker +@ContainerMarker class StackSelectionBuilder private constructor(private val count: Int = 0) { private var selector: (ItemStack, Slot?) -> Boolean = { _, _ -> true } private var item: Item? = null @@ -232,10 +229,10 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { companion object { private val efficientToolCache = Collections.synchronizedMap(mutableMapOf()) - @StackSelectionMarker + @ContainerMarker fun Item.select(count: Int = 0) = selectStack(count) { isItem(this@select) } - @StackSelectionMarker + @ContainerMarker fun ItemStack.select(count: Int = 0) = selectStack(count) { isItemStack(this@select) } fun selectStack( diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 666442a33..1053ea0c6 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -24,13 +24,13 @@ import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.external.ShulkerBoxContainer -import com.lambda.interaction.managers.inventory.InvRequestBuilder -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.TaskGenerator import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.ContainerTransferTask -import com.lambda.task.tasks.NoopTask.Companion.noop +import com.lambda.task.tasks.NoopTask.Companion.noopTask import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.empty @@ -111,14 +111,14 @@ abstract class Container( ShulkerBoxContainer( slot.stack.shulkerBoxStacks, containedIn = this@Container, - shulkerSlot = slot + slot = slot ) }?.toSet() ?: stacks.map { stack -> ShulkerBoxContainer( stack.shulkerBoxStacks, containedIn = this@Container, - shulkerSlot = null + slot = null ) }.toSet() @@ -133,7 +133,7 @@ abstract class Container( open fun accessThen( closeAfter: Boolean = true, afterClose: TaskOrNullGenerator? = null, - afterOpen: TaskGenerator = { noop() } + afterOpen: TaskGenerator = { noopTask() } ) = with(automatedSafeContext) { afterOpen(Unit).also { if (closeAfter && afterClose != null) { @@ -142,6 +142,28 @@ abstract class Container( } } + context(automatedSafeContext: AutomatedSafeContext) + fun transfer(selection: StackSelection, toContainer: Container): Boolean = + with(automatedSafeContext) { + val (fromSlot, toSlot) = getTransferSlots(selection, toContainer) + if (fromSlot == null || toSlot == null) return false + return transfer(fromSlot, toSlot, toContainer) + } + + context(_: Automated) + fun getTransferSlots(selection: StackSelection, destination: Container): Pair = + Pair(getSlot(selection), destination.getReplaceSlot()) + + context(automatedSafeContext: AutomatedSafeContext) + fun transfer(fromSlot: Slot, toSlot: Slot, toContainer: Container): Boolean { + val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@Container, toContainer) + if (transferEvent.post().isCanceled()) return false + return automatedSafeContext.inventoryRequest { + if (swapMethodPriority > toContainer.swapMethodPriority) transfer(fromSlot, toSlot) + else with(toContainer) { transfer(toSlot, fromSlot) } + }.submit().done + } + context(safeContext: SafeContext) open fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { if (fromHere.stack.isEmpty) moveSlot(toSlot.id, fromHere.id) @@ -151,19 +173,6 @@ abstract class Container( } } - context(automatedSafeContext: AutomatedSafeContext) - fun transfer(selection: StackSelection, destination: Container): Boolean = - with(automatedSafeContext) { - val fromSlot = getSlot(selection) ?: return false - val toSlot = destination.getReplaceSlot() ?: return false - val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@Container, destination) - if (transferEvent.post().isCanceled()) return false - return inventoryRequest { - if (swapMethodPriority > destination.swapMethodPriority) transfer(fromSlot, toSlot) - else with(destination) { transfer(toSlot, fromSlot) } - }.submit().done - } - context(automated: Automated) fun transferByTask(stackSelection: StackSelection, destination: Container, failIfNoMaterial: Boolean = false) = ContainerTransferTask(this, destination, stackSelection, failIfNoMaterial, automated) @@ -191,6 +200,7 @@ abstract class Container( ShulkerBox, EnderChest, PlacedShulkerBox, + PlacedEnderChest, Chest, Stash } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt new file mode 100644 index 000000000..94f48fffa --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container + +import net.minecraft.screen.slot.Slot + +interface NestedContainer { + val slotCache: Slot +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt new file mode 100644 index 000000000..7d6d9d051 --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container + +import com.lambda.interaction.inventory.container.containers.external.StashContainer + +interface PlacedContainer { + val stash: StashContainer? +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt index dc115fe6d..fd0e0135f 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt @@ -21,7 +21,7 @@ import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InvRequestBuilder +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt index a4e2cd9fd..9949c3d88 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InvRequestBuilder +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.hotbarSlots import com.lambda.util.player.SlotUtils.hotbarStacks import com.lambda.util.text.buildText diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt index ecbdff3cf..c87db7077 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InvRequestBuilder +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.mainHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt index 9746bb349..cbe16ada8 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.managers.inventory.InvRequestBuilder +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.offHandSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt index 586b77644..5a2cd8de9 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt @@ -17,34 +17,42 @@ package com.lambda.interaction.inventory.container.containers.external -import com.lambda.Lambda +import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext -import com.lambda.interaction.handlers.ContainerHandler +import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.TaskGenerator import com.lambda.task.TaskOrNullGenerator +import com.lambda.task.tasks.NoopTask.Companion.noopTask import com.lambda.task.tasks.OpenContainerTask +import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer +import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted import com.lambda.util.text.literal +import net.minecraft.block.ChestBlock import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.item.ItemStack import net.minecraft.screen.ScreenHandler +import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos data class ChestContainer( - override var stacks: List, val blockPos: BlockPos, - val containedInStash: StashContainer? = null -) : Container(Rank.Chest), ExternalContainer { + override var stacks: List, + override val stash: StashContainer? = null +) : Container(Rank.Chest), ExternalContainer, PlacedContainer { override val slots get(): List = - ContainerHandler.lastInteractedBlockEntity?.let { blockEntity -> + lastInteractedBlockEntity?.let { blockEntity -> if (blockEntity is ChestBlockEntity && blockEntity.pos == blockPos) { - Lambda.mc.player?.currentScreenHandler?.containerSlots + mc.player?.currentScreenHandler?.containerSlots } else emptyList() } ?: emptyList() @@ -52,20 +60,31 @@ data class ChestContainer( buildText { literal("Chest at ") highlighted(blockPos.toShortString()) - containedInStash?.let { stash -> + stash?.let { stash -> literal(" (contained in ") highlighted(stash.name) literal(")") } } - context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( - exitAfter: Boolean, - afterOpen: TaskOrNullGenerator = { null }, - afterClose: TaskOrNullGenerator = { null } - ): Task<*> = - OpenContainerTask(blockPos, automatedSafeContext) - .thenOrNull(afterOpen) - .then { if (exitAfter) automatedSafeContext.player.closeHandledScreen() } + override val isAccessed + get() = lastInteractedBlockEntity?.let { blockEntity -> + blockEntity.pos == blockPos && + blockEntity.cachedState.block is ChestBlock && + mc.player?.currentScreenHandler?.type == ScreenHandlerType.GENERIC_9X3 + } ?: false + + context(_: AutomatedSafeContext) + override fun accessThen( + closeAfter: Boolean, + afterClose: TaskOrNullGenerator?, + afterOpen: TaskGenerator + ) = + openContainer(blockPos).then { + afterOpen(Unit).thenOrNull { + if (closeAfter) { + simpleAction("Close inventory") { player.closeHandledScreen() } + } else null + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt index f769bd802..f81b87ddf 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt @@ -19,48 +19,74 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext -import com.lambda.interaction.handlers.ContainerHandler +import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.task.TaskGenerator import com.lambda.task.TaskOrNullGenerator -import com.lambda.task.tasks.AcquirePlacedBlockTask -import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock +import com.lambda.task.tasks.AcquireStackTask.Companion.acquireStack +import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect +import com.lambda.task.tasks.NoopTask.Companion.noopTask import com.lambda.task.tasks.OpenContainerTask +import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer +import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer +import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal -import net.minecraft.block.Blocks import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.screen.ScreenHandlerType +import kotlin.comparisons.then object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { override val slots get() = - if (ContainerHandler.lastInteractedBlockEntity is EnderChestBlockEntity) { - mc.player?.currentScreenHandler?.containerSlots ?: emptyList() - } else emptyList() + if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() + else emptyList() override var stacks = emptyList() override val description = buildText { literal("Ender Chest") } + override val isAccessed + get() = + lastInteractedBlockEntity?.let { blockEntity -> + blockEntity is EnderChestBlockEntity && + mc.player?.currentScreenHandler?.type == ScreenHandlerType.GENERIC_9X3 + } ?: false + context(automatedSafeContext: AutomatedSafeContext) override fun accessThen( closeAfter: Boolean, afterClose: TaskOrNullGenerator?, afterOpen: TaskGenerator ) = - AcquirePlacedBlockTask( - Blocks.ENDER_CHEST, - automated = automatedSafeContext - ).then { pos -> - OpenContainerTask(pos, automatedSafeContext).then { - afterOpen.invoke(automatedSafeContext, Unit).thenOrNull { - if (closeAfter) { - player.closeHandledScreen() - automatedSafeContext.breakAndCollectBlock(pos, lifeMaintenance = false) - } else null + with(automatedSafeContext) { + if (!isAccessed) { + acquireStack(Items.ENDER_CHEST.select()).then { slot -> + placeContainer(slot).then { pos -> + openContainer(pos).then { + afterOpen(Unit).thenOrNull { + if (closeAfter) { + simpleAction("Close inventory") { player.closeHandledScreen() }.then { + breakAndCollect(pos, lifeMaintenance = false).thenOrNull { + afterClose?.invoke(this, Unit) + } + } + } else null + } + } + } } + } else afterOpen(Unit).thenOrNull { + if (closeAfter) { + simpleAction("Close inventory") { mc.player?.closeHandledScreen() }.thenOrNull { + afterClose?.invoke(this, Unit) + } + } else null } } + } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt index d4f1cca4e..697a52783 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt @@ -17,21 +17,69 @@ package com.lambda.interaction.inventory.container.containers.external +import com.lambda.Lambda.mc +import com.lambda.context.AutomatedSafeContext +import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.PlacedContainer +import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator +import com.lambda.task.tasks.NoopTask.Companion.noopTask +import com.lambda.task.tasks.OpenContainerTask +import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction +import com.lambda.util.extension.containerSlots +import com.lambda.util.text.buildText +import com.lambda.util.text.highlighted +import com.lambda.util.text.literal +import net.minecraft.block.Block import net.minecraft.item.ItemStack +import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot -import net.minecraft.text.Text import net.minecraft.util.math.BlockPos class PlacedShulkerBoxContainer( val blockPos: BlockPos, - val -) : Container(Rank.PlacedShulkerBox) { - override val slots: List - get() = TODO("Not yet implemented") + val block: Block, + override val stash: StashContainer?, override var stacks: List - get() = TODO("Not yet implemented") - set(value) {} - override val description: Text - get() = TODO("Not yet implemented") +) : Container(Rank.PlacedShulkerBox), PlacedContainer { + override val slots: List + get() = + if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() + else emptyList() + + override val description = + buildText { + literal("Placed shulker box at ") + highlighted(blockPos.toShortString()) + stash?.let { stash -> + literal(" (contained in ") + highlighted(stash.name) + literal(")") + } + } + + override val isAccessed + get() = lastInteractedBlockEntity?.let { blockEntity -> + blockEntity.pos == blockPos && + blockEntity.cachedState.block == block && + mc.player?.currentScreenHandler?.type == ScreenHandlerType.SHULKER_BOX + } ?: false + + context(automatedSafeContext: AutomatedSafeContext) + override fun accessThen( + closeAfter: Boolean, + afterClose: TaskOrNullGenerator?, + afterOpen: TaskGenerator + ) = + run { + if (!isAccessed) OpenContainerTask(blockPos, automated = automatedSafeContext) + else noopTask() + }.then { + afterOpen(Unit).thenOrNull { + if (closeAfter) { + simpleAction("Close Inventory") { automatedSafeContext.player.closeHandledScreen() } + } else null + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index eace9fcb3..9d4091153 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -20,15 +20,16 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.ContainerHandler.lastInteractedBlockEntity +import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.task.Task +import com.lambda.interaction.inventory.container.NestedContainer import com.lambda.task.TaskGenerator import com.lambda.task.TaskOrNullGenerator -import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock -import com.lambda.task.tasks.OpenContainerTask -import com.lambda.task.tasks.PlaceContainerTask +import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect +import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer +import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer +import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction import com.lambda.threading.runSafe import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText @@ -36,44 +37,56 @@ import com.lambda.util.text.highlighted import com.lambda.util.text.literal import net.minecraft.block.entity.ShulkerBoxBlockEntity import net.minecraft.item.ItemStack +import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot +import net.minecraft.util.math.BlockPos data class ShulkerBoxContainer( override var stacks: List, val containedIn: Container, - val shulkerSlot: Slot?, -) : Container(Rank.ShulkerBox), ExternalContainer { + override val slotCache: Slot, +) : Container(Rank.ShulkerBox), ExternalContainer, NestedContainer { override val slots get(): List = - if (lastInteractedBlockEntity is ShulkerBoxBlockEntity) - mc.player?.currentScreenHandler?.containerSlots ?: emptyList() + if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() else emptyList() override val description = buildText { - highlighted(shulkerSlot?.stack?.name?.string ?: "Shulker Box") + highlighted(slotCache.stack.name.string) literal(" in ") highlighted(containedIn.name) - literal(" in slot ") - highlighted("${runSafe { slotInContainer }}") + literal(" in slot $slotCache") } - context(_: SafeContext) - private val slotInContainer: Int get() = containedIn.slots.indexOf(shulkerSlot) + private var placed = false + private var blockPos: BlockPos? = null - override val isAccessed get() = lastInteractedBlockEntity is ShulkerBoxBlockEntity + override val isAccessed + get() = + lastInteractedBlockEntity?.let { blockEntity -> + blockEntity is ShulkerBoxBlockEntity && + blockEntity.pos == blockPos && + mc.player?.currentScreenHandler?.type == ScreenHandlerType.SHULKER_BOX + } ?: false context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen(closeAfter: Boolean, afterClose: TaskOrNullGenerator?, afterOpen: TaskGenerator): Task<*> { - return PlaceContainerTask(shulkerSlot, automatedSafeContext).then { pos -> - OpenContainerTask(pos, automatedSafeContext).then { - afterOpen.invoke(automatedSafeContext, Unit).thenOrNull { - if (closeAfter) { - player.closeHandledScreen() - automatedSafeContext.breakAndCollectBlock(pos) - } else null - } + override fun accessThen( + closeAfter: Boolean, + afterClose: TaskOrNullGenerator?, + afterOpen: TaskGenerator + ) = + with(automatedSafeContext) { + if (!isAccessed) { + + } else afterOpen(Unit).thenOrNull { + if (closeAfter) { + simpleAction("Close inventory") { player.closeHandledScreen() }.then { + breakAndCollect(blockPos, lifeMaintenance = false).thenOrNull { + afterClose?.invoke(this, Unit) + } + } + } else null } } - } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/managers/ActionInfo.kt b/src/main/kotlin/com/lambda/interaction/manager/ActionInfo.kt similarity index 96% rename from src/main/kotlin/com/lambda/interaction/managers/ActionInfo.kt rename to src/main/kotlin/com/lambda/interaction/manager/ActionInfo.kt index 6d457e8d3..dfaf5548e 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/ActionInfo.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/ActionInfo.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers +package com.lambda.interaction.manager import com.lambda.interaction.construction.simulation.context.BuildContext diff --git a/src/main/kotlin/com/lambda/interaction/managers/Manager.kt b/src/main/kotlin/com/lambda/interaction/manager/Manager.kt similarity index 97% rename from src/main/kotlin/com/lambda/interaction/managers/Manager.kt rename to src/main/kotlin/com/lambda/interaction/manager/Manager.kt index 7da159c1f..842806fce 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/Manager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/Manager.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers +package com.lambda.interaction.manager import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext @@ -25,7 +25,7 @@ import com.lambda.event.Event import com.lambda.event.events.TickEvent import com.lambda.event.events.TickEvent.Companion.ALL_STAGES import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.ManagerUtils.accumulatedManagerPriority +import com.lambda.interaction.manager.managers.ManagerUtils.accumulatedManagerPriority import com.lambda.threading.runSafeAutomated import kotlin.reflect.KClass diff --git a/src/main/kotlin/com/lambda/interaction/managers/ManagerUtils.kt b/src/main/kotlin/com/lambda/interaction/manager/ManagerUtils.kt similarity index 96% rename from src/main/kotlin/com/lambda/interaction/managers/ManagerUtils.kt rename to src/main/kotlin/com/lambda/interaction/manager/ManagerUtils.kt index 9a5f193bd..ae2b3589c 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/ManagerUtils.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/ManagerUtils.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers +package com.lambda.interaction.manager import com.lambda.util.ReflectionUtils.getInstances import net.minecraft.util.math.BlockPos diff --git a/src/main/kotlin/com/lambda/interaction/managers/PositionBlocking.kt b/src/main/kotlin/com/lambda/interaction/manager/PositionBlocking.kt similarity index 96% rename from src/main/kotlin/com/lambda/interaction/managers/PositionBlocking.kt rename to src/main/kotlin/com/lambda/interaction/manager/PositionBlocking.kt index 14c3bf240..e10a9d2ba 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/PositionBlocking.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/PositionBlocking.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers +package com.lambda.interaction.manager import net.minecraft.util.math.BlockPos diff --git a/src/main/kotlin/com/lambda/interaction/managers/Request.kt b/src/main/kotlin/com/lambda/interaction/manager/Request.kt similarity index 97% rename from src/main/kotlin/com/lambda/interaction/managers/Request.kt rename to src/main/kotlin/com/lambda/interaction/manager/Request.kt index 61fa20be2..9bdcd58c6 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/Request.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/Request.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers +package com.lambda.interaction.manager import com.lambda.context.Automated import com.lambda.event.events.TickEvent diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakInfo.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt similarity index 89% rename from src/main/kotlin/com/lambda/interaction/managers/breaking/BreakInfo.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt index bae597df4..9c5149243 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakInfo.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt @@ -15,18 +15,18 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.breaking +package com.lambda.interaction.manager.managers.breaking import com.lambda.config.blocks.BreakConfig import com.lambda.context.SafeContext import com.lambda.interaction.construction.simulation.context.BreakContext -import com.lambda.interaction.handlers.breaking.RebreakHandler -import com.lambda.interaction.managers.ActionInfo -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Primary -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Rebreak -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.RedundantSecondary -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Secondary -import com.lambda.interaction.managers.breaking.BreakManager.calcBreakDelta +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler +import com.lambda.interaction.manager.managers.ActionInfo +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Primary +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Rebreak +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.RedundantSecondary +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Secondary +import com.lambda.interaction.manager.managers.breaking.BreakManager.calcBreakDelta import com.lambda.threading.runSafeAutomated import com.lambda.util.Describable import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt similarity index 89% rename from src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt index d8f35e129..bfd6eea7c 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.breaking +package com.lambda.interaction.manager.managers.breaking import com.lambda.config.blocks.BreakConfig import com.lambda.config.blocks.BreakConfig.BreakConfirmationMode @@ -34,47 +34,47 @@ import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.destroyBlock -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.pendingActions -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.setPendingConfigs -import com.lambda.interaction.handlers.breaking.BrokenBlockHandler.startPending -import com.lambda.interaction.handlers.breaking.RebreakHandler -import com.lambda.interaction.handlers.breaking.RebreakHandler.getRebreakPotential -import com.lambda.interaction.handlers.breaking.RebreakResult -import com.lambda.interaction.handlers.packet.PacketLimitHandler -import com.lambda.interaction.handlers.packet.PacketType +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.pendingActions +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.setPendingConfigs +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.startPending +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.getRebreakPotential +import com.lambda.interaction.handler.handlers.breaking.RebreakResult +import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler +import com.lambda.interaction.handler.handlers.packet.PacketType import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.managers.Manager -import com.lambda.interaction.managers.ManagerUtils.isPosBlocked -import com.lambda.interaction.managers.PositionBlocking -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Primary -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Rebreak -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.RedundantSecondary -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Secondary -import com.lambda.interaction.managers.breaking.BreakManager.abandonedBreak -import com.lambda.interaction.managers.breaking.BreakManager.activeInfos -import com.lambda.interaction.managers.breaking.BreakManager.activeRequest -import com.lambda.interaction.managers.breaking.BreakManager.breakInfos -import com.lambda.interaction.managers.breaking.BreakManager.breaks -import com.lambda.interaction.managers.breaking.BreakManager.canAccept -import com.lambda.interaction.managers.breaking.BreakManager.checkForCancels -import com.lambda.interaction.managers.breaking.BreakManager.handlePreProcessing -import com.lambda.interaction.managers.breaking.BreakManager.hotbarRequest -import com.lambda.interaction.managers.breaking.BreakManager.initNewBreak -import com.lambda.interaction.managers.breaking.BreakManager.maxBreaksThisTick -import com.lambda.interaction.managers.breaking.BreakManager.nullify -import com.lambda.interaction.managers.breaking.BreakManager.populateFrom -import com.lambda.interaction.managers.breaking.BreakManager.processNewBreak -import com.lambda.interaction.managers.breaking.BreakManager.processRequest -import com.lambda.interaction.managers.breaking.BreakManager.rotationRequest -import com.lambda.interaction.managers.breaking.BreakManager.simulateAbandoned -import com.lambda.interaction.managers.breaking.BreakManager.updateBreakProgress -import com.lambda.interaction.managers.breaking.BreakManager.updatePreProcessing -import com.lambda.interaction.managers.breaking.SwapInfo.Companion.getSwapInfo -import com.lambda.interaction.managers.hotbar.HotbarRequest -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.interacting.InteractManager -import com.lambda.interaction.managers.rotating.RotationRequest +import com.lambda.interaction.manager.managers.Manager +import com.lambda.interaction.manager.managers.ManagerUtils.isPosBlocked +import com.lambda.interaction.manager.managers.PositionBlocking +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Primary +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Rebreak +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.RedundantSecondary +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Secondary +import com.lambda.interaction.manager.managers.breaking.BreakManager.abandonedBreak +import com.lambda.interaction.manager.managers.breaking.BreakManager.activeInfos +import com.lambda.interaction.manager.managers.breaking.BreakManager.activeRequest +import com.lambda.interaction.manager.managers.breaking.BreakManager.breakInfos +import com.lambda.interaction.manager.managers.breaking.BreakManager.breaks +import com.lambda.interaction.manager.managers.breaking.BreakManager.canAccept +import com.lambda.interaction.manager.managers.breaking.BreakManager.checkForCancels +import com.lambda.interaction.manager.managers.breaking.BreakManager.handlePreProcessing +import com.lambda.interaction.manager.managers.breaking.BreakManager.hotbarRequest +import com.lambda.interaction.manager.managers.breaking.BreakManager.initNewBreak +import com.lambda.interaction.manager.managers.breaking.BreakManager.maxBreaksThisTick +import com.lambda.interaction.manager.managers.breaking.BreakManager.nullify +import com.lambda.interaction.manager.managers.breaking.BreakManager.populateFrom +import com.lambda.interaction.manager.managers.breaking.BreakManager.processNewBreak +import com.lambda.interaction.manager.managers.breaking.BreakManager.processRequest +import com.lambda.interaction.manager.managers.breaking.BreakManager.rotationRequest +import com.lambda.interaction.manager.managers.breaking.BreakManager.simulateAbandoned +import com.lambda.interaction.manager.managers.breaking.BreakManager.updateBreakProgress +import com.lambda.interaction.manager.managers.breaking.BreakManager.updatePreProcessing +import com.lambda.interaction.manager.managers.breaking.SwapInfo.Companion.getSwapInfo +import com.lambda.interaction.manager.managers.hotbar.HotbarRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.interacting.InteractManager +import com.lambda.interaction.manager.managers.rotating.RotationRequest import com.lambda.threading.runGameScheduled import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt similarity index 98% rename from src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt index 2e160c1bb..0a284cb3a 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/BreakRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.breaking +package com.lambda.interaction.manager.managers.breaking import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext @@ -27,7 +27,7 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.Request +import com.lambda.interaction.manager.managers.Request import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.isEmpty diff --git a/src/main/kotlin/com/lambda/interaction/managers/breaking/SwapInfo.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/SwapInfo.kt similarity index 87% rename from src/main/kotlin/com/lambda/interaction/managers/breaking/SwapInfo.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/breaking/SwapInfo.kt index 390c4caa5..269ef29f5 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/breaking/SwapInfo.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/SwapInfo.kt @@ -15,16 +15,16 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.breaking +package com.lambda.interaction.manager.managers.breaking import com.lambda.config.automation.AutomationConfig.Companion.DEFAULT import com.lambda.config.blocks.BreakConfig import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.breaking.RebreakHandler -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Primary -import com.lambda.interaction.managers.breaking.BreakInfo.BreakType.Secondary -import com.lambda.interaction.managers.breaking.BreakManager.calcBreakDelta +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Primary +import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Secondary +import com.lambda.interaction.manager.managers.breaking.BreakManager.calcBreakDelta import com.lambda.threading.runSafeAutomated /** diff --git a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarManager.kt similarity index 91% rename from src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarManager.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarManager.kt index 3feb3275c..76c69b950 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarManager.kt @@ -15,19 +15,19 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.hotbar +package com.lambda.interaction.manager.managers.hotbar import com.lambda.config.blocks.HotbarConfig.SwapMode import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.Manager -import com.lambda.interaction.managers.hotbar.HotbarManager.activeRequest -import com.lambda.interaction.managers.hotbar.HotbarManager.activeSlot -import com.lambda.interaction.managers.hotbar.HotbarManager.checkResetSwap -import com.lambda.interaction.managers.hotbar.HotbarManager.setActiveRequest -import com.lambda.interaction.managers.hotbar.HotbarManager.setActiveSlot +import com.lambda.interaction.manager.Manager +import com.lambda.interaction.manager.managers.hotbar.HotbarManager.activeRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarManager.activeSlot +import com.lambda.interaction.manager.managers.hotbar.HotbarManager.checkResetSwap +import com.lambda.interaction.manager.managers.hotbar.HotbarManager.setActiveRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarManager.setActiveSlot import com.lambda.threading.runSafe import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarRequest.kt similarity index 93% rename from src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarRequest.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarRequest.kt index f16a1d6f3..682ec2993 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/hotbar/HotbarRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarRequest.kt @@ -15,10 +15,11 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.hotbar +package com.lambda.interaction.manager.managers.hotbar import com.lambda.context.Automated -import com.lambda.interaction.managers.Request +import com.lambda.interaction.manager.Request +import com.lambda.interaction.manager.managers.Request class HotbarRequest( val slot: Int, diff --git a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractInfo.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractInfo.kt similarity index 91% rename from src/main/kotlin/com/lambda/interaction/managers/interacting/InteractInfo.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractInfo.kt index b4e813267..c5efd746c 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractInfo.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractInfo.kt @@ -15,13 +15,13 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.interacting +package com.lambda.interaction.manager.managers.interacting import com.lambda.config.blocks.InteractConfig import com.lambda.context.SafeContext import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.context.InteractContext -import com.lambda.interaction.managers.ActionInfo +import com.lambda.interaction.manager.managers.ActionInfo import net.minecraft.util.math.BlockPos data class InteractInfo( diff --git a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt similarity index 91% rename from src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt index 56fa03e4e..2b7983e23 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.interacting +package com.lambda.interaction.manager.managers.interacting import com.lambda.config.blocks.InteractConfig import com.lambda.config.blocks.InteractConfig.AirPlaceMode @@ -29,22 +29,22 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.InteractContext -import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.pendingActions -import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.setPendingConfigs -import com.lambda.interaction.handlers.interacting.InteractedBlockHandler.startPending -import com.lambda.interaction.handlers.packet.PacketLimitHandler -import com.lambda.interaction.handlers.packet.PacketType -import com.lambda.interaction.managers.Manager -import com.lambda.interaction.managers.ManagerUtils.isPosBlocked -import com.lambda.interaction.managers.PositionBlocking -import com.lambda.interaction.managers.breaking.BreakManager -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.interacting.InteractManager.activeRequest -import com.lambda.interaction.managers.interacting.InteractManager.maxInteractionsThisTick -import com.lambda.interaction.managers.interacting.InteractManager.populateFrom -import com.lambda.interaction.managers.interacting.InteractManager.potentialInteractions -import com.lambda.interaction.managers.interacting.InteractManager.processRequest -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler.pendingActions +import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler.setPendingConfigs +import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler.startPending +import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler +import com.lambda.interaction.handler.handlers.packet.PacketType +import com.lambda.interaction.manager.managers.Manager +import com.lambda.interaction.manager.managers.ManagerUtils.isPosBlocked +import com.lambda.interaction.manager.managers.PositionBlocking +import com.lambda.interaction.manager.managers.breaking.BreakManager +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.interacting.InteractManager.activeRequest +import com.lambda.interaction.manager.managers.interacting.InteractManager.maxInteractionsThisTick +import com.lambda.interaction.manager.managers.interacting.InteractManager.populateFrom +import com.lambda.interaction.manager.managers.interacting.InteractManager.potentialInteractions +import com.lambda.interaction.manager.managers.interacting.InteractManager.processRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.modules.world.AutoSign.signWriteDelay import com.lambda.threading.runConcurrent import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt similarity index 97% rename from src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt index 3132cda20..4aeb87bef 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/interacting/InteractRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.interacting +package com.lambda.interaction.manager.managers.interacting import com.lambda.context.Automated import com.lambda.context.SafeContext @@ -24,7 +24,7 @@ import com.lambda.interaction.construction.simulation.context.InteractContext import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.InteractResult -import com.lambda.interaction.managers.Request +import com.lambda.interaction.manager.managers.Request import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.matches diff --git a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryAction.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryAction.kt similarity index 95% rename from src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryAction.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryAction.kt index 33f4559a6..ebf22474f 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryAction.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryAction.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.inventory +package com.lambda.interaction.manager.managers.inventory import com.lambda.context.SafeContext diff --git a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryManager.kt similarity index 93% rename from src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryManager.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryManager.kt index f89841caf..ee90518eb 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryManager.kt @@ -15,21 +15,21 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.inventory +package com.lambda.interaction.manager.managers.inventory import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.packet.PacketLimitHandler.canSendPackets -import com.lambda.interaction.handlers.packet.PacketLimitHandler.sentPackets -import com.lambda.interaction.handlers.packet.PacketType -import com.lambda.interaction.managers.Manager -import com.lambda.interaction.managers.inventory.InventoryManager.actions -import com.lambda.interaction.managers.inventory.InventoryManager.activeRequest -import com.lambda.interaction.managers.inventory.InventoryManager.alteredSlots -import com.lambda.interaction.managers.inventory.InventoryManager.processActiveRequest +import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler.canSendPackets +import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler.sentPackets +import com.lambda.interaction.handler.handlers.packet.PacketType +import com.lambda.interaction.manager.Manager +import com.lambda.interaction.manager.managers.inventory.InventoryManager.actions +import com.lambda.interaction.manager.managers.inventory.InventoryManager.activeRequest +import com.lambda.interaction.manager.managers.inventory.InventoryManager.alteredSlots +import com.lambda.interaction.manager.managers.inventory.InventoryManager.processActiveRequest import com.lambda.module.modules.client.Client import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryRequest.kt similarity index 97% rename from src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryRequest.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryRequest.kt index 5e3c84e92..82d81e619 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/inventory/InventoryRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryRequest.kt @@ -15,11 +15,12 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.inventory +package com.lambda.interaction.manager.managers.inventory import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.managers.Request +import com.lambda.interaction.manager.Request +import com.lambda.interaction.manager.managers.Request import com.lambda.util.PacketUtils.sendPacket import com.lambda.util.player.SlotUtils.clickSlot import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap diff --git a/src/main/kotlin/com/lambda/interaction/managers/rotating/Rotation.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/Rotation.kt similarity index 99% rename from src/main/kotlin/com/lambda/interaction/managers/rotating/Rotation.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/rotating/Rotation.kt index c464fb7c9..fa530996b 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/rotating/Rotation.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/Rotation.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.rotating +package com.lambda.interaction.manager.managers.rotating import com.lambda.threading.runSafe import com.lambda.util.math.MathUtils.toDegree diff --git a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationManager.kt similarity index 95% rename from src/main/kotlin/com/lambda/interaction/managers/rotating/RotationManager.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationManager.kt index 93851e71f..52d946aa5 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationManager.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.rotating +package com.lambda.interaction.manager.managers.rotating import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext @@ -28,12 +28,12 @@ import com.lambda.event.events.TickEvent import com.lambda.event.events.TickEvent.Companion.ALL_STAGES import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe -import com.lambda.interaction.managers.Manager -import com.lambda.interaction.managers.rotating.Rotation.Companion.slerpPitch -import com.lambda.interaction.managers.rotating.Rotation.Companion.slerpYaw -import com.lambda.interaction.managers.rotating.RotationManager.activeRotation -import com.lambda.interaction.managers.rotating.RotationManager.serverRotation -import com.lambda.interaction.managers.rotating.RotationManager.updateActiveRotation +import com.lambda.interaction.manager.Manager +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.slerpPitch +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.slerpYaw +import com.lambda.interaction.manager.managers.rotating.RotationManager.activeRotation +import com.lambda.interaction.manager.managers.rotating.RotationManager.serverRotation +import com.lambda.interaction.manager.managers.rotating.RotationManager.updateActiveRotation import com.lambda.threading.runGameScheduled import com.lambda.threading.runSafe import com.lambda.util.extension.rotation diff --git a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationMode.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationMode.kt similarity index 96% rename from src/main/kotlin/com/lambda/interaction/managers/rotating/RotationMode.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationMode.kt index 5d0cae02e..0ce450f52 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationMode.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationMode.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.rotating +package com.lambda.interaction.manager.managers.rotating import com.lambda.util.Describable import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationRequest.kt similarity index 90% rename from src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt rename to src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationRequest.kt index 518c98465..12c43a884 100644 --- a/src/main/kotlin/com/lambda/interaction/managers/rotating/RotationRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/rotating/RotationRequest.kt @@ -15,18 +15,18 @@ * along with this program. If not, see . */ -package com.lambda.interaction.managers.rotating +package com.lambda.interaction.manager.managers.rotating import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.managers.Request -import com.lambda.interaction.managers.rotating.IRotationRequest.Full -import com.lambda.interaction.managers.rotating.IRotationRequest.Pitch -import com.lambda.interaction.managers.rotating.IRotationRequest.Yaw -import com.lambda.interaction.managers.rotating.Rotation.Companion.dist -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation -import com.lambda.interaction.managers.rotating.Rotation.Companion.wrap +import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.manager.Request +import com.lambda.interaction.manager.managers.rotating.IRotationRequest.Full +import com.lambda.interaction.manager.managers.rotating.IRotationRequest.Pitch +import com.lambda.interaction.manager.managers.rotating.IRotationRequest.Yaw +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.dist +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.wrap import com.lambda.threading.runSafe import com.lambda.util.collections.UpdatableLazy import com.lambda.util.collections.updatableLazy diff --git a/src/main/kotlin/com/lambda/module/hud/Baritone.kt b/src/main/kotlin/com/lambda/module/hud/Baritone.kt index 601602b71..438671ece 100644 --- a/src/main/kotlin/com/lambda/module/hud/Baritone.kt +++ b/src/main/kotlin/com/lambda/module/hud/Baritone.kt @@ -19,7 +19,7 @@ package com.lambda.module.hud import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.interaction.construction.simulation.BuildGoal -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.HudModule import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt b/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt index 9f2199c93..25c6dab7f 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt @@ -22,7 +22,7 @@ import com.lambda.config.ConfigBlock import com.lambda.config.Group import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.FriendHandler +import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.ChatUtils.addresses diff --git a/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt b/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt index 2c68b2abd..3357ecf63 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt @@ -21,7 +21,7 @@ import com.google.common.collect.Comparators.min import com.lambda.command.CommandRegistry.prefix import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt b/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt index b25e12a60..c9220aeb6 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.chat import com.lambda.command.CommandRegistry.prefix import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.ChatUtils.toBlue diff --git a/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt b/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt index 72d48f3b2..604d03a0f 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.chat import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.FriendHandler +import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.sound.SoundHandler.playSound diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt index aa0a248a2..1fffa8804 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt @@ -27,7 +27,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.ArmorContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.EnchantmentUtils.getEnchantment diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index 3ca0ee386..00d00c49f 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -23,9 +23,9 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.FriendHandler +import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.combat.CombatUtils.hasDeadlyCrystal diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt b/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt index a4c848b0d..bc7822c21 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt @@ -20,8 +20,8 @@ package com.lambda.module.modules.combat import com.lambda.context.SafeContext import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.PacketUtils.sendPacket diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index d20b8b8a8..f9d86b24e 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -27,14 +27,14 @@ import com.lambda.context.SafeContext import com.lambda.event.events.EntityEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.ContainerHandler.transfer +import com.lambda.interaction.handler.handlers.ContainerHandler.transfer import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index 8ed274c82..a470a32fd 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -30,8 +30,8 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index 79848af5d..9758e1a2f 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -24,7 +24,7 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.FriendHandler.isFriend +import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt b/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt index c479ac4b9..a72292411 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt @@ -26,7 +26,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.components.ClickGuiLayout -import com.lambda.interaction.handlers.FriendHandler +import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.sound.SoundHandler.playSound @@ -41,10 +41,10 @@ import com.lambda.util.combat.CombatUtils.crystalDamage import com.lambda.util.combat.DamageUtils.isFallDeadly import com.lambda.util.extension.fullHealth import com.lambda.util.extension.tickDeltaF -import com.lambda.util.item.ItemStackUtils.bundleContents -import com.lambda.util.item.ItemStackUtils.shulkerBoxContents -import com.lambda.util.player.PlayerUtils.isIn2b2tQueue +import com.lambda.util.item.ItemStackUtils.bundleStacks +import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.player.MovementUtils.moveDelta +import com.lambda.util.player.PlayerUtils.isIn2b2tQueue import com.lambda.util.player.SlotUtils.allStacks import com.lambda.util.player.SlotUtils.armorSlots import com.lambda.util.player.SlotUtils.hotbarStacks @@ -706,7 +706,7 @@ object AutoDisconnect : Module( private fun itemRow(stack: ItemStack, label: String? = null, selected: Boolean = false): DetailSection { val header = itemHeader(stack, label, selected) val enchantments = stack.forEachEnchantment { entry, level -> Enchantment.getName(entry, level) } - val contents = (stack.shulkerBoxContents + stack.bundleContents).filter { !it.isEmpty } + val contents = (stack.shulkerBoxStacks + stack.bundleStacks).filter { !it.isEmpty } if (enchantments.isEmpty() && contents.isEmpty()) { return DetailSection.TextSection(header) diff --git a/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt index 0edf97ccc..759fc8253 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.debug import baritone.api.pathing.goals.GoalXZ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index 898e5b046..fc2597653 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -23,7 +23,7 @@ import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run -import com.lambda.task.tasks.AcquireStack.Companion.acquire +import com.lambda.task.tasks.AcquireStackTask.Companion.acquireStack import net.minecraft.item.Items @Suppress("unused") @@ -38,7 +38,7 @@ object ContainerTest : Module( } onEnable { - acquire { + acquireStack { Items.OBSIDIAN.select() }.run() } diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt index aeaeb7a3f..1648c632e 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.player.RotationUtils.lookAt diff --git a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt index 17a70165e..f13616f8c 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt @@ -22,7 +22,7 @@ import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomat import com.lambda.config.withEdits import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.CommunicationUtils.info diff --git a/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt b/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt index 7548a0e24..a026b7fa7 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt @@ -21,8 +21,8 @@ import baritone.api.pathing.goals.GoalXZ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.BlockPosIterators diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 05118f58b..177d6d9f6 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -28,14 +28,14 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.GlideHandler +import com.lambda.interaction.handler.handlers.GlideHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt index 1416e7428..92282461c 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt @@ -23,7 +23,7 @@ import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomat import com.lambda.config.withEdits import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.modules.movement.BetterFirework.startFirework import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt index 4e3fa5740..aba6b353e 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt @@ -26,7 +26,7 @@ import com.lambda.event.events.ClientEvent import com.lambda.event.events.MovementEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt index 57ece652e..91b65ab2a 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.movement import com.lambda.event.events.RotationEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.module.Module import com.lambda.module.modules.combat.KillAura import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt index edc0e2bc0..f56939f61 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt @@ -24,13 +24,13 @@ import com.lambda.event.Muteable import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.GlideHandler.ELYTRA_SELECTION +import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION import com.lambda.interaction.inventory.container.containers.ArmorContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.inventory.InvRequestBuilder -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest -import com.lambda.interaction.managers.inventory.InventoryManager +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InventoryManager import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFly.fakeFly import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt index 3159c59b8..04c828d87 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt @@ -21,7 +21,7 @@ import baritone.api.pathing.goals.GoalGetToBlock import com.lambda.config.Config import com.lambda.config.ConfigBlock import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.hud.Speedometer import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.threading.runGameScheduled diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt index 1b33c12c7..67e4b7544 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt @@ -25,10 +25,10 @@ import com.lambda.event.events.MovementEvent import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.handlers.GlideHandler -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.GlideHandler +import com.lambda.interaction.manager.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.hud.Speedometer import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFly.fakeFly diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt index 7c3875b0b..bd92459d2 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt @@ -25,8 +25,8 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.modules.movement.BetterFirework.startFirework import com.lambda.module.modules.movement.elytrafly.ElytraFly.FlyMode import com.lambda.module.modules.movement.elytrafly.ElytraFlyMode diff --git a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt index b078fcb14..645239f00 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt @@ -21,8 +21,8 @@ import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.distSq diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt index 407de5e5d..92fc44463 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt @@ -18,13 +18,13 @@ package com.lambda.module.modules.player import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.GlideHandler.CHESTPLATE_SELECTION -import com.lambda.interaction.handlers.GlideHandler.ELYTRA_SELECTION -import com.lambda.interaction.handlers.GlideHandler.manuallySwapped -import com.lambda.interaction.handlers.GlideHandler.swapped +import com.lambda.interaction.handler.handlers.GlideHandler.CHESTPLATE_SELECTION +import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION +import com.lambda.interaction.handler.handlers.GlideHandler.manuallySwapped +import com.lambda.interaction.handler.handlers.GlideHandler.swapped import com.lambda.interaction.inventory.container.containers.ArmorContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt b/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt index 5bbfb4bf3..402260cd5 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt @@ -20,10 +20,10 @@ package com.lambda.module.modules.player import com.lambda.config.settings.complex.Bind import com.lambda.config.settings.complex.KeybindSetting.Companion.onPress import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.FriendHandler -import com.lambda.interaction.handlers.FriendHandler.befriend -import com.lambda.interaction.handlers.FriendHandler.isFriend -import com.lambda.interaction.handlers.FriendHandler.unfriend +import com.lambda.interaction.handler.handlers.FriendHandler +import com.lambda.interaction.handler.handlers.FriendHandler.befriend +import com.lambda.interaction.handler.handlers.FriendHandler.isFriend +import com.lambda.interaction.handler.handlers.FriendHandler.unfriend import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.CommunicationUtils.info diff --git a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 4b0ce1787..ab1265f27 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -27,7 +27,7 @@ import com.lambda.event.events.PlayerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.context.BuildContext -import com.lambda.interaction.managers.breaking.BreakRequestBuilder.Companion.breakRequest +import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt index 833f0a7db..b65300f3b 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt @@ -22,8 +22,8 @@ import com.lambda.config.blocks.RotationConfig import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.LambdaScreen -import com.lambda.interaction.managers.rotating.RotationMode -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.InputUtils diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt index ba421be95..59d0909c7 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.player import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.TickTimer diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index a9abb1ef8..ace2216cc 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -27,7 +27,7 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock +import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect import com.lambda.task.tasks.OpenContainerTask import com.lambda.task.tasks.PlaceContainerTask import com.lambda.util.item.ItemUtils.shulkerBoxes @@ -72,7 +72,7 @@ object InventoryTweaks : Module( if (event.screenHandler != lastOpenScreen) return@listen lastOpenScreen = null placedPos?.let { - lastBreak = breakAndCollectBlock(it).run() + lastBreak = breakAndCollect(it).run() placedPos = null } } diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 1d8fd9e99..4653b5e59 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -37,7 +37,7 @@ import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.breaking.BreakRequestBuilder.Companion.breakRequest +import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt index d0edbc647..9ebf59a3b 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt @@ -34,10 +34,10 @@ import com.lambda.event.events.MovementEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.components.ClickGuiLayout -import com.lambda.interaction.handlers.TimerHandler -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.RotationMode -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.handler.handlers.TimerHandler +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.modules.player.Replay.InputAction.Companion.toAction import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt index 307251bc7..843bf0061 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt @@ -23,8 +23,8 @@ import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomat import com.lambda.config.withEdits import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.RotationMode -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import kotlin.math.roundToInt diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index 3a2ba080c..b1a90ca64 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -26,7 +26,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.item.ItemStackUtils.slotId diff --git a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt index 6df4bcb7d..c11621cc4 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt @@ -25,7 +25,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.EnchantmentUtils.forEachEnchantment diff --git a/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt b/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt index a67af3e35..5541edce9 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt @@ -20,8 +20,8 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.extension.rotation diff --git a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt index 1ff346388..d6f1f05fb 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt @@ -29,9 +29,9 @@ import com.lambda.event.events.PlayerEvent import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.RotationMode -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt b/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt index b097805d2..90458cb1d 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt @@ -30,7 +30,7 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.graphics.mc.renderer.RendererUtils.worldToScreenNormalized import com.lambda.graphics.text.FontHandler import com.lambda.graphics.util.DynamicAABB.Companion.interpolatedBox -import com.lambda.interaction.handlers.FriendHandler.isFriend +import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt b/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt index f2d4d074e..914ba8ad4 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt @@ -26,7 +26,7 @@ import com.lambda.config.blocks.ScreenLineSettings import com.lambda.config.withEdits import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.mc.renderer.RendererUtils.worldToScreenNormalized -import com.lambda.interaction.handlers.FriendHandler.isFriend +import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt index 182d49707..894e92a98 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt @@ -32,9 +32,9 @@ import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.interacting.InteractRequest -import com.lambda.interaction.managers.interacting.PlaceRequestBuilder.Companion.interactRequest -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotation +import com.lambda.interaction.manager.managers.interacting.InteractRequest +import com.lambda.interaction.manager.managers.interacting.PlaceRequestBuilder.Companion.interactRequest +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index d36d5d538..73c860bf0 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -35,12 +35,12 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.util.DirectionMask import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.modules.world.AutoPortal.PosHandler.currAnchorPos import com.lambda.module.modules.world.AutoPortal.PosHandler.obiPositions diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt index bb68c9222..edcb11719 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt @@ -30,7 +30,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.sound.SoundHandler.playSound diff --git a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt index c288468d9..82aa2a647 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt @@ -23,7 +23,7 @@ import com.lambda.config.withEdits import com.lambda.interaction.construction.blueprint.Blueprint.Companion.emptyStructure import com.lambda.interaction.construction.blueprint.PropagatingBlueprint.Companion.propagatingBlueprint import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index 1708ba5c4..3850596d5 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -33,7 +33,7 @@ import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.managers.interacting.PlaceRequestBuilder.Companion.interactRequest +import com.lambda.interaction.manager.managers.interacting.PlaceRequestBuilder.Companion.interactRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index 92304d9a5..a18c1d5b3 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -40,18 +40,18 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.Rotation.Companion.dist -import com.lambda.interaction.managers.rotating.RotationManager -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.dist +import com.lambda.interaction.manager.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt index 086700731..cf705440a 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -21,7 +21,7 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial +import com.lambda.interaction.handler.handlers.ContainerHandler.findSlots import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.task.Task import com.lambda.threading.runSafeAutomated @@ -43,7 +43,7 @@ class AcquirePlacedBlockTask @Ta5kBuilder constructor( runSafeAutomated { Items.ENDER_CHEST .select(1) - .findSlotsWithMaterial() + .findSlots() .firstOrNull()?.let { slot -> PlaceContainerTask(slot, this).finally { success(it) @@ -71,4 +71,13 @@ class AcquirePlacedBlockTask @Ta5kBuilder constructor( .firstOrNull { blockPos -> blockState(blockPos).block == block } + + companion object { + @Ta5kBuilder + context(automated: Automated) + fun acquirePlacedBlock( + block: Block, + maxSearchRadius: Int = 10 + ) = AcquirePlacedBlockTask(block, maxSearchRadius, automated) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStack.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt similarity index 66% rename from src/main/kotlin/com/lambda/task/tasks/AcquireStack.kt rename to src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index a28f1c336..dbc2b6a57 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStack.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -19,34 +19,40 @@ package com.lambda.task.tasks import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.ContainerHandler -import com.lambda.interaction.handlers.ContainerHandler.findContainerWithMaterial +import com.lambda.interaction.handler.handlers.ContainerHandler +import com.lambda.interaction.handler.handlers.ContainerHandler.findContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import com.lambda.threading.runSafeAutomated +import net.minecraft.screen.slot.Slot -class AcquireStack @Ta5kBuilder constructor( +class AcquireStackTask @Ta5kBuilder constructor( val selection: StackSelection, automated: Automated -) : Task(), Automated by automated { +) : Task(), Automated by automated { override val name: String get() = "Acquiring $selection" override fun SafeContext.onStart() { runSafeAutomated { - selection.findContainerWithMaterial() + selection.findContainer() ?.transferByTask(selection, HotbarContainer) - ?.finally { - success(selection) - }?.execute(this@AcquireStack) + ?.finally { slot -> success(slot) } + ?.execute(this@AcquireStackTask) ?: failure(ContainerHandler.NoContainerFound(selection)) // ToDo: Create crafting path } } companion object { @Ta5kBuilder - fun Automated.acquire(selection: () -> StackSelection) = - AcquireStack(selection(), this) + context(automated: Automated) + fun acquireStack(selection: StackSelection) = + AcquireStackTask(selection, automated) + + @Ta5kBuilder + context(automated: Automated) + fun acquireStack(selection: () -> StackSelection) = + AcquireStackTask(selection(), automated) } } diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index 31888b729..1f8e52634 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -46,11 +46,11 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.simulation.result.results.PreSimResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.managers.breaking.BreakRequestBuilder.Companion.breakRequest -import com.lambda.interaction.managers.interacting.PlaceRequestBuilder.Companion.interactRequest -import com.lambda.interaction.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest +import com.lambda.interaction.manager.managers.interacting.PlaceRequestBuilder.Companion.interactRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.modules.client.Client import com.lambda.task.Task import com.lambda.task.tasks.EatTask.Companion.eat @@ -78,7 +78,7 @@ import java.util.concurrent.ConcurrentLinkedQueue import kotlin.coroutines.cancellation.CancellationException import kotlin.math.sqrt -class BuildTask private constructor( +class BuildTask @Ta5kBuilder private constructor( private val blueprint: Blueprint, private val finishOnDone: Boolean, private val collectDrops: Boolean, @@ -377,7 +377,8 @@ class BuildTask private constructor( ) = BuildTask(this, finishOnDone, collectDrops, lifeMaintenance, async, automated, buildResultFilter) @Ta5kBuilder - fun Automated.breakAndCollectBlock( + context(automated: Automated) + fun breakAndCollect( blockPos: BlockPos, finishOnDone: Boolean = true, lifeMaintenance: Boolean = false, @@ -385,7 +386,7 @@ class BuildTask private constructor( buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, ) = BuildTask( blockPos.toStructure(TargetState.Empty).toBlueprint(), - finishOnDone, true, lifeMaintenance, async, this, buildResultFilter + finishOnDone, true, lifeMaintenance, async, automated, buildResultFilter ) } } diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index 03ce1c3ec..a495f49c9 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -20,20 +20,22 @@ package com.lambda.task.tasks import com.lambda.context.Automated import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.handler.handlers.ContainerHandler.findContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.task.Task import com.lambda.threading.runSafeAutomated +import net.minecraft.screen.slot.Slot -class ContainerTransferTask( +class ContainerTransferTask @Ta5kBuilder constructor( private var fromContainer: Container, private val toContainer: Container, private val stackSelection: StackSelection, private val failIfNoStack: Boolean = false, automated: Automated -) : Task(), Automated by automated { +) : Task(), Automated by automated { override val name = "Transferring $stackSelection from $fromContainer to $toContainer" init { @@ -44,7 +46,7 @@ class ContainerTransferTask( true, { HotbarAndInventoryContainer.transferByTask(stackSelection, toContainer) - .finally { success() } + .finally { slot -> success(slot) } } ) { fromContainer.transferByTask(stackSelection, HotbarAndInventoryContainer) @@ -54,21 +56,32 @@ class ContainerTransferTask( fromContainer.accessThen { toContainer.accessThen { - TransferTask() + TransferTask().finally { slot -> + success(slot) + } } }.execute(this@ContainerTransferTask) } } } - private inner class TransferTask : Task() { + private inner class TransferTask : Task() { override val name = "Transferring" init { listen { runSafeAutomated { - val transferSuccessful = fromContainer.transfer(stackSelection, toContainer) - if (transferSuccessful) success() + val (fromSlot, toSlot) = fromContainer.getTransferSlots(stackSelection, toContainer) + if (fromSlot == null) { + checkFail() + return@listen + } + if (toSlot == null) { + failure("Unable to find a slot to transfer to.") + return@listen + } + val transferSuccessful = fromContainer.transfer(fromSlot, toSlot, toContainer) + if (transferSuccessful) success(toSlot) else checkFail() } } @@ -80,4 +93,34 @@ class ContainerTransferTask( private inner class NoMaterialAccessException(stackSelection: StackSelection) : IllegalStateException("Unable to access $stackSelection.") } + + companion object { + @Ta5kBuilder + context(automated: Automated) + fun transfer( + fromContainer: Container, + toContainer: Container, + stackSelection: StackSelection, + failIfNoStack: Boolean = false + ) = ContainerTransferTask(fromContainer, toContainer, stackSelection, failIfNoStack, automated) + + @Ta5kBuilder + context(automated: Automated) + fun transfer( + stackSelection: StackSelection, + toContainer: Container, + failIfNoStack: Boolean = false + ) = stackSelection.findContainer()?.let { + ContainerTransferTask(it, toContainer, stackSelection, failIfNoStack, automated) + } + + @Ta5kBuilder + context(automated: Automated) + fun StackSelection.transfer( + toContainer: Container, + failIfNoStack: Boolean = false + ) = findContainer()?.let { + ContainerTransferTask(it, toContainer, this, failIfNoStack, automated) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index d09163dc6..9e086f5e4 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -25,7 +25,8 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt b/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt index bc7b870c5..47c34dea6 100644 --- a/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt @@ -29,6 +29,6 @@ class NoopTask : Task() { companion object { @Ta5kBuilder - fun noop() = NoopTask() + fun noopTask() = NoopTask() } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt index a5c181286..bff0253e0 100644 --- a/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt @@ -22,8 +22,8 @@ import com.lambda.context.Automated import com.lambda.event.events.InventoryEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handlers.BaritoneHandler -import com.lambda.interaction.managers.rotating.RotationRequestBuilder.Companion.rotationRequest +import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated import com.lambda.util.TickTimer @@ -36,9 +36,9 @@ import net.minecraft.util.math.Direction class OpenContainerTask @Ta5kBuilder constructor( private val blockPos: BlockPos, - private val automated: Automated, private val waitForSlotLoad: Boolean = true, - private val sides: Set = Direction.entries.toSet() + private val sides: Set = Direction.entries.toSet(), + private val automated: Automated ) : Task(), Automated by automated { override val name get() = "${containerState.description()} at ${blockPos.toShortString()}" @@ -109,4 +109,14 @@ class OpenContainerTask @Ta5kBuilder constructor( containerState = State.Opening } } + + companion object { + @Ta5kBuilder + context(automated: Automated) + fun openContainer( + blockPos: BlockPos, + waitForSlotLoad: Boolean = true, + sides: Set = Direction.entries.toSet() + ) = OpenContainerTask(blockPos, waitForSlotLoad, sides, automated) + } } diff --git a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt index 185ae5da4..96e807e4d 100644 --- a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt @@ -25,7 +25,7 @@ import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.managers.ManagerUtils +import com.lambda.interaction.manager.ManagerUtils import com.lambda.task.Task import com.lambda.task.tasks.BuildTask.Companion.build import com.lambda.threading.runSafeAutomated @@ -96,4 +96,14 @@ class PlaceContainerTask @Ta5kBuilder constructor( } else -> false } + + companion object { + @Ta5kBuilder + context(automated: Automated) + fun placeContainer(slot: Slot) = PlaceContainerTask(slot, automated) + + @Ta5kBuilder + context(automated: Automated) + fun placeContainer(slot: () -> Slot) = PlaceContainerTask(slot(), automated) + } } diff --git a/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt b/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt new file mode 100644 index 000000000..27b7ad071 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks + +import com.lambda.context.SafeContext +import com.lambda.task.Task + +class SimpleActionTask @Ta5kBuilder constructor( + override val name: String, + val action: () -> Unit +) : Task() { + override fun SafeContext.onStart() { + action() + success() + } + + companion object { + @Ta5kBuilder + fun simpleAction(name: String, action: () -> Unit) = SimpleActionTask(name, action) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt b/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt new file mode 100644 index 000000000..057b98d41 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks + +import com.lambda.context.SafeContext +import com.lambda.task.Task +import com.lambda.util.player.SlotUtils.matches +import net.minecraft.screen.slot.Slot + +class SlotByCacheTask @Ta5kBuilder constructor( + val slotCache: Slot +) : Task() { + override val name = "Finding slot by cache: $slotCache" + + override fun SafeContext.onStart() { + val slots = player.currentScreenHandler.slots + val slot = slots.find { it matches slotCache } + if (slot != null) success(slot) + else failure("Failed to find matching slot by cache: $slotCache") + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/util/PlaceDirection.kt b/src/main/kotlin/com/lambda/util/PlaceDirection.kt index b6e3b0484..bf0483a63 100644 --- a/src/main/kotlin/com/lambda/util/PlaceDirection.kt +++ b/src/main/kotlin/com/lambda/util/PlaceDirection.kt @@ -17,7 +17,7 @@ package com.lambda.util -import com.lambda.interaction.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec3i diff --git a/src/main/kotlin/com/lambda/util/PlayerBuildLayerUtils.kt b/src/main/kotlin/com/lambda/util/PlayerBuildLayerUtils.kt index 86d0375b3..96b029a8e 100644 --- a/src/main/kotlin/com/lambda/util/PlayerBuildLayerUtils.kt +++ b/src/main/kotlin/com/lambda/util/PlayerBuildLayerUtils.kt @@ -18,7 +18,7 @@ package com.lambda.util import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.isNotEmpty import com.lambda.util.math.MathUtils.ceilToInt diff --git a/src/main/kotlin/com/lambda/util/extension/Entity.kt b/src/main/kotlin/com/lambda/util/extension/Entity.kt index 50f761620..94ee5c188 100644 --- a/src/main/kotlin/com/lambda/util/extension/Entity.kt +++ b/src/main/kotlin/com/lambda/util/extension/Entity.kt @@ -17,7 +17,7 @@ package com.lambda.util.extension -import com.lambda.interaction.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity import net.minecraft.util.math.Vec3d diff --git a/src/main/kotlin/com/lambda/util/math/Linear.kt b/src/main/kotlin/com/lambda/util/math/Linear.kt index fe0360966..de0ab8c2e 100644 --- a/src/main/kotlin/com/lambda/util/math/Linear.kt +++ b/src/main/kotlin/com/lambda/util/math/Linear.kt @@ -17,7 +17,7 @@ package com.lambda.util.math -import com.lambda.interaction.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation import net.minecraft.util.math.Box import net.minecraft.util.math.Vec3d import java.awt.Color diff --git a/src/main/kotlin/com/lambda/util/player/MovementUtils.kt b/src/main/kotlin/com/lambda/util/player/MovementUtils.kt index 33f266cd2..2adf4de83 100644 --- a/src/main/kotlin/com/lambda/util/player/MovementUtils.kt +++ b/src/main/kotlin/com/lambda/util/player/MovementUtils.kt @@ -18,7 +18,7 @@ package com.lambda.util.player import com.lambda.context.SafeContext -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.util.math.MathUtils.toDegree import com.lambda.util.math.MathUtils.toDouble import com.lambda.util.math.MathUtils.toRadian diff --git a/src/main/kotlin/com/lambda/util/player/PlayerUtils.kt b/src/main/kotlin/com/lambda/util/player/PlayerUtils.kt index f381daac1..574394b7a 100644 --- a/src/main/kotlin/com/lambda/util/player/PlayerUtils.kt +++ b/src/main/kotlin/com/lambda/util/player/PlayerUtils.kt @@ -19,7 +19,7 @@ package com.lambda.util.player import com.lambda.config.blocks.BuildConfig import com.lambda.context.SafeContext -import com.lambda.interaction.handlers.GlideHandler +import com.lambda.interaction.handler.handlers.GlideHandler import com.lambda.util.extension.getBlockState import com.lambda.util.player.MovementUtils.sneaking import com.lambda.util.world.fastEntitySearch diff --git a/src/main/kotlin/com/lambda/util/player/RotationUtils.kt b/src/main/kotlin/com/lambda/util/player/RotationUtils.kt index 840cf5670..cb0af20ec 100644 --- a/src/main/kotlin/com/lambda/util/player/RotationUtils.kt +++ b/src/main/kotlin/com/lambda/util/player/RotationUtils.kt @@ -23,9 +23,9 @@ import com.lambda.context.SafeContext import com.lambda.interaction.construction.simulation.processing.PreProcessingData import com.lambda.interaction.construction.verify.ScanMode import com.lambda.interaction.construction.verify.SurfaceScan -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.module.modules.client.Client import com.lambda.util.BlockUtils.blockState import com.lambda.util.PlaceDirection diff --git a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt index 81e89d0c2..65a60cb96 100644 --- a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt +++ b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt @@ -62,4 +62,11 @@ object SlotUtils { val syncId = player.currentScreenHandler?.syncId ?: return interaction.clickSlot(syncId, slotId, button, actionType, player) } + + infix fun Slot.matches(slot: Slot) = + index == slot.index && + inventory::class == slot.inventory::class && + id == slot.id && + x == slot.x && + y == slot.y } diff --git a/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt b/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt index 17a9a4d7c..a4a6e3bc6 100644 --- a/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt +++ b/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt @@ -19,7 +19,7 @@ package com.lambda.util.player.prediction import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.module.modules.movement.SafeWalk.isNearLedge import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState diff --git a/src/main/kotlin/com/lambda/util/player/prediction/PredictionTick.kt b/src/main/kotlin/com/lambda/util/player/prediction/PredictionTick.kt index 074a6c69d..3d05d802c 100644 --- a/src/main/kotlin/com/lambda/util/player/prediction/PredictionTick.kt +++ b/src/main/kotlin/com/lambda/util/player/prediction/PredictionTick.kt @@ -17,7 +17,7 @@ package com.lambda.util.player.prediction -import com.lambda.interaction.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation import net.minecraft.util.math.Box import net.minecraft.util.math.Vec3d diff --git a/src/main/kotlin/com/lambda/util/world/raycast/RayCastUtils.kt b/src/main/kotlin/com/lambda/util/world/raycast/RayCastUtils.kt index 343b0e8ca..91ac2263e 100644 --- a/src/main/kotlin/com/lambda/util/world/raycast/RayCastUtils.kt +++ b/src/main/kotlin/com/lambda/util/world/raycast/RayCastUtils.kt @@ -19,7 +19,7 @@ package com.lambda.util.world.raycast import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.util.math.distSq import net.minecraft.client.network.ClientPlayerEntity import net.minecraft.entity.Entity diff --git a/src/test/kotlin/PlaceDirectionTest.kt b/src/test/kotlin/PlaceDirectionTest.kt index 02b5fb6e3..15c94436e 100644 --- a/src/test/kotlin/PlaceDirectionTest.kt +++ b/src/test/kotlin/PlaceDirectionTest.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -import com.lambda.interaction.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.util.PlaceDirection import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/test/kotlin/RotationTest.kt b/src/test/kotlin/RotationTest.kt index f57a3c33e..7c182d8c1 100644 --- a/src/test/kotlin/RotationTest.kt +++ b/src/test/kotlin/RotationTest.kt @@ -15,12 +15,12 @@ * along with this program. If not, see . */ -import com.lambda.interaction.managers.rotating.Rotation -import com.lambda.interaction.managers.rotating.Rotation.Companion.angleDifference -import com.lambda.interaction.managers.rotating.Rotation.Companion.dist -import com.lambda.interaction.managers.rotating.Rotation.Companion.lerp -import com.lambda.interaction.managers.rotating.Rotation.Companion.slerp -import com.lambda.interaction.managers.rotating.Rotation.Companion.wrap +import com.lambda.interaction.manager.managers.rotating.Rotation +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.angleDifference +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.dist +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.lerp +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.slerp +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.wrap import kotlin.math.abs import kotlin.math.hypot import kotlin.test.Test From bc1f3725843609033fccb74d7c6bdbad414812e2 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Tue, 28 Jul 2026 16:56:33 +0100 Subject: [PATCH 06/18] cleanup, still broken. Need to rework task chaining --- .../command/commands/TransferCommand.kt | 4 +- .../lambda/config/blocks/InventoryConfig.kt | 1 - .../interaction/handler/PostActionHandler.kt | 11 +- .../handler/handlers/ContainerHandler.kt | 1 - .../handlers/breaking/BrokenBlockHandler.kt | 2 +- .../handlers/breaking/RebreakHandler.kt | 2 +- .../interaction/inventory/StackSelection.kt | 11 ++ .../inventory/container/Container.kt | 28 ++-- .../containers/external/ChestContainer.kt | 25 ++-- .../external/EnderChestContainer.kt | 53 ++++---- .../external/PlacedShulkerBoxContainer.kt | 31 +++-- .../external/ShulkerBoxContainer.kt | 53 +++++--- .../com/lambda/interaction/manager/Manager.kt | 2 +- .../manager/managers/breaking/BreakInfo.kt | 2 +- .../manager/managers/breaking/BreakManager.kt | 8 +- .../manager/managers/breaking/BreakRequest.kt | 3 +- .../manager/managers/hotbar/HotbarRequest.kt | 1 - .../managers/interacting/InteractInfo.kt | 2 +- .../managers/interacting/InteractManager.kt | 29 ++-- .../managers/interacting/InteractRequest.kt | 2 +- .../managers/inventory/InventoryRequest.kt | 1 - .../containers/EnderChestContainer.kt | 0 .../module/modules/player/EndermanLook.kt | 4 +- .../module/modules/player/InventoryTweaks.kt | 4 +- .../lambda/module/modules/player/Replay.kt | 1 - .../lambda/module/modules/world/AutoPortal.kt | 1 - .../lambda/module/modules/world/StashMover.kt | 10 +- src/main/kotlin/com/lambda/task/RootTask.kt | 2 +- src/main/kotlin/com/lambda/task/Task.kt | 125 ++++++++++++++++-- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 1 - .../task/tasks/ContainerTransferTask.kt | 11 +- .../kotlin/com/lambda/task/tasks/EatTask.kt | 1 - .../kotlin/com/lambda/task/tasks/NoopTask.kt | 2 +- .../lambda/task/tasks/PlaceContainerTask.kt | 14 +- .../com/lambda/task/tasks/SlotByCacheTask.kt | 5 + .../com/lambda/util/player/SlotUtils.kt | 3 +- 36 files changed, 298 insertions(+), 158 deletions(-) delete mode 100644 src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index 86db90836..a9e046b44 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -96,11 +96,11 @@ object TransferCommand : LambdaCommand( isItem(stack().value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val fromContainer = ContainerHandler.filteredContainers().find { + val fromContainer = ContainerHandler.filteredContainers.find { it.name == from().value().split(".").last().trim() } ?: return@executeWithResult failure("From container not found") - val toContainer = ContainerHandler.filteredContainers().find { + val toContainer = ContainerHandler.filteredContainers.find { it.name == to().value().split(".").last().trim() } ?: return@executeWithResult failure("To container not found") diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index be5c27139..964f4732c 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -17,7 +17,6 @@ package com.lambda.config.blocks -import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer diff --git a/src/main/kotlin/com/lambda/interaction/handler/PostActionHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/PostActionHandler.kt index 5994bb01e..0c64982fb 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/PostActionHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/PostActionHandler.kt @@ -22,7 +22,6 @@ import com.lambda.event.events.ConnectionEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe -import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler import com.lambda.interaction.manager.ActionInfo import com.lambda.util.collections.LimitedDecayQueue @@ -52,8 +51,10 @@ abstract class PostActionHandler { pendingInteractionsList.remove(context) } - fun Automated.setPendingConfigs() { - BrokenBlockHandler.pendingActions.setSizeLimit(buildConfig.maxPendingActions) - BrokenBlockHandler.pendingActions.setDecayTime(buildConfig.actionTimeout * 50L) - } + context(automated: Automated) + fun setPendingConfigs() = + with(automated) { + pendingActions.setSizeLimit(buildConfig.maxPendingActions) + pendingActions.setDecayTime(buildConfig.actionTimeout * 50L) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index e7b91ede3..a14699fc4 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -30,7 +30,6 @@ import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.containers.external.ChestContainer import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer -import com.lambda.task.Task.Ta5kBuilder import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.ReflectionUtils.getInstances import com.lambda.util.extension.containerStacks diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt index 6477e2996..681358860 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt @@ -24,8 +24,8 @@ import com.lambda.event.events.EntityEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.processing.ProcessorRegistry -import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.rebreak import com.lambda.interaction.handler.PostActionHandler +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.reBreak import com.lambda.interaction.manager.managers.breaking.BreakInfo import com.lambda.interaction.manager.managers.breaking.BreakManager.lastPosStarted import com.lambda.interaction.manager.managers.breaking.BreakManager.matchesBlockItem diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt index eddb0987c..84c82a11f 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt @@ -25,7 +25,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock -import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.rebreak +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.reBreak import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler import com.lambda.interaction.handler.handlers.packet.PacketType import com.lambda.interaction.manager.managers.breaking.BreakInfo diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index 9e59af8b7..e83152448 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.inventory import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils +import com.lambda.util.player.SlotUtils.matches import net.minecraft.block.Block import net.minecraft.block.BlockState import net.minecraft.component.ComponentType @@ -189,6 +190,16 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { appendSelector { stack, _ -> stack.isEmpty} } + fun isSlot(slot: Slot) { + appendSelector { _, s -> + s != null && s matches slot + } + } + + fun isSlotByReference(slot: Slot) { + appendSelector { _, s -> s === slot } + } + fun custom(predicate: (ItemStack, Slot?) -> Boolean) { appendSelector { stack, slot -> predicate(stack, slot) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 1053ea0c6..195b4c803 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -26,11 +26,10 @@ import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.task.Task.Companion.taskOrSkipOrNull import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.TaskGenerator import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.ContainerTransferTask -import com.lambda.task.tasks.NoopTask.Companion.noopTask import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.empty @@ -110,15 +109,15 @@ abstract class Container( }?.map { slot -> ShulkerBoxContainer( slot.stack.shulkerBoxStacks, - containedIn = this@Container, - slot = slot + this@Container, + slot ) }?.toSet() ?: stacks.map { stack -> ShulkerBoxContainer( stack.shulkerBoxStacks, - containedIn = this@Container, - slot = null + this@Container, + null ) }.toSet() @@ -130,15 +129,14 @@ abstract class Container( @Ta5kBuilder context(automatedSafeContext: AutomatedSafeContext) - open fun accessThen( + open fun accessThen( closeAfter: Boolean = true, - afterClose: TaskOrNullGenerator? = null, - afterOpen: TaskGenerator = { noopTask() } + afterOpen: TaskOrNullGenerator = { null }, + afterClose: TaskOrNullGenerator = { null } ) = with(automatedSafeContext) { - afterOpen(Unit).also { - if (closeAfter && afterClose != null) { - it.thenOrNull { afterClose(Unit) } - } + taskOrSkipOrNull({ afterOpen(Unit) }) { result -> + if (closeAfter) afterClose(result) + else null } } @@ -174,8 +172,8 @@ abstract class Container( } context(automated: Automated) - fun transferByTask(stackSelection: StackSelection, destination: Container, failIfNoMaterial: Boolean = false) = - ContainerTransferTask(this, destination, stackSelection, failIfNoMaterial, automated) + fun transferByTask(stackSelection: StackSelection, toContainer: Container, failIfNoStack: Boolean = true) = + ContainerTransferTask(this, toContainer, stackSelection, failIfNoStack, automated) open fun stackCount(selection: StackSelection) = selection.filter(stacks).count diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt index 5a2cd8de9..9830a1e24 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt @@ -23,12 +23,8 @@ import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBl import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.PlacedContainer -import com.lambda.task.Task -import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.TaskGenerator +import com.lambda.task.Task.Companion.taskOrSkipOrNull import com.lambda.task.TaskOrNullGenerator -import com.lambda.task.tasks.NoopTask.Companion.noopTask -import com.lambda.task.tasks.OpenContainerTask import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction import com.lambda.util.extension.containerSlots @@ -38,7 +34,6 @@ import com.lambda.util.text.literal import net.minecraft.block.ChestBlock import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.item.ItemStack -import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos @@ -74,14 +69,20 @@ data class ChestContainer( mc.player?.currentScreenHandler?.type == ScreenHandlerType.GENERIC_9X3 } ?: false - context(_: AutomatedSafeContext) - override fun accessThen( + context(automatedSafeContext: AutomatedSafeContext) + override fun accessThen( closeAfter: Boolean, - afterClose: TaskOrNullGenerator?, - afterOpen: TaskGenerator + afterOpen: TaskOrNullGenerator, + afterClose: TaskOrNullGenerator ) = - openContainer(blockPos).then { - afterOpen(Unit).thenOrNull { + with(automatedSafeContext) { + taskOrSkipOrNull( + optional = { + openContainer(blockPos).thenOrNull { + afterOpen(Unit) + } + } + ) { if (closeAfter) { simpleAction("Close inventory") { player.closeHandledScreen() } } else null diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt index f81b87ddf..a046e168a 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt @@ -23,12 +23,11 @@ import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBl import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.task.TaskGenerator +import com.lambda.task.Task.Companion.taskOrSkipOrNull +import com.lambda.task.Task.Companion.wrappedTask import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.AcquireStackTask.Companion.acquireStack import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect -import com.lambda.task.tasks.NoopTask.Companion.noopTask -import com.lambda.task.tasks.OpenContainerTask import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction @@ -39,7 +38,7 @@ import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.screen.ScreenHandlerType -import kotlin.comparisons.then +import net.minecraft.util.math.BlockPos object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { override val slots @@ -58,34 +57,40 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { } ?: false context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( + override fun accessThen( closeAfter: Boolean, - afterClose: TaskOrNullGenerator?, - afterOpen: TaskGenerator + afterOpen: TaskOrNullGenerator, + afterClose: TaskOrNullGenerator ) = with(automatedSafeContext) { - if (!isAccessed) { - acquireStack(Items.ENDER_CHEST.select()).then { slot -> - placeContainer(slot).then { pos -> - openContainer(pos).then { - afterOpen(Unit).thenOrNull { - if (closeAfter) { - simpleAction("Close inventory") { player.closeHandledScreen() }.then { - breakAndCollect(pos, lifeMaintenance = false).thenOrNull { - afterClose?.invoke(this, Unit) - } + taskOrSkipOrNull( + optional = { + if (isAccessed) null + else { + wrappedTask("Setup Ender Chest") { success -> + acquireStack(Items.ENDER_CHEST.select(1)).then { slot -> + placeContainer(slot).then { pos -> + openContainer(pos).finally { + success(pos) } - } else null + } } } } } - } else afterOpen(Unit).thenOrNull { - if (closeAfter) { - simpleAction("Close inventory") { mc.player?.closeHandledScreen() }.thenOrNull { - afterClose?.invoke(this, Unit) - } - } else null + ) { pos -> + taskOrSkipOrNull({ afterOpen(Unit) }) { afterOpenResult -> + if (closeAfter) { + simpleAction("Close inventory") { player.closeHandledScreen() }.thenOrNull { + taskOrSkipOrNull( + optional = { + if (pos != null) breakAndCollect(pos) + else null + } + ) { afterClose(afterOpenResult) } + } + } else null + } } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt index 697a52783..009e58def 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt @@ -22,9 +22,8 @@ import com.lambda.context.AutomatedSafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.PlacedContainer -import com.lambda.task.TaskGenerator +import com.lambda.task.Task.Companion.taskOrSkipOrNull import com.lambda.task.TaskOrNullGenerator -import com.lambda.task.tasks.NoopTask.Companion.noopTask import com.lambda.task.tasks.OpenContainerTask import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction import com.lambda.util.extension.containerSlots @@ -67,19 +66,25 @@ class PlacedShulkerBoxContainer( } ?: false context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( + override fun accessThen( closeAfter: Boolean, - afterClose: TaskOrNullGenerator?, - afterOpen: TaskGenerator + afterOpen: TaskOrNullGenerator, + afterClose: TaskOrNullGenerator ) = - run { - if (!isAccessed) OpenContainerTask(blockPos, automated = automatedSafeContext) - else noopTask() - }.then { - afterOpen(Unit).thenOrNull { - if (closeAfter) { - simpleAction("Close Inventory") { automatedSafeContext.player.closeHandledScreen() } - } else null + with(automatedSafeContext) { + taskOrSkipOrNull( + optional = { + if (!isAccessed) OpenContainerTask(blockPos, automated = automatedSafeContext) + else null + } + ) { + taskOrSkipOrNull({ afterOpen(Unit) }) { result -> + if (closeAfter) { + simpleAction("Close Inventory") { + automatedSafeContext.player.closeHandledScreen() + }.thenOrNull { afterClose(result) } + } else null + } } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index 9d4091153..01a4b312c 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -19,18 +19,19 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.AutomatedSafeContext -import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.NestedContainer -import com.lambda.task.TaskGenerator +import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.task.Task.Companion.nullableWrappedTask +import com.lambda.task.Task.Companion.taskOrSkipOrNull import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction -import com.lambda.threading.runSafe import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -59,7 +60,6 @@ data class ShulkerBoxContainer( literal(" in slot $slotCache") } - private var placed = false private var blockPos: BlockPos? = null override val isAccessed @@ -71,22 +71,45 @@ data class ShulkerBoxContainer( } ?: false context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( + override fun accessThen( closeAfter: Boolean, - afterClose: TaskOrNullGenerator?, - afterOpen: TaskGenerator + afterOpen: TaskOrNullGenerator, + afterClose: TaskOrNullGenerator ) = with(automatedSafeContext) { - if (!isAccessed) { - - } else afterOpen(Unit).thenOrNull { - if (closeAfter) { - simpleAction("Close inventory") { player.closeHandledScreen() }.then { - breakAndCollect(blockPos, lifeMaintenance = false).thenOrNull { - afterClose?.invoke(this, Unit) + taskOrSkipOrNull( + optional = { + if (isAccessed) null + else nullableWrappedTask("Setup Shulker Box") { success -> + containedIn.accessThen( + afterOpen = { + if (player.currentScreenHandler.syncId == 0) null + else { + val selection = selectStack { isSlot(slotCache) } + containedIn.transferByTask(selection, HotbarContainer) + } + } + ) { slot -> + slot?.let { s -> + placeContainer(s).then { pos -> + openContainer(pos).finally { + success(pos) + } + } + } } } - } else null + } + ) { pos -> + taskOrSkipOrNull({ afterOpen(Unit) }) { result -> + if (closeAfter && pos != null) { + simpleAction("Close inventory") { player.closeHandledScreen() }.then { + breakAndCollect(pos).thenOrNull { + afterClose(result) + } + } + } else null + } } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/manager/Manager.kt b/src/main/kotlin/com/lambda/interaction/manager/Manager.kt index 842806fce..cab1aa21f 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/Manager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/Manager.kt @@ -25,7 +25,7 @@ import com.lambda.event.Event import com.lambda.event.events.TickEvent import com.lambda.event.events.TickEvent.Companion.ALL_STAGES import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.manager.managers.ManagerUtils.accumulatedManagerPriority +import com.lambda.interaction.manager.ManagerUtils.accumulatedManagerPriority import com.lambda.threading.runSafeAutomated import kotlin.reflect.KClass diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt index a25920312..d1830a959 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt @@ -22,7 +22,7 @@ import com.lambda.config.blocks.BreakConfig.BreakMode import com.lambda.context.SafeContext import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.handler.handlers.breaking.RebreakHandler -import com.lambda.interaction.manager.managers.ActionInfo +import com.lambda.interaction.manager.ActionInfo import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Primary import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Rebreak import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.RedundantSecondary diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt index c30170404..61d7d1234 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt @@ -34,9 +34,9 @@ import com.lambda.interaction.construction.simulation.BuildSimulator.simulate import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.pendingActions -import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.setPendingConfigs import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.startPending import com.lambda.interaction.handler.handlers.breaking.RebreakHandler import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.getRebreakPotential @@ -45,10 +45,8 @@ import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler import com.lambda.interaction.handler.handlers.packet.PacketType import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.manager.Manager +import com.lambda.interaction.manager.ManagerUtils.isPosBlocked import com.lambda.interaction.manager.PositionBlocking -import com.lambda.interaction.manager.managers.Manager -import com.lambda.interaction.manager.managers.ManagerUtils.isPosBlocked -import com.lambda.interaction.manager.managers.PositionBlocking import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Primary import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Rebreak import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.RedundantSecondary @@ -524,7 +522,7 @@ object BreakManager : Manager( } primaryBreak = breakInfo - setPendingConfigs() + BrokenBlockHandler.setPendingConfigs() return primaryBreak } diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt index 0a284cb3a..8b03b2c3f 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt @@ -27,7 +27,8 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.manager.managers.Request +import com.lambda.interaction.manager.Request +import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.isEmpty diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarRequest.kt index 682ec2993..904c32489 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/hotbar/HotbarRequest.kt @@ -19,7 +19,6 @@ package com.lambda.interaction.manager.managers.hotbar import com.lambda.context.Automated import com.lambda.interaction.manager.Request -import com.lambda.interaction.manager.managers.Request class HotbarRequest( val slot: Int, diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractInfo.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractInfo.kt index c5efd746c..a0401782e 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractInfo.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractInfo.kt @@ -21,7 +21,7 @@ import com.lambda.config.blocks.InteractConfig import com.lambda.context.SafeContext import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.context.InteractContext -import com.lambda.interaction.manager.managers.ActionInfo +import com.lambda.interaction.manager.ActionInfo import net.minecraft.util.math.BlockPos data class InteractInfo( diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt index 2b7983e23..4c57ca26a 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt @@ -18,7 +18,6 @@ package com.lambda.interaction.manager.managers.interacting import com.lambda.config.blocks.InteractConfig -import com.lambda.config.blocks.InteractConfig.AirPlaceMode import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext @@ -29,14 +28,13 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.InteractContext -import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler.pendingActions -import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler.setPendingConfigs +import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler.startPending import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler import com.lambda.interaction.handler.handlers.packet.PacketType -import com.lambda.interaction.manager.managers.Manager -import com.lambda.interaction.manager.managers.ManagerUtils.isPosBlocked -import com.lambda.interaction.manager.managers.PositionBlocking +import com.lambda.interaction.manager.Manager +import com.lambda.interaction.manager.ManagerUtils.isPosBlocked +import com.lambda.interaction.manager.PositionBlocking import com.lambda.interaction.manager.managers.breaking.BreakManager import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.interacting.InteractManager.activeRequest @@ -45,7 +43,7 @@ import com.lambda.interaction.manager.managers.interacting.InteractManager.popul import com.lambda.interaction.manager.managers.interacting.InteractManager.potentialInteractions import com.lambda.interaction.manager.managers.interacting.InteractManager.processRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest -import com.lambda.module.modules.world.AutoSign.signWriteDelay +import com.lambda.module.modules.world.AutoSign import com.lambda.threading.runConcurrent import com.lambda.threading.runSafeAutomated import com.lambda.threading.runSafeGameScheduled @@ -69,7 +67,6 @@ import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket import net.minecraft.sound.SoundCategory import net.minecraft.util.ActionResult -import net.minecraft.util.ActionResult.PassToDefaultBlockAction import net.minecraft.util.Hand import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.math.BlockPos @@ -90,7 +87,7 @@ object InteractManager : Manager( private val ClientPlayerEntity.validSneak get() = isSneaking == shouldSneak override val blockedPositions - get() = pendingActions.map { it.context.blockPos } + get() = InteractedBlockHandler.pendingActions.map { it.context.blockPos } private var cancellingSignScreens = 0 @@ -128,7 +125,7 @@ object InteractManager : Manager( } /** - * Accepts, and processes the request, as long as the current [activeRequest] is null, and the [BreakManager] has not + * Accepts, and processes the request, as long as the current [activeRequest] is null, and the [com.lambda.interaction.manager.managers.breaking.BreakManager] has not * been active this tick. If nowOrNothing is true, the request is cleared after the first process. * * @see processRequest @@ -166,7 +163,7 @@ object InteractManager : Manager( if (!hotbarRequest.done) break } var interactResult: InteractResult? = null - if (interactConfig.airPlace == AirPlaceMode.Grim) { + if (interactConfig.airPlace == InteractConfig.AirPlaceMode.Grim) { val inventoryRequest = inventoryRequest { swapHands() action { interactResult = performInteractions(request) } @@ -194,7 +191,7 @@ object InteractManager : Manager( if (!player.validSneak) return InteractResult.CompleteFailure if (tickStage !in interactConfig.tickStageMask) return InteractResult.CompleteFailure - val hand = if (interactConfig.airPlace == AirPlaceMode.Grim) Hand.OFF_HAND else Hand.MAIN_HAND + val hand = if (interactConfig.airPlace == InteractConfig.AirPlaceMode.Grim) Hand.OFF_HAND else Hand.MAIN_HAND val actionResult = if (ctx.preProcessingInfo.placing) placeBlock(ctx, request, hand) else interaction.interactBlock(player, if (ctx.preProcessingInfo.item != null) hand else Hand.MAIN_HAND, ctx.hitResult) @@ -214,7 +211,7 @@ object InteractManager : Manager( if (ctx.preProcessingInfo.placing && expectedState.block is AbstractSignBlock) { cancellingSignScreens++ runConcurrent { - delay(signWriteDelay) + delay(AutoSign.signWriteDelay) runSafeGameScheduled { connection.sendPacket { UpdateSignC2SPacket(ctx.blockPos, true, "", "", "", "") @@ -243,7 +240,7 @@ object InteractManager : Manager( * @see isPosBlocked */ private fun Automated.populateFrom(request: InteractRequest) { - setPendingConfigs() + InteractedBlockHandler.setPendingConfigs() potentialInteractions = request.contexts .distinctBy { it.blockPos } .filter { !isPosBlocked(it.blockPos) } @@ -287,7 +284,7 @@ object InteractManager : Manager( val actionResult = blockState.onUseWithItem(player.getStackInHand(hand), world, player, hand, hitResult) if (actionResult.isAccepted) return actionResult - if (actionResult is PassToDefaultBlockAction && hand == Hand.MAIN_HAND) { + if (actionResult is ActionResult.PassToDefaultBlockAction && hand == Hand.MAIN_HAND) { val actionResult2 = blockState.onUse(world, player, hitResult) if (actionResult2.isAccepted) return actionResult2 } @@ -411,4 +408,4 @@ object InteractManager : Manager( WrongSlot, CompleteFailure } -} +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt index 4aeb87bef..bc025b4d6 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt @@ -24,7 +24,7 @@ import com.lambda.interaction.construction.simulation.context.InteractContext import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.InteractResult -import com.lambda.interaction.manager.managers.Request +import com.lambda.interaction.manager.Request import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.matches diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryRequest.kt index 82d81e619..3a7521c21 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryRequest.kt @@ -20,7 +20,6 @@ package com.lambda.interaction.manager.managers.inventory import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.interaction.manager.Request -import com.lambda.interaction.manager.managers.Request import com.lambda.util.PacketUtils.sendPacket import com.lambda.util.player.SlotUtils.clickSlot import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt b/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt index 2920b0328..64b24ffb5 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt @@ -23,8 +23,8 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest -import com.lambda.interaction.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.distSq diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index ace2216cc..5004341e5 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -28,7 +28,7 @@ import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect -import com.lambda.task.tasks.OpenContainerTask +import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.PlaceContainerTask import com.lambda.util.item.ItemUtils.shulkerBoxes import net.minecraft.item.Items @@ -62,7 +62,7 @@ object InventoryTweaks : Module( lastOpenScreen = null placeAndOpen = PlaceContainerTask(slot, this@InventoryTweaks).then { placePos -> placedPos = placePos - OpenContainerTask(placePos, this@InventoryTweaks).finally { screenHandler -> + openContainer(placePos).finally { screenHandler -> lastOpenScreen = screenHandler } }.run() diff --git a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt index 698c00f3b..9ebf59a3b 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt @@ -34,7 +34,6 @@ import com.lambda.event.events.MovementEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.components.ClickGuiLayout -import com.lambda.interaction.handlers.TimerHandler import com.lambda.interaction.handler.handlers.TimerHandler import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.RotationMode diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 87d2289e0..73c860bf0 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -35,7 +35,6 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.util.DirectionMask import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index b37d23072..e9be28de2 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -38,13 +38,12 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer +import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.interaction.manager.managers.rotating.Rotation @@ -56,7 +55,7 @@ import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task import com.lambda.task.tasks.BuildTask.Companion.build -import com.lambda.task.tasks.OpenContainerTask +import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.BlockUtils.blockState @@ -748,10 +747,7 @@ object StashMover : Module( return } - OpenContainerTask( - pos, - StashMover - ).finally { + openContainer(pos).finally { finally(pos) }.execute(this@MoverBot) } diff --git a/src/main/kotlin/com/lambda/task/RootTask.kt b/src/main/kotlin/com/lambda/task/RootTask.kt index bc868991f..5c5c6af9d 100644 --- a/src/main/kotlin/com/lambda/task/RootTask.kt +++ b/src/main/kotlin/com/lambda/task/RootTask.kt @@ -29,7 +29,7 @@ object RootTask : Task() { } @Ta5kBuilder - fun Task<*>.run(task: TaskGenerator) { + fun Task<*>.run(task: TaskGenerator) { runSafe { task(Unit).execute(this@run) } diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index bd2f0dbaa..90c5be7fe 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -25,6 +25,8 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.modules.client.Client import com.lambda.module.modules.client.Client.verboseDebug +import com.lambda.task.Task.Companion.taskOrSkip +import com.lambda.task.Task.Companion.taskOrSkipOrNull import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.logError import com.lambda.util.Nameable @@ -33,8 +35,8 @@ import kotlin.time.Duration.Companion.milliseconds import kotlin.time.DurationUnit import kotlin.time.toDuration -typealias TaskGenerator = SafeContext.(R) -> Task<*> -typealias TaskOrNullGenerator = SafeContext.(R) -> Task<*>? +typealias TaskGenerator = SafeContext.(R) -> Task +typealias TaskOrNullGenerator = SafeContext.(R) -> Task? typealias TaskUnitGenerator = SafeContext.(R) -> Unit @Suppress("unused") @@ -49,12 +51,12 @@ abstract class Task : Nameable, Muteable { val isCompleted get() = state == State.Completed val size: Int get() = subTasks.sumOf { it.size } + 1 - private var nextTask: TaskGenerator? = null - private var nextTaskOrNull: TaskOrNullGenerator? = null + private var nextTask: TaskGenerator? = null + private var nextTaskOrNull: TaskOrNullGenerator? = null private var onFinish: TaskUnitGenerator? = null - private var onFail: TaskGenerator? = null - private var onFailOrNull: TaskOrNullGenerator? = null + private var onFail: TaskGenerator? = null + private var onFailOrNull: TaskOrNullGenerator? = null private var softFail = false enum class State { @@ -286,8 +288,7 @@ abstract class Task : Nameable, Muteable { * @return The current task instance (`Task`) to allow method chaining. */ @Ta5kBuilder - fun then(taskGenerator: TaskGenerator): Task { - require(nextTask == null && nextTaskOrNull == null) { "Cannot link multiple tasks to a single task" } + fun then(taskGenerator: TaskGenerator): Task { nextTask = taskGenerator return this } @@ -307,14 +308,42 @@ abstract class Task : Nameable, Muteable { * @return The current task instance (`Task`) to allow method chaining. */ @Ta5kBuilder - fun thenOrNull(taskGenerator: TaskOrNullGenerator): Task { - require(nextTask == null && nextTaskOrNull == null) { "Cannot link multiple tasks to a single task" } + fun thenOrNull(taskGenerator: TaskOrNullGenerator): Task { nextTaskOrNull = taskGenerator return this } + /** + * Chains an optional step whose typed result is forwarded to a mandatory continuation. + * + * If the [optional] generator returns a non-null [Task] of type [T] that completes + * with a result, the [then] continuation receives that result. If the [optional] + * generator returns null (step skipped), the [then] continuation receives null. + * + * This allows downstream steps to use the output of an optional step without + * storing state outside the task chain. + * + * @param T The result type of the optional step. + * @param optional A generator that may produce a task, or null to skip. + * @param then A continuation that receives the optional step's result as [T?]. + * @return The current task instance (`Task`) to allow method chaining. + */ + @Ta5kBuilder + fun thenOrSkip( + optional: TaskOrNullGenerator, + then: TaskOrNullGenerator + ): Task { + thenOrNull { result -> + val step = optional(result) + step?.thenOrNull { stepResult -> + then(stepResult) + } ?: then(null) + } + return this + } + @Ta5kBuilder - fun onFail(taskGenerator: TaskGenerator): Task { + fun onFail(taskGenerator: TaskGenerator): Task { require(onFail == null && onFailOrNull == null) { "Cannot have multiple onFail callbacks on a single task" } onFail = taskGenerator softFail() @@ -322,7 +351,7 @@ abstract class Task : Nameable, Muteable { } @Ta5kBuilder - fun onFailOrNull(taskGenerator: TaskOrNullGenerator): Task { + fun onFailOrNull(taskGenerator: TaskOrNullGenerator): Task { require(onFail == null && onFailOrNull == null) { "Cannot have multiple onFail callbacks on a single task" } onFailOrNull = taskGenerator softFail() @@ -372,4 +401,76 @@ abstract class Task : Nameable, Muteable { appendTaskTree(it, level + 1) } } + + companion object { + @Ta5kBuilder + fun SafeContext.taskOrSkip( + optional: TaskOrNullGenerator, + then: TaskGenerator + ): Task<*> { + val step = optional(Unit) + return step?.thenOrNull { stepResult -> + then(stepResult) + } ?: then(null) + } + + @Ta5kBuilder + fun SafeContext.taskOrSkipOrNull( + optional: TaskOrNullGenerator, + then: TaskOrNullGenerator + ): Task<*>? { + val step = optional(Unit) + return step?.thenOrNull { stepResult -> + then(stepResult) + } ?: then(null) + } + + /** + * Creates a task that runs a chain of subtasks and emits a custom result. + * + * Use this when you need an intermediate result (e.g. a [net.minecraft.util.math.BlockPos] from a + * placement step) to be the result type of the returned task, allowing it + * to flow through [taskOrSkip] / [thenOrSkip] / [taskOrSkipOrNull] as a nullable scoped value. + * + * The [builder] receives a `success` callback. Call `success(value)` when + * the chain reaches the point where the desired result is available. + * + * ```kotlin + * wrappedTask("Setup Ender Chest") { success -> + * acquireStack(selection).then { slot -> + * placeContainer(slot).then { pos -> + * openContainer(pos).finally { success(pos) } + * } + * } + * } + * ``` + */ + @Ta5kBuilder + fun wrappedTask( + name: String, + builder: SafeContext.(success: (R) -> Unit) -> Task<*> + ) = object : Task() { + override val name = name + private val self = this + + override fun SafeContext.onStart() { + val chain = builder { result -> self.success(result) } + chain.execute(self) + } + } + + @Ta5kBuilder + fun nullableWrappedTask( + name: String, + builder: SafeContext.(success: (R?) -> Unit) -> Task<*>? + ) = object : Task() { + override val name = name + private val self = this + + override fun SafeContext.onStart() { + val chain = builder { result -> self.success(result) } + chain?.execute(self) ?: self.success(null) + } + } + } } diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index 0f802c600..1f8e52634 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -46,7 +46,6 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.simulation.result.results.PreSimResult import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handlers.BaritoneHandler import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index a495f49c9..024f56bad 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -43,14 +43,13 @@ class ContainerTransferTask @Ta5kBuilder constructor( runSafeAutomated { if (fromContainer is ExternalContainer && toContainer is ExternalContainer) { fromContainer.accessThen( - true, - { - HotbarAndInventoryContainer.transferByTask(stackSelection, toContainer) - .finally { slot -> success(slot) } + afterOpen = { + fromContainer.transferByTask(stackSelection, HotbarAndInventoryContainer, failIfNoStack) } ) { - fromContainer.transferByTask(stackSelection, HotbarAndInventoryContainer) - }.execute(this@ContainerTransferTask) + HotbarAndInventoryContainer.transferByTask(stackSelection, toContainer, failIfNoStack) + .finally { slot -> success(slot) } + }?.execute(this@ContainerTransferTask) return@listen } diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index 9e086f5e4..0677ba082 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -26,7 +26,6 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest -import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.task.Task import com.lambda.threading.runSafeAutomated import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt b/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt index 47c34dea6..011031a41 100644 --- a/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt @@ -20,7 +20,7 @@ package com.lambda.task.tasks import com.lambda.context.SafeContext import com.lambda.task.Task -class NoopTask : Task() { +class NoopTask @Ta5kBuilder constructor() : Task() { override val name = "No-operation task" override fun SafeContext.onStart() { diff --git a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt index 96e807e4d..065f6bfa5 100644 --- a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt @@ -41,12 +41,17 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction class PlaceContainerTask @Ta5kBuilder constructor( - val slot: Slot, + val slot: Slot?, automated: Automated ) : Task(), Automated by automated { - override val name: String get() = "Placing container ${slot.stack.name.string}" + override val name: String get() = "Placing container ${slot?.stack?.name?.string}" override fun SafeContext.onStart() { + if (slot == null) { + failure("No slot provided") + return + } + val results = runSafeAutomated { BlockPos.iterateOutwards(player.blockPos, 4, 3, 4) .map { it.blockPos } @@ -97,13 +102,14 @@ class PlaceContainerTask @Ta5kBuilder constructor( else -> false } + @Suppress("unused") companion object { @Ta5kBuilder context(automated: Automated) - fun placeContainer(slot: Slot) = PlaceContainerTask(slot, automated) + fun placeContainer(slot: Slot?) = PlaceContainerTask(slot, automated) @Ta5kBuilder context(automated: Automated) - fun placeContainer(slot: () -> Slot) = PlaceContainerTask(slot(), automated) + fun placeContainer(slot: () -> Slot?) = PlaceContainerTask(slot(), automated) } } diff --git a/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt b/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt index 057b98d41..4402252b7 100644 --- a/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt @@ -33,4 +33,9 @@ class SlotByCacheTask @Ta5kBuilder constructor( if (slot != null) success(slot) else failure("Failed to find matching slot by cache: $slotCache") } + + companion object { + @Ta5kBuilder + fun slotByCache(slotCache: Slot) = SlotByCacheTask(slotCache) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt index 65a60cb96..c8cece603 100644 --- a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt +++ b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt @@ -68,5 +68,6 @@ object SlotUtils { inventory::class == slot.inventory::class && id == slot.id && x == slot.x && - y == slot.y + y == slot.y && + ItemStack.areEqual(stack, slot.stack) } From 4b3d4b40f470cd60ab972f7f399c4c0cc054c84a Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sun, 23 Aug 2026 16:55:25 +0100 Subject: [PATCH 07/18] initial merge --- .../inventory/container/Container.kt | 7 +- .../containers/external/ChestContainer.kt | 8 +- .../external/EnderChestContainer.kt | 10 +- .../external/PlacedShulkerBoxContainer.kt | 8 +- .../external/ShulkerBoxContainer.kt | 10 +- .../module/modules/movement/AutoWalk.kt | 4 +- .../modules/movement/elytrafly/ElytraFly.kt | 8 +- .../movement/elytrafly/GrimFireworkBox.kt | 2 +- .../lambda/module/modules/player/LineLock.kt | 8 +- src/main/kotlin/com/lambda/task/Task.kt | 112 +----------------- 10 files changed, 36 insertions(+), 141 deletions(-) diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 195b4c803..31ea7d518 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -26,10 +26,9 @@ import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest -import com.lambda.task.Task.Companion.taskOrSkipOrNull import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.ContainerTransferTask +import com.lambda.task.wrappers.TaskOrNullSupplier import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.empty @@ -131,8 +130,8 @@ abstract class Container( context(automatedSafeContext: AutomatedSafeContext) open fun accessThen( closeAfter: Boolean = true, - afterOpen: TaskOrNullGenerator = { null }, - afterClose: TaskOrNullGenerator = { null } + afterOpen: TaskOrNullSupplier = { null }, + afterClose: TaskOrNullSupplier = { null } ) = with(automatedSafeContext) { taskOrSkipOrNull({ afterOpen(Unit) }) { result -> if (closeAfter) afterClose(result) diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt index 9830a1e24..23625a41d 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt @@ -23,10 +23,10 @@ import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBl import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.PlacedContainer -import com.lambda.task.Task.Companion.taskOrSkipOrNull -import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction +import com.lambda.task.wrappers.TaskOrNullSupplier +import com.lambda.task.wrappers.thenOrNull import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -72,8 +72,8 @@ data class ChestContainer( context(automatedSafeContext: AutomatedSafeContext) override fun accessThen( closeAfter: Boolean, - afterOpen: TaskOrNullGenerator, - afterClose: TaskOrNullGenerator + afterOpen: TaskOrNullSupplier, + afterClose: TaskOrNullSupplier ) = with(automatedSafeContext) { taskOrSkipOrNull( diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt index a046e168a..0e1c1f4cd 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt @@ -23,14 +23,14 @@ import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBl import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.task.Task.Companion.taskOrSkipOrNull -import com.lambda.task.Task.Companion.wrappedTask -import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.AcquireStackTask.Companion.acquireStack import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction +import com.lambda.task.wrappers.TaskOrNullSupplier +import com.lambda.task.wrappers.then +import com.lambda.task.wrappers.thenOrNull import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal @@ -59,8 +59,8 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { context(automatedSafeContext: AutomatedSafeContext) override fun accessThen( closeAfter: Boolean, - afterOpen: TaskOrNullGenerator, - afterClose: TaskOrNullGenerator + afterOpen: TaskOrNullSupplier, + afterClose: TaskOrNullSupplier ) = with(automatedSafeContext) { taskOrSkipOrNull( diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt index 009e58def..1bd6bff54 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt @@ -22,10 +22,10 @@ import com.lambda.context.AutomatedSafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.PlacedContainer -import com.lambda.task.Task.Companion.taskOrSkipOrNull -import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.OpenContainerTask import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction +import com.lambda.task.wrappers.TaskOrNullSupplier +import com.lambda.task.wrappers.thenOrNull import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -68,8 +68,8 @@ class PlacedShulkerBoxContainer( context(automatedSafeContext: AutomatedSafeContext) override fun accessThen( closeAfter: Boolean, - afterOpen: TaskOrNullGenerator, - afterClose: TaskOrNullGenerator + afterOpen: TaskOrNullSupplier, + afterClose: TaskOrNullSupplier ) = with(automatedSafeContext) { taskOrSkipOrNull( diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index 01a4b312c..18c45fea5 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -25,13 +25,13 @@ import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.NestedContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.task.Task.Companion.nullableWrappedTask -import com.lambda.task.Task.Companion.taskOrSkipOrNull -import com.lambda.task.TaskOrNullGenerator import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction +import com.lambda.task.wrappers.TaskOrNullSupplier +import com.lambda.task.wrappers.then +import com.lambda.task.wrappers.thenOrNull import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -73,8 +73,8 @@ data class ShulkerBoxContainer( context(automatedSafeContext: AutomatedSafeContext) override fun accessThen( closeAfter: Boolean, - afterOpen: TaskOrNullGenerator, - afterClose: TaskOrNullGenerator + afterOpen: TaskOrNullSupplier, + afterClose: TaskOrNullSupplier ) = with(automatedSafeContext) { taskOrSkipOrNull( diff --git a/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt b/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt index 2c5492a24..d0dc18219 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt @@ -22,8 +22,8 @@ import com.lambda.context.SafeContext import com.lambda.event.events.MovementEvent import com.lambda.event.events.PacketEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.breaking.BreakManager -import com.lambda.interaction.managers.interacting.InteractManager +import com.lambda.interaction.manager.managers.breaking.BreakManager +import com.lambda.interaction.manager.managers.interacting.InteractManager import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.MathUtils.toDouble diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt index 4ea420a64..9026773f5 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt @@ -17,19 +17,19 @@ package com.lambda.module.modules.movement.elytrafly +import com.lambda.config.ConfigEditor.editSetting +import com.lambda.config.ConfigEditor.forEachSetting +import com.lambda.config.ConfigEditor.hideAllExcept import com.lambda.config.Tab import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig -import com.lambda.config.editSetting import com.lambda.config.entries.Setting.Companion.onValueChange -import com.lambda.config.forEachSetting -import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.event.events.ClientEvent import com.lambda.event.events.MovementEvent import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.module.Module import com.lambda.module.modules.movement.elytrafly.modes.BounceElytraFly import com.lambda.module.modules.movement.elytrafly.modes.GeneralElytraFly diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/GrimFireworkBox.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/GrimFireworkBox.kt index dd3344672..c70ead991 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/GrimFireworkBox.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/GrimFireworkBox.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.movement.elytrafly import com.lambda.context.SafeContext -import com.lambda.interaction.managers.rotating.RotationManager +import com.lambda.interaction.manager.managers.rotating.RotationManager import net.minecraft.util.math.MathHelper import net.minecraft.util.math.Vec3d import kotlin.math.asin diff --git a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt index df99b71f8..b1105ff51 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt @@ -17,17 +17,17 @@ package com.lambda.module.modules.player +import com.lambda.config.ConfigEditor.editSetting +import com.lambda.config.ConfigEditor.hideAllExcept import com.lambda.config.Group import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig -import com.lambda.config.editSetting -import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer -import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest -import com.lambda.interaction.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationMode +import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index 6071df718..109b3c1c4 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -25,8 +25,6 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.modules.client.Client.verboseDebug import com.lambda.task.wrappers.onFail -import com.lambda.task.Task.Companion.taskOrSkip -import com.lambda.task.Task.Companion.taskOrSkipOrNull import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.logError import com.lambda.util.Nameable @@ -44,7 +42,6 @@ abstract class Task : Nameable, Muteable { override val isMuted: Boolean get() = state == State.Paused || state == State.Init var age = 0 private val depth: Int get() = parent?.depth?.plus(1) ?: 0 - val isCompleted get() = state == State.Completed val size: Int get() = subTasks.sumOf { it.size } + 1 private val successCallbacks = mutableListOf Unit>() @@ -222,13 +219,13 @@ abstract class Task : Nameable, Muteable { } @Ta5kBuilder - protected open fun onSubTaskCompletion(subTask: Task<*>) { - activate() + protected open fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { + failure(cause) } @Ta5kBuilder - protected open fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { - failure(cause) + protected open fun onSubTaskCompletion(subTask: Task<*>) { + activate() } /** @@ -240,35 +237,6 @@ abstract class Task : Nameable, Muteable { return this } - /** - * Chains an optional step whose typed result is forwarded to a mandatory continuation. - * - * If the [optional] generator returns a non-null [Task] of type [T] that completes - * with a result, the [then] continuation receives that result. If the [optional] - * generator returns null (step skipped), the [then] continuation receives null. - * - * This allows downstream steps to use the output of an optional step without - * storing state outside the task chain. - * - * @param T The result type of the optional step. - * @param optional A generator that may produce a task, or null to skip. - * @param then A continuation that receives the optional step's result as [T?]. - * @return The current task instance (`Task`) to allow method chaining. - */ - @Ta5kBuilder - fun thenOrSkip( - optional: TaskOrNullGenerator, - then: TaskOrNullGenerator - ): Task { - thenOrNull { result -> - val step = optional(result) - step?.thenOrNull { stepResult -> - then(stepResult) - } ?: then(null) - } - return this - } - /** * Registers a callback for if the task fails. * @@ -305,76 +273,4 @@ abstract class Task : Nameable, Muteable { appendTaskTree(it, level + 1) } } - - companion object { - @Ta5kBuilder - fun SafeContext.taskOrSkip( - optional: TaskOrNullGenerator, - then: TaskGenerator - ): Task<*> { - val step = optional(Unit) - return step?.thenOrNull { stepResult -> - then(stepResult) - } ?: then(null) - } - - @Ta5kBuilder - fun SafeContext.taskOrSkipOrNull( - optional: TaskOrNullGenerator, - then: TaskOrNullGenerator - ): Task<*>? { - val step = optional(Unit) - return step?.thenOrNull { stepResult -> - then(stepResult) - } ?: then(null) - } - - /** - * Creates a task that runs a chain of subtasks and emits a custom result. - * - * Use this when you need an intermediate result (e.g. a [net.minecraft.util.math.BlockPos] from a - * placement step) to be the result type of the returned task, allowing it - * to flow through [taskOrSkip] / [thenOrSkip] / [taskOrSkipOrNull] as a nullable scoped value. - * - * The [builder] receives a `success` callback. Call `success(value)` when - * the chain reaches the point where the desired result is available. - * - * ```kotlin - * wrappedTask("Setup Ender Chest") { success -> - * acquireStack(selection).then { slot -> - * placeContainer(slot).then { pos -> - * openContainer(pos).finally { success(pos) } - * } - * } - * } - * ``` - */ - @Ta5kBuilder - fun wrappedTask( - name: String, - builder: SafeContext.(success: (R) -> Unit) -> Task<*> - ) = object : Task() { - override val name = name - private val self = this - - override fun SafeContext.onStart() { - val chain = builder { result -> self.success(result) } - chain.execute(self) - } - } - - @Ta5kBuilder - fun nullableWrappedTask( - name: String, - builder: SafeContext.(success: (R?) -> Unit) -> Task<*>? - ) = object : Task() { - override val name = name - private val self = this - - override fun SafeContext.onStart() { - val chain = builder { result -> self.success(result) } - chain?.execute(self) ?: self.success(null) - } - } - } } From d2966cf4e3f5be6510f2ae9e6868bdf806272779 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:35:43 +0100 Subject: [PATCH 08/18] idk, a bunch of stuff --- .../brigadier/argument/BlockArguments.kt | 20 +-- .../brigadier/argument/GeometricArguments.kt | 25 ++- .../brigadier/argument/IdentifierArguments.kt | 60 +++---- .../brigadier/argument/ItemArguments.kt | 30 ++-- .../brigadier/argument/MiscArguments.kt | 25 ++- .../lambda/brigadier/argument/NBTArguments.kt | 30 ++-- .../brigadier/argument/PlayerArguments.kt | 70 ++------ .../brigadier/argument/PrimitiveArguments.kt | 50 +++--- .../lambda/command/commands/BuildCommand.kt | 2 +- .../lambda/config/blocks/InventoryConfig.kt | 21 +-- .../lambda/config/blocks/InventorySettings.kt | 17 +- .../config/settings/complex/KeybindSetting.kt | 1 - src/main/kotlin/com/lambda/gui/MenuBar.kt | 1 - .../kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt | 4 +- .../simulation/result/results/BreakResult.kt | 3 +- .../result/results/GenericResult.kt | 3 +- .../handler/handlers/ContainerHandler.kt | 4 +- .../interaction/inventory/StackSelection.kt | 13 +- .../inventory/container/Container.kt | 15 +- .../inventory/container/ExternalContainer.kt | 3 +- .../inventory/container/NestedContainer.kt | 2 +- .../inventory/container/OpenContainerTask.kt} | 21 ++- .../container/OpenedContainerContext.kt | 40 +++++ .../containers/external/ChestContainer.kt | 50 +++--- .../external/EnderChestContainer.kt | 101 ++++++----- .../external/PlacedShulkerBoxContainer.kt | 48 +++-- .../external/ShulkerBoxContainer.kt | 99 ++++++----- .../manager/managers/breaking/BreakRequest.kt | 68 +++---- .../managers/interacting/InteractRequest.kt | 47 ++--- .../module/modules/combat/PlayerTrap.kt | 2 +- .../lambda/module/modules/combat/Surround.kt | 2 +- .../module/modules/debug/ContainerTest.kt | 2 +- .../module/modules/movement/TargetStrafe.kt | 4 +- .../modules/movement/elytrafly/ElytraFly.kt | 6 +- .../elytrafly/modes/GrimControlElytraFly.kt | 4 - .../lambda/module/modules/player/AutoEat.kt | 4 +- .../lambda/module/modules/player/FastBreak.kt | 2 +- .../module/modules/player/InventoryTweaks.kt | 8 +- .../lambda/module/modules/player/LineLock.kt | 4 +- .../module/modules/player/StackReplenish.kt | 2 +- .../lambda/module/modules/world/AirPlace.kt | 2 +- .../lambda/module/modules/world/AutoPortal.kt | 4 +- .../module/modules/world/AutoVillagerCycle.kt | 4 +- .../module/modules/world/HighwayTools.kt | 2 +- .../com/lambda/module/modules/world/Nuker.kt | 2 +- .../lambda/module/modules/world/Printer.kt | 2 +- .../lambda/module/modules/world/Scaffold.kt | 2 +- .../lambda/module/modules/world/StashMover.kt | 7 +- src/main/kotlin/com/lambda/task/RootTask.kt | 3 +- src/main/kotlin/com/lambda/task/Task.kt | 10 +- .../task/tasks/AcquirePlacedBlockTask.kt | 51 +++--- .../com/lambda/task/tasks/AcquireStackTask.kt | 27 ++- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 100 +++++------ .../task/tasks/ContainerTransferTask.kt | 73 ++++---- .../kotlin/com/lambda/task/tasks/EatTask.kt | 13 +- .../lambda/task/tasks/FindPlacedBlockTask.kt | 45 +++++ .../lambda/task/tasks/OpenContainerTask.kt | 21 ++- .../lambda/task/tasks/PlaceContainerTask.kt | 25 ++- .../com/lambda/task/tasks/SimpleActionTask.kt | 13 +- .../com/lambda/task/tasks/SlotByCacheTask.kt | 11 +- .../wrappers/ActionTasks.kt} | 27 ++- .../lambda/task/tasks/wrappers/BranchTasks.kt | 103 +++++++++++ .../lambda/task/tasks/wrappers/OnFailTasks.kt | 167 ++++++++++++++++++ .../lambda/task/tasks/wrappers/ResultTasks.kt | 57 ++++++ .../{ => tasks}/wrappers/SequenceTasks.kt | 58 ++++-- .../task/{ => tasks}/wrappers/SoftFailTask.kt | 7 +- .../com/lambda/task/wrappers/RecoveryTasks.kt | 92 ---------- .../com/lambda/util/world/WorldUtils.kt | 14 +- 68 files changed, 1049 insertions(+), 806 deletions(-) rename src/main/kotlin/com/lambda/{task/tasks/NoopTask.kt => interaction/inventory/container/OpenContainerTask.kt} (60%) create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt create mode 100644 src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt rename src/main/kotlin/com/lambda/task/{wrappers/ActionTask.kt => tasks/wrappers/ActionTasks.kt} (69%) create mode 100644 src/main/kotlin/com/lambda/task/tasks/wrappers/BranchTasks.kt create mode 100644 src/main/kotlin/com/lambda/task/tasks/wrappers/OnFailTasks.kt create mode 100644 src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt rename src/main/kotlin/com/lambda/task/{ => tasks}/wrappers/SequenceTasks.kt (58%) rename src/main/kotlin/com/lambda/task/{ => tasks}/wrappers/SoftFailTask.kt (89%) delete mode 100644 src/main/kotlin/com/lambda/task/wrappers/RecoveryTasks.kt diff --git a/src/main/kotlin/com/lambda/brigadier/argument/BlockArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/BlockArguments.kt index bafbb787a..9c0034f3f 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/BlockArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/BlockArguments.kt @@ -37,9 +37,8 @@ import java.util.function.Predicate * @see BlockPredicateArgumentType.getBlockPredicate */ @BrigadierDsl -fun DefaultArgumentReader.value(): Predicate { - return BlockPredicateArgumentType.getBlockPredicate(context.assumeSourceNotUsed(), name) -} +fun DefaultArgumentReader.value(): Predicate = + BlockPredicateArgumentType.getBlockPredicate(context.assumeSourceNotUsed(), name) /** * Reads the [BlockStateArgument] value of the argument in @@ -48,9 +47,8 @@ fun DefaultArgumentReader.value(): Predicate.value(): BlockStateArgument { - return BlockStateArgumentType.getBlockState(context.assumeSourceNotUsed(), name) -} +fun DefaultArgumentReader.value(): BlockStateArgument = + BlockStateArgumentType.getBlockState(context.assumeSourceNotUsed(), name) /** * Creates a block predicate argument with [name] as the parameter name. @@ -62,9 +60,8 @@ fun DefaultArgumentReader.value(): BlockStateArgument { fun blockPredicate( name: String, registryAccess: CommandRegistryAccess, -): DefaultArgumentConstructor { - return argument(name, BlockPredicateArgumentType.blockPredicate(registryAccess)) -} +): DefaultArgumentConstructor = + argument(name, BlockPredicateArgumentType.blockPredicate(registryAccess)) /** * Creates a block state argument with [name] as the parameter name. @@ -76,6 +73,5 @@ fun blockPredicate( fun blockState( name: String, registryAccess: CommandRegistryAccess, -): DefaultArgumentConstructor { - return argument(name, BlockStateArgumentType.blockState(registryAccess)) -} +): DefaultArgumentConstructor = + argument(name, BlockStateArgumentType.blockState(registryAccess)) diff --git a/src/main/kotlin/com/lambda/brigadier/argument/GeometricArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/GeometricArguments.kt index 6c2117456..065bb8e0c 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/GeometricArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/GeometricArguments.kt @@ -167,9 +167,8 @@ fun rotation(name: String): DefaultArgumentConstructor swizzle( name: String, -): DefaultArgumentConstructor { - return argument(name, SwizzleArgumentType.swizzle()) -} +): DefaultArgumentConstructor = + argument(name, SwizzleArgumentType.swizzle()) /** * Creates a block pos argument with [name] as the parameter name. @@ -177,9 +176,8 @@ fun swizzle( @BrigadierDsl fun blockPos( name: String, -): DefaultArgumentConstructor { - return argument(name, BlockPosArgumentType.blockPos()) -} +): DefaultArgumentConstructor = + argument(name, BlockPosArgumentType.blockPos()) /** * Creates a column pos argument with [name] as the parameter name. @@ -187,9 +185,8 @@ fun blockPos( @BrigadierDsl fun columnPos( name: String, -): DefaultArgumentConstructor { - return argument(name, ColumnPosArgumentType.columnPos()) -} +): DefaultArgumentConstructor = + argument(name, ColumnPosArgumentType.columnPos()) /** * Creates a vec2 argument with [name] as the parameter name. @@ -200,9 +197,8 @@ fun columnPos( fun vec2( name: String, centerIntegers: Boolean = false, -): DefaultArgumentConstructor { - return argument(name, Vec2ArgumentType.vec2(centerIntegers)) -} +): DefaultArgumentConstructor = + argument(name, Vec2ArgumentType.vec2(centerIntegers)) /** * Creates a vec3 argument with [name] as the parameter name. @@ -213,6 +209,5 @@ fun vec2( fun vec3( name: String, centerIntegers: Boolean = false, -): DefaultArgumentConstructor { - return argument(name, Vec3ArgumentType.vec3(centerIntegers)) -} +): DefaultArgumentConstructor = + argument(name, Vec3ArgumentType.vec3(centerIntegers)) diff --git a/src/main/kotlin/com/lambda/brigadier/argument/IdentifierArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/IdentifierArguments.kt index c88a39cb3..d2a3b0218 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/IdentifierArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/IdentifierArguments.kt @@ -27,8 +27,6 @@ import com.lambda.brigadier.assumeSourceNotUsed import net.minecraft.advancement.AdvancementEntry import net.minecraft.command.argument.IdentifierArgumentType import net.minecraft.command.argument.RegistryKeyArgumentType -import net.minecraft.loot.condition.LootCondition -import net.minecraft.loot.function.LootFunction import net.minecraft.recipe.RecipeEntry import net.minecraft.server.command.ServerCommandSource import net.minecraft.util.Identifier @@ -41,9 +39,8 @@ import net.minecraft.util.Identifier */ @JvmName("valueIdentifierArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Identifier { - return IdentifierArgumentType.getIdentifier(context.assumeSourceNotUsed(), name) -} +fun DefaultArgumentReader.value(): Identifier = + IdentifierArgumentType.getIdentifier(context.assumeSourceNotUsed(), name) /** * Reads the [Identifier] value from the @@ -53,22 +50,16 @@ fun DefaultArgumentReader.value(): Identifier { * @see RegistryKeyArgumentType.getAdvancementEntry */ @BrigadierDsl -fun ArgumentReader< - ServerCommandSource, - DefaultArgumentDescriptor< - IdentifierArgumentType - > - >.asAdvancement(): AdvancementEntry { - return RegistryKeyArgumentType.getAdvancementEntry(context, name) -} +fun ArgumentReader>.asAdvancement(): AdvancementEntry = + RegistryKeyArgumentType.getAdvancementEntry(context, name) -/** - * Reads the [Identifier] value from the - * argument in the receiver [ArgumentReader] - * as a [LootCondition]. - * - * @see IdentifierArgumentType.getPredicateArgument - */ +///** +// * Reads the [Identifier] value from the +// * argument in the receiver [ArgumentReader] +// * as a [LootCondition]. +// * +// * @see IdentifierArgumentType.getPredicateArgument +// */ //@BrigadierDsl //fun ArgumentReader< // ServerCommandSource, @@ -79,13 +70,13 @@ fun ArgumentReader< // return IdentifierArgumentType.getPredicateArgument(context, name) //} -/** - * Reads the [Identifier] value from the - * argument in the receiver [ArgumentReader] - * as a [LootFunction]. - * - * @see IdentifierArgumentType.getItemModifierArgument - */ +///** +// * Reads the [Identifier] value from the +// * argument in the receiver [ArgumentReader] +// * as a [LootFunction]. +// * +// * @see IdentifierArgumentType.getItemModifierArgument +// */ //@BrigadierDsl //fun ArgumentReader< // ServerCommandSource, @@ -104,14 +95,8 @@ fun ArgumentReader< * @see IdentifierArgumentType.getRecipeArgument */ @BrigadierDsl -fun ArgumentReader< - ServerCommandSource, - DefaultArgumentDescriptor< - IdentifierArgumentType - > - >.asRecipe(): RecipeEntry<*> { - return RegistryKeyArgumentType.getRecipeEntry(context, name) -} +fun ArgumentReader>.asRecipe(): RecipeEntry<*> = + RegistryKeyArgumentType.getRecipeEntry(context, name) /** * Creates an identifier argument with [name] as the parameter name. @@ -119,6 +104,5 @@ fun ArgumentReader< @BrigadierDsl fun identifier( name: String, -): DefaultArgumentConstructor { - return argument(name, IdentifierArgumentType.identifier()) -} +): DefaultArgumentConstructor = + argument(name, IdentifierArgumentType.identifier()) diff --git a/src/main/kotlin/com/lambda/brigadier/argument/ItemArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/ItemArguments.kt index 846cdb2e3..ecaa559ef 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/ItemArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/ItemArguments.kt @@ -46,9 +46,8 @@ import java.util.function.Predicate */ @JvmName("valueItemPredicateArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Predicate { - return ItemPredicateArgumentType.getItemStackPredicate(context.assumeSourceNotUsed(), name) -} +fun DefaultArgumentReader.value(): Predicate = + ItemPredicateArgumentType.getItemStackPredicate(context.assumeSourceNotUsed(), name) /** * Reads the integer value from the @@ -58,9 +57,8 @@ fun DefaultArgumentReader.value(): Predicate.value(): Int { - return ItemSlotArgumentType.getItemSlot(context.assumeSourceNotUsed(), name) -} +fun DefaultArgumentReader.value(): Int = + ItemSlotArgumentType.getItemSlot(context.assumeSourceNotUsed(), name) /** * Reads the [ItemStackArgument] value from the @@ -70,9 +68,8 @@ fun DefaultArgumentReader.value(): Int { */ @JvmName("valueItemStackArg") @BrigadierDsl -fun DefaultArgumentReader.value(): ItemStackArgument { - return ItemStackArgumentType.getItemStackArgument(context, name) -} +fun DefaultArgumentReader.value(): ItemStackArgument = + ItemStackArgumentType.getItemStackArgument(context, name) /** * Creates an item predicate argument with [name] as the parameter name. @@ -83,9 +80,8 @@ fun DefaultArgumentReader.value(): ItemStackArgument { fun itemPredicate( name: String, context: CommandRegistryAccess, -): DefaultArgumentConstructor { - return argument(name, ItemPredicateArgumentType.itemPredicate(context)) -} +): DefaultArgumentConstructor = + argument(name, ItemPredicateArgumentType.itemPredicate(context)) /** * Creates an item slot argument with [name] as the parameter name. @@ -93,9 +89,8 @@ fun itemPredicate( @BrigadierDsl fun itemSlot( name: String, -): DefaultArgumentConstructor { - return argument(name, ItemSlotArgumentType.itemSlot()) -} +): DefaultArgumentConstructor = + argument(name, ItemSlotArgumentType.itemSlot()) /** * Creates an item stack argument with [name] as the parameter name. @@ -106,6 +101,5 @@ fun itemSlot( fun itemStack( name: String, context: CommandRegistryAccess, -): DefaultArgumentConstructor { - return argument(name, ItemStackArgumentType.itemStack(context)) -} +): DefaultArgumentConstructor = + argument(name, ItemStackArgumentType.itemStack(context)) diff --git a/src/main/kotlin/com/lambda/brigadier/argument/MiscArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/MiscArguments.kt index 3deb92a56..7a2c1f498 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/MiscArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/MiscArguments.kt @@ -48,9 +48,8 @@ object LiteralDescriptor : ArgumentDescriptor> */ @JvmName("valueTimeArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Int { - return IntegerArgumentType.getInteger(context, name) -} // TimeArgumentType does not provide an accessor, defaulting to int +fun DefaultArgumentReader.value(): Int = + IntegerArgumentType.getInteger(context, name) // TimeArgumentType does not provide an accessor, defaulting to int /** * Reads the [UUID] value from the @@ -60,9 +59,8 @@ fun DefaultArgumentReader.value(): Int { */ @JvmName("valueUuidArg") @BrigadierDsl -fun DefaultArgumentReader.value(): UUID { - return UuidArgumentType.getUuid(context.assumeSourceNotUsed(), name) -} +fun DefaultArgumentReader.value(): UUID = + UuidArgumentType.getUuid(context.assumeSourceNotUsed(), name) /** * Creates a time argument with [name] as the parameter name. @@ -73,9 +71,8 @@ fun DefaultArgumentReader.value(): UUID { fun time( name: String, minimumTicks: Int = 0, -): DefaultArgumentConstructor { - return argument(name, TimeArgumentType.time(minimumTicks)) -} +): DefaultArgumentConstructor = + argument(name, TimeArgumentType.time(minimumTicks)) /** * Creates a UUID argument with [name] as the parameter name. @@ -83,9 +80,8 @@ fun time( @BrigadierDsl fun uuid( name: String, -): RequiredArgumentConstructor> { - return argument(name, UuidArgumentType.uuid()) -} +): RequiredArgumentConstructor> = + argument(name, UuidArgumentType.uuid()) /** * Creates a literal argument with [name] as the literal. @@ -98,6 +94,5 @@ fun uuid( @BrigadierDsl fun literal( name: String, -): ArgumentConstructor, LiteralDescriptor> { - return ArgumentConstructor(LiteralArgumentBuilder.literal(name), name, LiteralDescriptor) -} +): ArgumentConstructor, LiteralDescriptor> = + ArgumentConstructor(LiteralArgumentBuilder.literal(name), name, LiteralDescriptor) diff --git a/src/main/kotlin/com/lambda/brigadier/argument/NBTArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/NBTArguments.kt index 08122cc82..41a7c13ac 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/NBTArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/NBTArguments.kt @@ -45,9 +45,8 @@ import net.minecraft.nbt.NbtElement */ @JvmName("valueNbtCompoundArg") @BrigadierDsl -fun DefaultArgumentReader.value(): NbtCompound { - return NbtCompoundArgumentType.getNbtCompound(context, name) -} +fun DefaultArgumentReader.value(): NbtCompound = + NbtCompoundArgumentType.getNbtCompound(context, name) /** * Reads the [NbtElement] value from the @@ -57,9 +56,8 @@ fun DefaultArgumentReader.value(): NbtCompound { */ @JvmName("valueNbtElementArg") @BrigadierDsl -fun DefaultArgumentReader.value(): NbtElement { - return NbtElementArgumentType.getNbtElement(context, name) -} +fun DefaultArgumentReader.value(): NbtElement = + NbtElementArgumentType.getNbtElement(context, name) /** * Reads the [NbtPath] value from the @@ -69,9 +67,8 @@ fun DefaultArgumentReader.value(): NbtElement { */ @JvmName("valueNbtPathArg") @BrigadierDsl -fun DefaultArgumentReader.value(): NbtPath { - return NbtPathArgumentType.getNbtPath(context.assumeSourceNotUsed(), name) -} +fun DefaultArgumentReader.value(): NbtPath = + NbtPathArgumentType.getNbtPath(context.assumeSourceNotUsed(), name) /** * Creates a nbt compound argument with [name] as the parameter name. @@ -79,9 +76,8 @@ fun DefaultArgumentReader.value(): NbtPath { @BrigadierDsl fun nbtCompound( name: String, -): DefaultArgumentConstructor { - return argument(name, NbtCompoundArgumentType.nbtCompound()) -} +): DefaultArgumentConstructor = + argument(name, NbtCompoundArgumentType.nbtCompound()) /** * Creates an NBT element argument with [name] as the parameter name. @@ -89,9 +85,8 @@ fun nbtCompound( @BrigadierDsl fun nbtElement( name: String, -): DefaultArgumentConstructor { - return argument(name, NbtElementArgumentType.nbtElement()) -} +): DefaultArgumentConstructor = + argument(name, NbtElementArgumentType.nbtElement()) /** * Creates an NBT path argument with [name] as the parameter name. @@ -99,6 +94,5 @@ fun nbtElement( @BrigadierDsl fun nbtPath( name: String, -): DefaultArgumentConstructor { - return argument(name, NbtPathArgumentType.nbtPath()) -} +): DefaultArgumentConstructor = + argument(name, NbtPathArgumentType.nbtPath()) diff --git a/src/main/kotlin/com/lambda/brigadier/argument/PlayerArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/PlayerArguments.kt index 102021f26..36169393c 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/PlayerArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/PlayerArguments.kt @@ -65,14 +65,8 @@ object ListPlayerArgumentDescriptor : ArgumentDescriptor */ @JvmName("valueGameProfileArg") @BrigadierDsl -fun ArgumentReader< - ServerCommandSource, - DefaultArgumentDescriptor< - GameProfileArgumentType - > - >.value(): Collection { - return GameProfileArgumentType.getProfileArgument(context, name) -} +fun ArgumentReader>.value(): Collection = + GameProfileArgumentType.getProfileArgument(context, name) /** * Reads the [Team] value from the @@ -82,14 +76,8 @@ fun ArgumentReader< */ @JvmName("valueTeamArg") @BrigadierDsl -fun ArgumentReader< - ServerCommandSource, - DefaultArgumentDescriptor< - TeamArgumentType - > - >.value(): Team { - return TeamArgumentType.getTeam(context, name) -} +fun ArgumentReader>.value(): Team = + TeamArgumentType.getTeam(context, name) /** * Reads the [ServerPlayerEntity] value from the @@ -99,12 +87,8 @@ fun ArgumentReader< */ @JvmName("valuePlayerArg") @BrigadierDsl -fun ArgumentReader< - ServerCommandSource, - SinglePlayerArgumentDescriptor - >.value(): ServerPlayerEntity { - return EntityArgumentType.getPlayer(context, name) -} +fun ArgumentReader.value(): ServerPlayerEntity = + EntityArgumentType.getPlayer(context, name) /** * Reads the collection of players from the argument in @@ -116,12 +100,8 @@ fun ArgumentReader< */ @JvmName("requiredPlayerArg") @BrigadierDsl -fun ArgumentReader< - ServerCommandSource, - ListPlayerArgumentDescriptor - >.required(): Collection { - return EntityArgumentType.getPlayers(context, name) -} +fun ArgumentReader.required(): Collection = + EntityArgumentType.getPlayers(context, name) /** * Reads the collection of players from the argument in @@ -133,12 +113,8 @@ fun ArgumentReader< */ @JvmName("optionalPlayerArg") @BrigadierDsl -fun ArgumentReader< - ServerCommandSource, - ListPlayerArgumentDescriptor - >.optional(): Collection { - return EntityArgumentType.getOptionalPlayers(context, name) -} +fun ArgumentReader.optional(): Collection = + EntityArgumentType.getOptionalPlayers(context, name) /** * Creates a game profile argument with [name] as the parameter name. @@ -146,9 +122,8 @@ fun ArgumentReader< @BrigadierDsl fun gameProfile( name: String, -): DefaultArgumentConstructor { - return argument(name, GameProfileArgumentType.gameProfile()) -} +): DefaultArgumentConstructor = + argument(name, GameProfileArgumentType.gameProfile()) /** * Creates a team argument with [name] as the parameter name. @@ -156,9 +131,8 @@ fun gameProfile( @BrigadierDsl fun team( name: String, -): DefaultArgumentConstructor { - return argument(name, TeamArgumentType.team()) -} +): DefaultArgumentConstructor = + argument(name, TeamArgumentType.team()) /** * Creates a player selector argument with [name] as the parameter name. @@ -166,12 +140,8 @@ fun team( @BrigadierDsl fun player( name: String, -): RequiredArgumentConstructor< - S, - SinglePlayerArgumentDescriptor - > { - return argument(name, EntityArgumentType.player(), SinglePlayerArgumentDescriptor) -} +): RequiredArgumentConstructor = + argument(name, EntityArgumentType.player(), SinglePlayerArgumentDescriptor) /** * Creates a multiple player selector argument with [name] as the parameter name. @@ -179,9 +149,5 @@ fun player( @BrigadierDsl fun players( name: String, -): RequiredArgumentConstructor< - S, - ListPlayerArgumentDescriptor - > { - return argument(name, EntityArgumentType.players(), ListPlayerArgumentDescriptor) -} +): RequiredArgumentConstructor = + argument(name, EntityArgumentType.players(), ListPlayerArgumentDescriptor) diff --git a/src/main/kotlin/com/lambda/brigadier/argument/PrimitiveArguments.kt b/src/main/kotlin/com/lambda/brigadier/argument/PrimitiveArguments.kt index 6544a31f3..258676e5c 100644 --- a/src/main/kotlin/com/lambda/brigadier/argument/PrimitiveArguments.kt +++ b/src/main/kotlin/com/lambda/brigadier/argument/PrimitiveArguments.kt @@ -42,9 +42,8 @@ import com.mojang.brigadier.arguments.LongArgumentType */ @JvmName("valueBoolArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Boolean { - return BoolArgumentType.getBool(context, name) -} +fun DefaultArgumentReader.value(): Boolean = + BoolArgumentType.getBool(context, name) /** * Reads the boolean value from the argument in @@ -54,9 +53,8 @@ fun DefaultArgumentReader.value(): Boolean { */ @JvmName("valueDoubleArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Double { - return DoubleArgumentType.getDouble(context, name) -} +fun DefaultArgumentReader.value(): Double = + DoubleArgumentType.getDouble(context, name) /** * Reads the float value from the argument in @@ -66,9 +64,8 @@ fun DefaultArgumentReader.value(): Double { */ @JvmName("valueFloatArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Float { - return FloatArgumentType.getFloat(context, name) -} +fun DefaultArgumentReader.value(): Float = + FloatArgumentType.getFloat(context, name) /** * Reads the integer value from the argument in @@ -78,9 +75,8 @@ fun DefaultArgumentReader.value(): Float { */ @JvmName("valueIntArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Int { - return IntegerArgumentType.getInteger(context, name) -} +fun DefaultArgumentReader.value(): Int = + IntegerArgumentType.getInteger(context, name) /** * Reads the long value from the argument in @@ -90,9 +86,8 @@ fun DefaultArgumentReader.value(): Int { */ @JvmName("valueLongArg") @BrigadierDsl -fun DefaultArgumentReader.value(): Long { - return LongArgumentType.getLong(context, name) -} +fun DefaultArgumentReader.value(): Long = + LongArgumentType.getLong(context, name) /** * Creates a boolean argument with [name] as the parameter name. @@ -100,9 +95,8 @@ fun DefaultArgumentReader.value(): Long { @BrigadierDsl fun boolean( name: String, -): DefaultArgumentConstructor { - return argument(name, BoolArgumentType.bool()) -} +): DefaultArgumentConstructor = + argument(name, BoolArgumentType.bool()) /** * Creates a double argument with [name] as the parameter name. @@ -115,9 +109,8 @@ fun double( name: String, min: Double = -Double.MAX_VALUE, max: Double = Double.MAX_VALUE, -): DefaultArgumentConstructor { - return argument(name, DoubleArgumentType.doubleArg(min, max)) -} +): DefaultArgumentConstructor = + argument(name, DoubleArgumentType.doubleArg(min, max)) /** * Creates a float argument with [name] as the parameter name. @@ -130,9 +123,8 @@ fun float( name: String, min: Float = -Float.MAX_VALUE, max: Float = Float.MAX_VALUE, -): DefaultArgumentConstructor { - return argument(name, FloatArgumentType.floatArg(min, max)) -} +): DefaultArgumentConstructor = + argument(name, FloatArgumentType.floatArg(min, max)) /** * Creates an integer argument with [name] as the parameter name. @@ -145,9 +137,8 @@ fun integer( name: String, min: Int = -Int.MAX_VALUE, max: Int = Int.MAX_VALUE, -): DefaultArgumentConstructor { - return argument(name, IntegerArgumentType.integer(min, max)) -} +): DefaultArgumentConstructor = + argument(name, IntegerArgumentType.integer(min, max)) /** * Creates a long argument with [name] as the parameter name. @@ -160,6 +151,5 @@ fun long( name: String, min: Long = -Long.MAX_VALUE, max: Long = Long.MAX_VALUE, -): DefaultArgumentConstructor { - return argument(name, LongArgumentType.longArg(min, max)) -} +): DefaultArgumentConstructor = + argument(name, LongArgumentType.longArg(min, max)) diff --git a/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt b/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt index 51e93f749..71f458664 100644 --- a/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt @@ -31,7 +31,7 @@ import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStruc import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.task.RootTask.run import com.lambda.task.tasks.BuildTask -import com.lambda.task.tasks.BuildTask.Companion.build +import com.lambda.task.tasks.build import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.info import com.lambda.util.extension.CommandBuilder diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 964f4732c..399677cdb 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -29,26 +29,15 @@ import net.minecraft.item.Item interface InventoryConfig { val tickStageMask: Collection val disposables: Collection - val swapWithDisposables: Boolean - val providerPriority: Priority + val accessPriority: Priority val storePriority: Priority - val accessShulkerBoxes: Boolean - val accessChests: Boolean - val accessEnderChest: Boolean - val accessStashes: Boolean + val allowedContainers: Collection + + val enderChestSearchRadius: Int val containerSelection: ContainerSelection - get() = selectContainer { - val allowedContainers = buildSet { - addAll(Container.Rank.entries) - if (!accessShulkerBoxes) remove(Container.Rank.ShulkerBox) - if (!accessEnderChest) remove(Container.Rank.EnderChest) - if (!accessChests) remove(Container.Rank.Chest) - if (!accessStashes) remove(Container.Rank.Stash) - } - ofAnyType(*allowedContainers.toTypedArray()) - } + get() = selectContainer { ofAnyType(*allowedContainers.toTypedArray()) } enum class Priority( override val displayName: String, diff --git a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt index ee64c7e13..34b5e2751 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt @@ -21,22 +21,19 @@ import com.lambda.config.Config import com.lambda.config.ConfigBlock import com.lambda.config.Group import com.lambda.event.events.TickEvent.Companion.ALL_STAGES +import com.lambda.interaction.inventory.container.Container import com.lambda.util.item.ItemUtils class InventorySettings(override val c: Config) : InventoryConfig, ConfigBlock { companion object { - private const val CONTAINER_GROUP = "Container" - private const val ACCESS_GROUP = "Access" + const val ENDER_CHEST_GROUP = "Ender Chest" } override val tickStageMask by c.setting("Inventory Stage Mask", ALL_STAGES.toSet(), description = "The sub-tick timing at which inventory actions are performed", displayClassName = true) - @Group(CONTAINER_GROUP) override val disposables by c.setting("Disposables", ItemUtils.defaultDisposables, description = "Items that will be ignored when checking for a free slot") - @Group(CONTAINER_GROUP) override val swapWithDisposables by c.setting("Swap With Disposables", true, "Swap items with disposable ones") - @Group(CONTAINER_GROUP) override val providerPriority by c.setting("Provider Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when retrieving the item from") - @Group(CONTAINER_GROUP) override val storePriority by c.setting("Store Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when storing the item to") + override val disposables by c.setting("Disposables", ItemUtils.defaultDisposables, description = "Items that will be ignored when checking for a free slot") + override val accessPriority by c.setting("Access Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when retrieving the item from") + override val storePriority by c.setting("Store Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when storing the item to") + override val allowedContainers by c.setting("Allowed Containers", Container.Rank.entries, description = "What containers are accessible") - @Group(ACCESS_GROUP) override val accessShulkerBoxes by c.setting("Access Shulker Boxes", false, "Allow access to the player's shulker boxes") - @Group(ACCESS_GROUP) override val accessChests by c.setting("Access Chests", false, "Allow access to the player's normal chests") - @Group(ACCESS_GROUP) override val accessEnderChest by c.setting("Access Ender Chest", false, "Allow access to the player's ender chest") - @Group(ACCESS_GROUP) override val accessStashes by c.setting("Access Stashes", false, "Allow access to the player's stashes") + @Group(ENDER_CHEST_GROUP) override val enderChestSearchRadius by c.setting("Initial Search Radius", 10, 0..20, unit = " blocks", description = "Initial search radius to scan for an already placed ender chest. If one isn't found, one will be placed. If an ender chest isn't found in the inventory, it scans the rest of the loaded area to find an already placed one") } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/config/settings/complex/KeybindSetting.kt b/src/main/kotlin/com/lambda/config/settings/complex/KeybindSetting.kt index ed2c94041..00629b99f 100644 --- a/src/main/kotlin/com/lambda/config/settings/complex/KeybindSetting.kt +++ b/src/main/kotlin/com/lambda/config/settings/complex/KeybindSetting.kt @@ -36,7 +36,6 @@ import com.lambda.event.Muteable import com.lambda.event.events.ButtonEvent import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.gui.dsl.ImGuiBuilder -import com.lambda.imgui.ImGui.isMouseClicked import com.lambda.imgui.flag.ImGuiCol import com.lambda.imgui.flag.ImGuiHoveredFlags import com.lambda.imgui.flag.ImGuiMouseButton diff --git a/src/main/kotlin/com/lambda/gui/MenuBar.kt b/src/main/kotlin/com/lambda/gui/MenuBar.kt index 30c164420..2c5550ff2 100644 --- a/src/main/kotlin/com/lambda/gui/MenuBar.kt +++ b/src/main/kotlin/com/lambda/gui/MenuBar.kt @@ -36,7 +36,6 @@ import com.lambda.gui.components.QuickSearch import com.lambda.gui.components.SettingsWidget.buildConfigSettingsContext import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.imgui.ImGui -import com.lambda.imgui.ImGui.closeCurrentPopup import com.lambda.imgui.flag.ImGuiCol import com.lambda.imgui.flag.ImGuiStyleVar import com.lambda.imgui.flag.ImGuiWindowFlags diff --git a/src/main/kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt b/src/main/kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt index 449b8bc40..5ba9f8b16 100644 --- a/src/main/kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt +++ b/src/main/kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt @@ -20,6 +20,8 @@ package com.lambda.gui.dsl import com.lambda.gui.components.ClickGuiLayout +import com.lambda.gui.dsl.ImGuiBuilder.onItemClick +import com.lambda.gui.dsl.ImGuiBuilder.onItemHover import com.lambda.gui.dsl.ImGuiBuilder.openPopup import com.lambda.gui.dsl.ImGuiBuilder.text import com.lambda.imgui.ImDrawList @@ -108,10 +110,8 @@ import com.lambda.imgui.ImGui.isItemEdited import com.lambda.imgui.ImGui.isItemFocused import com.lambda.imgui.ImGui.isItemHovered import com.lambda.imgui.ImGui.isItemToggledOpen -import com.lambda.imgui.ImGui.isMouseClicked import com.lambda.imgui.ImGui.isWindowAppearing import com.lambda.imgui.ImGui.isWindowCollapsed -import com.lambda.imgui.ImGui.isWindowHovered import com.lambda.imgui.ImGui.plotHistogram import com.lambda.imgui.ImGui.plotLines import com.lambda.imgui.ImGui.popFont diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 6de41dc5a..3be7609de 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -35,8 +35,7 @@ import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task -import com.lambda.task.tasks.ContainerTransferTask.Companion.transfer -import com.lambda.task.wrappers.softFail +import com.lambda.task.tasks.wrappers.softFail import net.minecraft.block.BlockState import net.minecraft.item.Item import net.minecraft.util.math.BlockPos diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index 1ef911d16..fe897f082 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -30,8 +30,7 @@ import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task -import com.lambda.task.wrappers.softFail -import com.lambda.task.tasks.ContainerTransferTask.Companion.transfer +import com.lambda.task.tasks.wrappers.softFail import net.minecraft.client.data.TextureMap.side import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index a14699fc4..770ea2850 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -126,7 +126,7 @@ object ContainerHandler : Loadable { filteredContainers .filter { containerSelection.matches(it) } .filter { it.stackCount(this) >= count } - .sortedWith(automated.inventoryConfig.providerPriority.materialComparator(this)) + .sortedWith(automated.inventoryConfig.accessPriority.materialComparator(this)) @ContainerMarker context(automated: Automated) @@ -142,7 +142,7 @@ object ContainerHandler : Loadable { filteredContainers .filter { containerSelection.matches(it) } .filter { it.spaceAvailable(this) >= count } - .sortedWith(automated.inventoryConfig.providerPriority.spaceComparator(this)) + .sortedWith(automated.inventoryConfig.accessPriority.spaceComparator(this)) @ContainerMarker context(automated: Automated) diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index e83152448..2be088cc1 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -17,6 +17,7 @@ package com.lambda.interaction.inventory +import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils @@ -34,6 +35,12 @@ import net.minecraft.registry.tag.TagKey import net.minecraft.screen.slot.Slot import java.util.* +@ContainerMarker +fun Item.select(count: Int = 0) = selectStack(count) { isItem(this@select) } + +@ContainerMarker +fun ItemStack.select(count: Int = 0) = selectStack(count) { isItemStack(this@select) } + @Suppress("unused") class StackSelection( val count: Int = 0, @@ -240,12 +247,6 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { companion object { private val efficientToolCache = Collections.synchronizedMap(mutableMapOf()) - @ContainerMarker - fun Item.select(count: Int = 0) = selectStack(count) { isItem(this@select) } - - @ContainerMarker - fun ItemStack.select(count: Int = 0) = selectStack(count) { isItemStack(this@select) } - fun selectStack( count: Int = 0, builder: StackSelectionBuilder.() -> Unit diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 31ea7d518..c09a5b6db 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -28,7 +28,6 @@ import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.ContainerTransferTask -import com.lambda.task.wrappers.TaskOrNullSupplier import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.empty @@ -127,17 +126,9 @@ abstract class Container( } @Ta5kBuilder - context(automatedSafeContext: AutomatedSafeContext) - open fun accessThen( - closeAfter: Boolean = true, - afterOpen: TaskOrNullSupplier = { null }, - afterClose: TaskOrNullSupplier = { null } - ) = with(automatedSafeContext) { - taskOrSkipOrNull({ afterOpen(Unit) }) { result -> - if (closeAfter) afterClose(result) - else null - } - } + context(automated: Automated) + open fun access(): OpenContainerTask<*> = + PlayerOpenContainerTask(description, ::isAccessed) context(automatedSafeContext: AutomatedSafeContext) fun transfer(selection: StackSelection, toContainer: Container): Boolean = diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt index 0e395e9bc..bad12fdb3 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt @@ -17,5 +17,4 @@ package com.lambda.interaction.inventory.container -interface ExternalContainer { -} \ No newline at end of file +interface ExternalContainer \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt index 94f48fffa..67f861999 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt @@ -20,5 +20,5 @@ package com.lambda.interaction.inventory.container import net.minecraft.screen.slot.Slot interface NestedContainer { - val slotCache: Slot + val slotCache: Slot? } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt similarity index 60% rename from src/main/kotlin/com/lambda/task/tasks/NoopTask.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt index 011031a41..2954b10a3 100644 --- a/src/main/kotlin/com/lambda/task/tasks/NoopTask.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt @@ -15,20 +15,23 @@ * along with this program. If not, see . */ -package com.lambda.task.tasks +package com.lambda.interaction.inventory.container import com.lambda.context.SafeContext import com.lambda.task.Task +import net.minecraft.text.Text -class NoopTask @Ta5kBuilder constructor() : Task() { - override val name = "No-operation task" +abstract class OpenContainerTask @Ta5kBuilder internal constructor( + description: Text +) : Task() { + override val name = "accessing container: ${description.string}" +} +class PlayerOpenContainerTask @Ta5kBuilder internal constructor( + description: Text, + private val isAccessed: () -> Boolean +) : OpenContainerTask(description) { override fun SafeContext.onStart() { - success() - } - - companion object { - @Ta5kBuilder - fun noopTask() = NoopTask() + success(BasicOpenedContainerContext(isAccessed)) } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt new file mode 100644 index 000000000..5b615bb86 --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container + +import com.lambda.context.Automated +import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.simpleAction + +interface OpenedContainerContext { + @Ta5kBuilder + context(automated: Automated) + fun close(): Task<*> +} + +open class BasicOpenedContainerContext( + private val isAccessed: () -> Boolean +) : OpenedContainerContext { + context(_: Automated) + final override fun close() = + simpleAction("Closing container") { + if (!isAccessed()) return@simpleAction + player.closeScreen() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt index 23625a41d..1b454ba7d 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt @@ -18,15 +18,17 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc -import com.lambda.context.AutomatedSafeContext +import com.lambda.context.Automated +import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity +import com.lambda.interaction.inventory.container.BasicOpenedContainerContext import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.container.OpenContainerTask import com.lambda.interaction.inventory.container.PlacedContainer -import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer -import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction -import com.lambda.task.wrappers.TaskOrNullSupplier -import com.lambda.task.wrappers.thenOrNull +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.openContainer +import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -34,6 +36,7 @@ import com.lambda.util.text.literal import net.minecraft.block.ChestBlock import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.item.ItemStack +import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos @@ -69,23 +72,26 @@ data class ChestContainer( mc.player?.currentScreenHandler?.type == ScreenHandlerType.GENERIC_9X3 } ?: false - context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( - closeAfter: Boolean, - afterOpen: TaskOrNullSupplier, - afterClose: TaskOrNullSupplier - ) = - with(automatedSafeContext) { - taskOrSkipOrNull( - optional = { - openContainer(blockPos).thenOrNull { - afterOpen(Unit) - } + @Ta5kBuilder + context(automated: Automated) + override fun access() = AccessChestTask(automated) + + inner class AccessChestTask @Ta5kBuilder internal constructor( + automated: Automated + ) : OpenContainerTask(description), Automated by automated { + override fun SafeContext.onStart() { + taskOrNull { + if (isAccessed) null + else openContainer(blockPos).onSuccess { sh -> + success(OpenedChestContext(sh)) } - ) { - if (closeAfter) { - simpleAction("Close inventory") { player.closeHandledScreen() } - } else null - } + }.execute(this@AccessChestTask) } + } + + inner class OpenedChestContext( + val screenHandler: ScreenHandler, + ) : BasicOpenedContainerContext(::isAccessed) { + val blockPos = this@ChestContainer.blockPos + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt index 0e1c1f4cd..d6e71869b 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt @@ -18,25 +18,33 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc -import com.lambda.context.AutomatedSafeContext +import com.lambda.context.Automated +import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.task.tasks.AcquireStackTask.Companion.acquireStack -import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect -import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer -import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer -import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction -import com.lambda.task.wrappers.TaskOrNullSupplier -import com.lambda.task.wrappers.then -import com.lambda.task.wrappers.thenOrNull +import com.lambda.interaction.inventory.container.OpenContainerTask +import com.lambda.interaction.inventory.container.OpenedContainerContext +import com.lambda.interaction.inventory.select +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.acquireStack +import com.lambda.task.tasks.breakAndCollect +import com.lambda.task.tasks.findBlock +import com.lambda.task.tasks.openContainer +import com.lambda.task.tasks.placeContainer +import com.lambda.task.tasks.wrappers.actionTask +import com.lambda.task.tasks.wrappers.successTask +import com.lambda.task.tasks.wrappers.taskOrNull +import com.lambda.task.tasks.wrappers.then +import com.lambda.task.tasks.wrappers.withBranch import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.literal +import net.minecraft.block.Blocks import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.item.ItemStack import net.minecraft.item.Items +import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.util.math.BlockPos @@ -56,42 +64,49 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { mc.player?.currentScreenHandler?.type == ScreenHandlerType.GENERIC_9X3 } ?: false - context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( - closeAfter: Boolean, - afterOpen: TaskOrNullSupplier, - afterClose: TaskOrNullSupplier - ) = - with(automatedSafeContext) { - taskOrSkipOrNull( - optional = { - if (isAccessed) null - else { - wrappedTask("Setup Ender Chest") { success -> - acquireStack(Items.ENDER_CHEST.select(1)).then { slot -> - placeContainer(slot).then { pos -> - openContainer(pos).finally { - success(pos) - } + @Ta5kBuilder + context(automated: Automated) + override fun access() = OpenEnderChestContainerTask(automated) + + class OpenEnderChestContainerTask @Ta5kBuilder internal constructor( + automated: Automated + ) : OpenContainerTask(description), Automated by automated { + override fun SafeContext.onStart() { + taskOrNull { + if (isAccessed) null + else findBlock(Blocks.ENDER_CHEST, inventoryConfig.enderChestSearchRadius).withBranch( + onSuccess = { pos -> + openContainer(pos).onSuccess { sh -> + success(OpenedEnderChestContext(sh, pos, false)) + } + }, + onFailure = { + acquireStack(Items.ENDER_CHEST.select(1)) + .then { placeContainer(it) } + .then { pos -> + openContainer(pos).onSuccess { sh -> + success(OpenedEnderChestContext(sh, pos, true)) } } - } } - } - ) { pos -> - taskOrSkipOrNull({ afterOpen(Unit) }) { afterOpenResult -> - if (closeAfter) { - simpleAction("Close inventory") { player.closeHandledScreen() }.thenOrNull { - taskOrSkipOrNull( - optional = { - if (pos != null) breakAndCollect(pos) - else null - } - ) { afterClose(afterOpenResult) } - } - } else null - } - } + ) + }.execute(this@OpenEnderChestContainerTask) } + } + class OpenedEnderChestContext( + val screenHandler: ScreenHandler, + val blockPos: BlockPos, + val placed: Boolean + ) : OpenedContainerContext { + context(_: Automated) + override fun close() = + taskOrNull { + if (isAccessed) actionTask { player.closeScreen() } + else null + }.then { + if (placed) breakAndCollect(blockPos) + else successTask() + } + } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt index 1bd6bff54..cb9d53de0 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt @@ -18,14 +18,16 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc -import com.lambda.context.AutomatedSafeContext +import com.lambda.context.Automated +import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity +import com.lambda.interaction.inventory.container.BasicOpenedContainerContext import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.OpenContainerTask import com.lambda.interaction.inventory.container.PlacedContainer -import com.lambda.task.tasks.OpenContainerTask -import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction -import com.lambda.task.wrappers.TaskOrNullSupplier -import com.lambda.task.wrappers.thenOrNull +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.openContainer +import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -65,26 +67,20 @@ class PlacedShulkerBoxContainer( mc.player?.currentScreenHandler?.type == ScreenHandlerType.SHULKER_BOX } ?: false - context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( - closeAfter: Boolean, - afterOpen: TaskOrNullSupplier, - afterClose: TaskOrNullSupplier - ) = - with(automatedSafeContext) { - taskOrSkipOrNull( - optional = { - if (!isAccessed) OpenContainerTask(blockPos, automated = automatedSafeContext) - else null - } - ) { - taskOrSkipOrNull({ afterOpen(Unit) }) { result -> - if (closeAfter) { - simpleAction("Close Inventory") { - automatedSafeContext.player.closeHandledScreen() - }.thenOrNull { afterClose(result) } - } else null - } - } + @Ta5kBuilder + context(automated: Automated) + override fun access() = OpenPlacedShulkerBoxTask(automated) + + inner class OpenPlacedShulkerBoxTask @Ta5kBuilder internal constructor( + automated: Automated + ) : OpenContainerTask(description), Automated by automated { + override fun SafeContext.onStart() { + taskOrNull { + if (isAccessed) null + else openContainer(blockPos) + }.onSuccess { + success(BasicOpenedContainerContext(::isAccessed)) + }.execute(this@OpenPlacedShulkerBoxTask) } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index 18c45fea5..71c79b4f8 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -18,26 +18,32 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc -import com.lambda.context.AutomatedSafeContext +import com.lambda.context.Automated +import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.NestedContainer +import com.lambda.interaction.inventory.container.OpenContainerTask +import com.lambda.interaction.inventory.container.OpenedContainerContext import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect -import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer -import com.lambda.task.tasks.PlaceContainerTask.Companion.placeContainer -import com.lambda.task.tasks.SimpleActionTask.Companion.simpleAction -import com.lambda.task.wrappers.TaskOrNullSupplier -import com.lambda.task.wrappers.then -import com.lambda.task.wrappers.thenOrNull +import com.lambda.interaction.inventory.container.containers.PlayerContainer +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.breakAndCollect +import com.lambda.task.tasks.openContainer +import com.lambda.task.tasks.placeContainer +import com.lambda.task.tasks.transfer +import com.lambda.task.tasks.wrappers.actionTask +import com.lambda.task.tasks.wrappers.taskOrNull +import com.lambda.task.tasks.wrappers.then import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted import com.lambda.util.text.literal import net.minecraft.block.entity.ShulkerBoxBlockEntity import net.minecraft.item.ItemStack +import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos @@ -70,46 +76,45 @@ data class ShulkerBoxContainer( mc.player?.currentScreenHandler?.type == ScreenHandlerType.SHULKER_BOX } ?: false - context(automatedSafeContext: AutomatedSafeContext) - override fun accessThen( - closeAfter: Boolean, - afterOpen: TaskOrNullSupplier, - afterClose: TaskOrNullSupplier - ) = - with(automatedSafeContext) { - taskOrSkipOrNull( - optional = { - if (isAccessed) null - else nullableWrappedTask("Setup Shulker Box") { success -> - containedIn.accessThen( - afterOpen = { - if (player.currentScreenHandler.syncId == 0) null - else { - val selection = selectStack { isSlot(slotCache) } - containedIn.transferByTask(selection, HotbarContainer) - } - } - ) { slot -> - slot?.let { s -> - placeContainer(s).then { pos -> - openContainer(pos).finally { - success(pos) - } - } - } + @Ta5kBuilder + context(automated: Automated) + override fun access() = OpenShulkerBoxTask(automated) + + inner class OpenShulkerBoxTask @Ta5kBuilder internal constructor( + automated: Automated + ) : OpenContainerTask(description), Automated by automated { + override fun SafeContext.onStart() { + transfer( + selectStack { isSlot(slotCache) }, + containedIn, + HotbarContainer + ).then { slot -> placeContainer(slot) } + .then { pos -> + openContainer(pos).onSuccess { sh -> + success(OpenedShulkerBoxContext(pos, sh, containedIn)) } } - } - ) { pos -> - taskOrSkipOrNull({ afterOpen(Unit) }) { result -> - if (closeAfter && pos != null) { - simpleAction("Close inventory") { player.closeHandledScreen() }.then { - breakAndCollect(pos).thenOrNull { - afterClose(result) - } - } - } else null - } - } + .execute(this@OpenShulkerBoxTask) } + } + + inner class OpenedShulkerBoxContext( + val blockPos: BlockPos, + val screenHandler: ScreenHandler, + val fromContainer: Container + ) : OpenedContainerContext { + context(automated: Automated) + override fun close() = + taskOrNull { + if (!isAccessed) null + else actionTask { player.closeScreen() } + }.then { breakAndCollect(blockPos) } + .then { slot -> + transfer( + selectStack { isSlot(slot) }, + PlayerContainer, + fromContainer + ) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt index 946250be3..f52910054 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakRequest.kt @@ -35,6 +35,40 @@ import com.lambda.util.BlockUtils.isEmpty import net.minecraft.entity.ItemEntity import net.minecraft.util.math.BlockPos +@JvmName("breakRequest1") +fun AutomatedSafeContext.breakRequest( + positions: Collection, + pendingInteractions: MutableCollection, + nowOrNothing: Boolean = false, + builder: (BreakRequestBuilder.() -> Unit)? = null +) = positions + .associateWith { TargetState.Empty } + .sim() + .breakRequest(pendingInteractions, nowOrNothing, builder) + +@JvmName("breakRequest2") +context(automated: Automated) +fun Collection.breakRequest( + pendingInteractions: MutableCollection, + nowOrNothing: Boolean = false, + builder: (BreakRequestBuilder.() -> Unit)? = null +) = asSequence() + .breakRequest(pendingInteractions, nowOrNothing, builder) + +@JvmName("breakRequest3") +context(automated: Automated) +fun Sequence.breakRequest( + pendingInteractions: MutableCollection, + nowOrNothing: Boolean = false, + builder: (BreakRequestBuilder.() -> Unit)? = null +) = map { if (it is Dependent) it.lastDependency else it } + .filterIsInstance() + .sorted() + .map { it.context } + .toSet() + .takeIf { it.isNotEmpty() } + ?.let { automated.breakRequest(it, pendingInteractions, nowOrNothing, builder) } + /** * Contains the information necessary for initializing and continuing breaks within the [BreakManager]. * @@ -139,40 +173,6 @@ class BreakRequestBuilder private constructor( ) companion object { - @JvmName("breakRequest1") - fun AutomatedSafeContext.breakRequest( - positions: Collection, - pendingInteractions: MutableCollection, - nowOrNothing: Boolean = false, - builder: (BreakRequestBuilder.() -> Unit)? = null - ) = positions - .associateWith { TargetState.Empty } - .sim() - .breakRequest(pendingInteractions, nowOrNothing, builder) - - @JvmName("breakRequest2") - context(automated: Automated) - fun Collection.breakRequest( - pendingInteractions: MutableCollection, - nowOrNothing: Boolean = false, - builder: (BreakRequestBuilder.() -> Unit)? = null - ) = asSequence() - .breakRequest(pendingInteractions, nowOrNothing, builder) - - @JvmName("breakRequest3") - context(automated: Automated) - fun Sequence.breakRequest( - pendingInteractions: MutableCollection, - nowOrNothing: Boolean = false, - builder: (BreakRequestBuilder.() -> Unit)? = null - ) = map { if (it is Dependent) it.lastDependency else it } - .filterIsInstance() - .sorted() - .map { it.context } - .toSet() - .takeIf { it.isNotEmpty() } - ?.let { automated.breakRequest(it, pendingInteractions, nowOrNothing, builder) } - @JvmName("breakRequest4") fun Automated.breakRequest( contexts: Collection, diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt index bc025b4d6..a0d9d7849 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractRequest.kt @@ -25,11 +25,35 @@ import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.Dependent import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.manager.Request +import com.lambda.interaction.manager.managers.interacting.PlaceRequestBuilder.Companion.interactRequest import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.matches import net.minecraft.util.math.BlockPos +@JvmName("interactRequest1") +context(automated: Automated) +fun Collection.interactRequest( + pendingInteractions: MutableCollection, + nowOrNothing: Boolean = false, + builder: (PlaceRequestBuilder.() -> Unit)? = null +) = asSequence() + .interactRequest(pendingInteractions, nowOrNothing, builder) + +@JvmName("interactRequest2") +context(automated: Automated) +fun Sequence.interactRequest( + pendingInteractions: MutableCollection, + nowOrNothing: Boolean = false, + builder: (PlaceRequestBuilder.() -> Unit)? = null +) = map { if (it is Dependent) it.lastDependency else it } + .filterIsInstance() + .sorted() + .map { it.context } + .toSet() + .takeIf { it.isNotEmpty() } + ?.let { automated.interactRequest(it, pendingInteractions, nowOrNothing, builder) } + data class InteractRequest( val contexts: Collection, val pendingInteractions: MutableCollection, @@ -81,29 +105,6 @@ class PlaceRequestBuilder private constructor( ) companion object { - @JvmName("interactRequest1") - context(automated: Automated) - fun Collection.interactRequest( - pendingInteractions: MutableCollection, - nowOrNothing: Boolean = false, - builder: (PlaceRequestBuilder.() -> Unit)? = null - ) = asSequence() - .interactRequest(pendingInteractions, nowOrNothing, builder) - - @JvmName("interactRequest2") - context(automated: Automated) - fun Sequence.interactRequest( - pendingInteractions: MutableCollection, - nowOrNothing: Boolean = false, - builder: (PlaceRequestBuilder.() -> Unit)? = null - ) = map { if (it is Dependent) it.lastDependency else it } - .filterIsInstance() - .sorted() - .map { it.context } - .toSet() - .takeIf { it.isNotEmpty() } - ?.let { automated.interactRequest(it, pendingInteractions, nowOrNothing, builder) } - @JvmName("interactRequest3") fun Automated.interactRequest( contexts: Collection, diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index d927b241a..1bd195dc3 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -30,7 +30,7 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build +import com.lambda.task.tasks.build import com.lambda.util.BlockUtils.blockState import com.lambda.util.extension.shrinkByEpsilon import com.lambda.util.item.ItemUtils.block diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt index 5eaba40b2..394a9b8f6 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt @@ -29,7 +29,7 @@ import com.lambda.module.modules.combat.PlayerTrap.getTrapPositions import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build +import com.lambda.task.tasks.build import com.lambda.util.item.ItemUtils.block import net.minecraft.block.Blocks import net.minecraft.item.BlockItem diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index fc2597653..ddc1d9205 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -23,7 +23,7 @@ import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run -import com.lambda.task.tasks.AcquireStackTask.Companion.acquireStack +import com.lambda.task.tasks.acquireStack import net.minecraft.item.Items @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt index 175c60513..71b8159dd 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt @@ -17,9 +17,9 @@ package com.lambda.module.modules.movement -import com.lambda.config.ConfigEditor.forEachSetting -import com.lambda.config.ConfigEditor.hideAllExcept import com.lambda.config.blocks.WorldLineSettings +import com.lambda.config.forEachSetting +import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.MovementEvent diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt index 9026773f5..a55f96e3e 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt @@ -17,12 +17,12 @@ package com.lambda.module.modules.movement.elytrafly -import com.lambda.config.ConfigEditor.editSetting -import com.lambda.config.ConfigEditor.forEachSetting -import com.lambda.config.ConfigEditor.hideAllExcept import com.lambda.config.Tab import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.editSetting import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.forEachSetting +import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.event.events.ClientEvent import com.lambda.event.events.MovementEvent diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt index 5adcbb206..b84478fbe 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt @@ -37,10 +37,6 @@ import com.lambda.module.modules.render.Freecam import com.lambda.util.NamedEnum import com.lambda.util.TickTimer import com.lambda.util.math.MathUtils.toFloat -import com.lambda.util.player.PlayerUtils.hasFirework -import net.minecraft.component.DataComponentTypes -import com.lambda.util.player.SlotUtils.hotbarStacks -import com.lambda.util.player.SlotUtils.inventoryStacks import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt index e8ea02ee0..e1e3af19c 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt @@ -27,8 +27,8 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.EatTask.Companion.eat -import com.lambda.task.wrappers.thenAction +import com.lambda.task.tasks.eat +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 996ae234c..b0270222a 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -27,7 +27,7 @@ import com.lambda.event.events.PlayerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.context.BuildContext -import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest +import com.lambda.interaction.manager.managers.breaking.breakRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index c6232d72e..a3339ba7a 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -27,11 +27,11 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.breakAndCollect -import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer import com.lambda.task.tasks.PlaceContainerTask -import com.lambda.task.wrappers.then -import com.lambda.task.wrappers.thenAction +import com.lambda.task.tasks.breakAndCollect +import com.lambda.task.tasks.openContainer +import com.lambda.task.tasks.wrappers.then +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.util.item.ItemUtils.shulkerBoxes import net.minecraft.item.Items import net.minecraft.screen.ScreenHandler diff --git a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt index b1105ff51..5f254bce7 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt @@ -17,10 +17,10 @@ package com.lambda.module.modules.player -import com.lambda.config.ConfigEditor.editSetting -import com.lambda.config.ConfigEditor.hideAllExcept import com.lambda.config.Group import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.editSetting +import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index 80f0e5401..dabfd131b 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -47,7 +47,7 @@ object StackReplenish : Module( .withEdits { hideAllExcept(::inventoryConfig) inventoryConfig.apply { - hide(::disposables, ::swapWithDisposables, ::providerPriority, ::storePriority) + hide(::disposables, ::accessPriority, ::storePriority) } } diff --git a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt index 850110aab..b29ce5000 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt @@ -33,7 +33,7 @@ import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.manager.managers.interacting.InteractRequest -import com.lambda.interaction.manager.managers.interacting.PlaceRequestBuilder.Companion.interactRequest +import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 97bd0b005..8bde75a8b 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -49,8 +49,8 @@ import com.lambda.module.modules.world.AutoPortal.PosHandler.prevAnchorPos import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build -import com.lambda.task.wrappers.thenOrNull +import com.lambda.task.tasks.build +import com.lambda.task.tasks.wrappers.thenOrNull import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.isEmpty diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt index 651b27adb..75e1ba526 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt @@ -36,8 +36,8 @@ import com.lambda.module.tag.ModuleTag import com.lambda.sound.SoundHandler.playSound import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build -import com.lambda.task.wrappers.thenAction +import com.lambda.task.tasks.build +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.isEmpty diff --git a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt index 62da6b69f..0972a2a43 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt @@ -28,7 +28,7 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build +import com.lambda.task.tasks.build import com.lambda.util.CommunicationUtils.info import com.lambda.util.Describable import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt index d58d517a3..026b3851d 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt @@ -28,7 +28,7 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build +import com.lambda.task.tasks.build import com.lambda.util.BlockUtils.blockPos import com.lambda.util.PlayerBuildLayerUtils.FlattenMode import com.lambda.util.PlayerBuildLayerUtils.isInBaritoneSelection diff --git a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt index 97e290420..f2e2332e8 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt @@ -36,7 +36,7 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build +import com.lambda.task.tasks.build import com.lambda.util.BlockUtils.blockPos import com.lambda.util.CommunicationUtils.logError import com.lambda.util.Describable diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index 5a584b65b..dd30460a3 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -32,7 +32,7 @@ import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.manager.managers.interacting.PlaceRequestBuilder.Companion.interactRequest +import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index 8e89c99d4..0bdd2d006 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -54,10 +54,9 @@ import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build -import com.lambda.task.tasks.OpenContainerTask -import com.lambda.task.wrappers.thenAction -import com.lambda.task.tasks.OpenContainerTask.Companion.openContainer +import com.lambda.task.tasks.build +import com.lambda.task.tasks.openContainer +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.BlockUtils.blockState diff --git a/src/main/kotlin/com/lambda/task/RootTask.kt b/src/main/kotlin/com/lambda/task/RootTask.kt index cd73c3aa1..fac5f6208 100644 --- a/src/main/kotlin/com/lambda/task/RootTask.kt +++ b/src/main/kotlin/com/lambda/task/RootTask.kt @@ -17,7 +17,6 @@ package com.lambda.task -import com.lambda.task.wrappers.TaskSupplier import com.lambda.threading.runSafe object RootTask : Task() { @@ -30,7 +29,7 @@ object RootTask : Task() { } @Ta5kBuilder - fun Task<*>.run(task: TaskSupplier) { + fun Task<*>.run(task: TaskGenerator) { runSafe { task(Unit).execute(this@run) } diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index 109b3c1c4..8aaba1110 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -24,7 +24,7 @@ import com.lambda.event.Muteable import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.modules.client.Client.verboseDebug -import com.lambda.task.wrappers.onFail +import com.lambda.task.tasks.wrappers.withRecovery import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.logError import com.lambda.util.Nameable @@ -240,7 +240,7 @@ abstract class Task : Nameable, Muteable { /** * Registers a callback for if the task fails. * - * This could be mistaken for [onFail] which is used to wrap the given task with another task that runs a recovery task if this one fails. + * This could be mistaken for [withRecovery] which is used to wrap the given task with another task that runs a recovery task if this one fails. */ @Ta5kBuilder fun onFailure(callback: SafeContext.(Throwable) -> Unit): Task { @@ -274,3 +274,9 @@ abstract class Task : Nameable, Muteable { } } } + +typealias TaskGenerator = SafeContext.(R) -> Task +typealias TaskOrNullGenerator = SafeContext.(R) -> Task? + +typealias TaskSupplier = SafeContext.() -> Task +typealias TaskOrNullSupplier = SafeContext.() -> Task? \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt index cf705440a..30a0dbf73 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -24,16 +24,23 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.ContainerHandler.findSlots import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.wrappers.softFail import com.lambda.threading.runSafeAutomated -import com.lambda.util.BlockUtils.blockPos -import com.lambda.util.BlockUtils.blockState +import com.lambda.util.BlockUtils.item import net.minecraft.block.Block -import net.minecraft.item.Items import net.minecraft.util.math.BlockPos -class AcquirePlacedBlockTask @Ta5kBuilder constructor( +@Ta5kBuilder +context(automated: Automated) +fun acquirePlacedBlock( + block: Block, + maxSearchRadius: Int = 10 +) = AcquirePlacedBlockTask(block, maxSearchRadius, automated) + +class AcquirePlacedBlockTask @Ta5kBuilder internal constructor( val block: Block, - val maxSearchRadius: Int = 10, + val searchRadius: Int = 10, automated: Automated ) : Task(), Automated by automated { override val name get() = "Acquiring placed ${block.name.string}" @@ -41,43 +48,25 @@ class AcquirePlacedBlockTask @Ta5kBuilder constructor( init { listen { runSafeAutomated { - Items.ENDER_CHEST + block.item .select(1) .findSlots() .firstOrNull()?.let { slot -> - PlaceContainerTask(slot, this).finally { - success(it) - }.execute(this@AcquirePlacedBlockTask) + PlaceContainerTask(slot, this) + .onSuccess { success(it) } + .execute(this@AcquirePlacedBlockTask) return@listen } } - failure("No ender chest found in range or hotbar/inventory!") + failure("No $block found in range or hotbar/inventory!") return@listen } } override fun SafeContext.onStart() { - checkInRange()?.let { success(it) } - } - - private fun SafeContext.checkInRange() = - BlockPos.iterateOutwards( - player.blockPos, - maxSearchRadius, - maxSearchRadius, - maxSearchRadius - ).map { it.blockPos } - .firstOrNull { blockPos -> - blockState(blockPos).block == block - } - - companion object { - @Ta5kBuilder - context(automated: Automated) - fun acquirePlacedBlock( - block: Block, - maxSearchRadius: Int = 10 - ) = AcquirePlacedBlockTask(block, maxSearchRadius, automated) + findBlock(block, searchRadius) + .softFail() + .execute(this@AcquirePlacedBlockTask) } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index 20d22e8af..167f4c542 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -24,11 +24,22 @@ import com.lambda.interaction.handler.handlers.ContainerHandler.findContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task -import com.lambda.task.wrappers.thenAction +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated import net.minecraft.screen.slot.Slot -class AcquireStackTask @Ta5kBuilder constructor( +@Ta5kBuilder +context(automated: Automated) +fun acquireStack(selection: StackSelection) = + AcquireStackTask(selection, automated) + +@Ta5kBuilder +context(automated: Automated) +fun acquireStack(selection: () -> StackSelection) = + AcquireStackTask(selection(), automated) + +class AcquireStackTask @Ta5kBuilder internal constructor( val selection: StackSelection, automated: Automated ) : Task(), Automated by automated { @@ -44,16 +55,4 @@ class AcquireStackTask @Ta5kBuilder constructor( ?: failure(ContainerHandler.NoContainerFound(selection)) // ToDo: Create crafting path } } - - companion object { - @Ta5kBuilder - context(automated: Automated) - fun acquireStack(selection: StackSelection) = - AcquireStackTask(selection, automated) - - @Ta5kBuilder - context(automated: Automated) - fun acquireStack(selection: () -> StackSelection) = - AcquireStackTask(selection(), automated) - } } diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index c4dbb71d7..5053c5649 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -48,13 +48,13 @@ import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest -import com.lambda.interaction.manager.managers.interacting.PlaceRequestBuilder.Companion.interactRequest +import com.lambda.interaction.manager.managers.breaking.breakRequest +import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.modules.client.Client import com.lambda.task.Task -import com.lambda.task.tasks.EatTask.Companion.eat -import com.lambda.task.wrappers.thenAction +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runConcurrent import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated @@ -79,7 +79,50 @@ import java.util.concurrent.ConcurrentLinkedQueue import kotlin.coroutines.cancellation.CancellationException import kotlin.math.sqrt -class BuildTask @Ta5kBuilder private constructor( +@Ta5kBuilder +fun Automated.build( + finishOnDone: Boolean = true, + collectDrops: Boolean = buildConfig.collectDrops, + lifeMaintenance: Boolean = false, + async: Boolean = false, + buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, + blueprint: () -> Blueprint +) = BuildTask(blueprint(), finishOnDone, collectDrops, lifeMaintenance, async, this, buildResultFilter) + +@Ta5kBuilder +context(automated: Automated) +fun Structure.build( + finishOnDone: Boolean = true, + collectDrops: Boolean = automated.buildConfig.collectDrops, + lifeMaintenance: Boolean = false, + async: Boolean = false, + buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, +) = BuildTask(toBlueprint(), finishOnDone, collectDrops, lifeMaintenance, async, automated, buildResultFilter) + +@Ta5kBuilder +context(automated: Automated) +fun Blueprint.build( + finishOnDone: Boolean = true, + collectDrops: Boolean = automated.buildConfig.collectDrops, + lifeMaintenance: Boolean = false, + async: Boolean = false, + buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, +) = BuildTask(this, finishOnDone, collectDrops, lifeMaintenance, async, automated, buildResultFilter) + +@Ta5kBuilder +context(automated: Automated) +fun breakAndCollect( + blockPos: BlockPos, + finishOnDone: Boolean = true, + lifeMaintenance: Boolean = false, + async: Boolean = false, + buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, +) = BuildTask( + blockPos.toStructure(TargetState.Empty).toBlueprint(), + finishOnDone, true, lifeMaintenance, async, automated, buildResultFilter +) + +class BuildTask @Ta5kBuilder internal constructor( private val blueprint: Blueprint, private val finishOnDone: Boolean, private val collectDrops: Boolean, @@ -340,54 +383,9 @@ class BuildTask @Ta5kBuilder private constructor( true } ?: false - fun iteratePropagating() = + private fun iteratePropagating() = if (blueprint is PropagatingBlueprint) { blueprint.next() ?: failure("Failed to propagate the next blueprint") true } else false - - companion object { - @Ta5kBuilder - fun Automated.build( - finishOnDone: Boolean = true, - collectDrops: Boolean = buildConfig.collectDrops, - lifeMaintenance: Boolean = false, - async: Boolean = false, - buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, - blueprint: () -> Blueprint - ) = BuildTask(blueprint(), finishOnDone, collectDrops, lifeMaintenance, async, this, buildResultFilter) - - @Ta5kBuilder - context(automated: Automated) - fun Structure.build( - finishOnDone: Boolean = true, - collectDrops: Boolean = automated.buildConfig.collectDrops, - lifeMaintenance: Boolean = false, - async: Boolean = false, - buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, - ) = BuildTask(toBlueprint(), finishOnDone, collectDrops, lifeMaintenance, async, automated, buildResultFilter) - - @Ta5kBuilder - context(automated: Automated) - fun Blueprint.build( - finishOnDone: Boolean = true, - collectDrops: Boolean = automated.buildConfig.collectDrops, - lifeMaintenance: Boolean = false, - async: Boolean = false, - buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, - ) = BuildTask(this, finishOnDone, collectDrops, lifeMaintenance, async, automated, buildResultFilter) - - @Ta5kBuilder - context(automated: Automated) - fun breakAndCollect( - blockPos: BlockPos, - finishOnDone: Boolean = true, - lifeMaintenance: Boolean = false, - async: Boolean = false, - buildResultFilter: SafeContext.(BuildResult) -> Boolean = { true }, - ) = BuildTask( - blockPos.toStructure(TargetState.Empty).toBlueprint(), - finishOnDone, true, lifeMaintenance, async, automated, buildResultFilter - ) - } } diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index fafcc2e6f..6207e8af2 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -26,11 +26,38 @@ import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.task.Task -import com.lambda.task.wrappers.thenAction +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated import net.minecraft.screen.slot.Slot -class ContainerTransferTask @Ta5kBuilder constructor( +@Ta5kBuilder +context(automated: Automated) +fun transfer( + stackSelection: StackSelection, + fromContainer: Container, + toContainer: Container, + failIfNoStack: Boolean = true +) = ContainerTransferTask(fromContainer, toContainer, stackSelection, failIfNoStack, automated) + +@Ta5kBuilder +context(automated: Automated) +@JvmName("transferByStackSelection") +fun transfer( + stackSelection: StackSelection, + toContainer: Container, + failIfNoStack: Boolean = true +) = transfer(stackSelection, stackSelection.findContainer() ?: HotbarAndInventoryContainer, toContainer, failIfNoStack) + +@Ta5kBuilder +context(automated: Automated) +@JvmName("transferExt") +fun StackSelection.transferTo( + toContainer: Container, + failIfNoStack: Boolean = true +) = transfer(this, findContainer() ?: HotbarAndInventoryContainer, toContainer, failIfNoStack) + +class ContainerTransferTask @Ta5kBuilder internal constructor( private var fromContainer: Container, private val toContainer: Container, private val stackSelection: StackSelection, @@ -43,24 +70,24 @@ class ContainerTransferTask @Ta5kBuilder constructor( listen { runSafeAutomated { if (fromContainer is ExternalContainer && toContainer is ExternalContainer) { - fromContainer.accessThen( + fromContainer.accessThen( afterOpen = { fromContainer.transferByTask(stackSelection, HotbarAndInventoryContainer, failIfNoStack) } ) { HotbarAndInventoryContainer.transferByTask(stackSelection, toContainer, failIfNoStack) - .finally { slot -> success(slot) } + .thenAction { slot -> success(slot) } }?.execute(this@ContainerTransferTask) return@listen } - fromContainer.accessThen { - toContainer.accessThen { - TransferTask().finally { slot -> + fromContainer.accessThen { + toContainer.accessThen { + TransferTask().thenAction { slot -> success(slot) } } - }.execute(this@ContainerTransferTask) + }?.execute(this@ContainerTransferTask) } } } @@ -93,34 +120,4 @@ class ContainerTransferTask @Ta5kBuilder constructor( private inner class NoMaterialAccessException(stackSelection: StackSelection) : IllegalStateException("Unable to access $stackSelection.") } - - companion object { - @Ta5kBuilder - context(automated: Automated) - fun transfer( - fromContainer: Container, - toContainer: Container, - stackSelection: StackSelection, - failIfNoStack: Boolean = false - ) = ContainerTransferTask(fromContainer, toContainer, stackSelection, failIfNoStack, automated) - - @Ta5kBuilder - context(automated: Automated) - fun transfer( - stackSelection: StackSelection, - toContainer: Container, - failIfNoStack: Boolean = false - ) = stackSelection.findContainer()?.let { - ContainerTransferTask(it, toContainer, stackSelection, failIfNoStack, automated) - } - - @Ta5kBuilder - context(automated: Automated) - fun StackSelection.transfer( - toContainer: Container, - failIfNoStack: Boolean = false - ) = findContainer()?.let { - ContainerTransferTask(it, toContainer, this, failIfNoStack, automated) - } - } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index 0677ba082..c68f4ae24 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -27,12 +27,17 @@ import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder import com.lambda.threading.runSafeAutomated import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult import net.minecraft.util.Hand -class EatTask @Ta5kBuilder constructor( +@Ta5kBuilder +context(automated: Automated) +fun eat() = EatTask(automated) + +class EatTask @Ta5kBuilder internal constructor( automated: Automated ) : Task(), Automated by automated { override val name: String @@ -94,10 +99,4 @@ class EatTask @Ta5kBuilder constructor( } } } - - companion object { - @Ta5kBuilder - context(automated: Automated) - fun eat() = EatTask(automated) - } } diff --git a/src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt new file mode 100644 index 000000000..7ec969db0 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks + +import com.lambda.context.SafeContext +import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.util.world.blockSearch +import net.minecraft.block.Block +import net.minecraft.util.math.BlockPos + +@Ta5kBuilder +fun findBlock(block: Block, searchRadius: Int) = FindPlacedBlockTask(block, searchRadius) + +class FindPlacedBlockTask( + private val block: Block, + private val searchRadius: Int +) : Task() { + override val name = "Finding placed block: $block" + + override fun SafeContext.onStart() { + val pos = + blockSearch(searchRadius, player.blockPos) { _, state -> + state.isOf(block) + }.keys.firstOrNull() + + if (pos != null) success(pos) + else failure(IllegalStateException("Could not find block $block")) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt index acb95a451..be2dbea17 100644 --- a/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/OpenContainerTask.kt @@ -25,6 +25,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder import com.lambda.threading.runSafeAutomated import com.lambda.util.TickTimer import com.lambda.util.player.RotationUtils.lookAtBlock @@ -34,7 +35,15 @@ import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction -class OpenContainerTask @Ta5kBuilder constructor( +@Ta5kBuilder +context(automated: Automated) +fun openContainer( + blockPos: BlockPos, + waitForSlotLoad: Boolean = true, + sides: Set = Direction.entries.toSet() +) = OpenContainerTask(blockPos, waitForSlotLoad, sides, automated) + +class OpenContainerTask @Ta5kBuilder internal constructor( private val blockPos: BlockPos, private val waitForSlotLoad: Boolean = true, private val sides: Set = Direction.entries.toSet(), @@ -112,14 +121,4 @@ class OpenContainerTask @Ta5kBuilder constructor( containerState = State.Opening } } - - companion object { - @Ta5kBuilder - context(automated: Automated) - fun openContainer( - blockPos: BlockPos, - waitForSlotLoad: Boolean = true, - sides: Set = Direction.entries.toSet() - ) = OpenContainerTask(blockPos, waitForSlotLoad, sides, automated) - } } diff --git a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt index 667b8230a..92a451718 100644 --- a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt @@ -27,8 +27,8 @@ import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.manager.ManagerUtils import com.lambda.task.Task -import com.lambda.task.tasks.BuildTask.Companion.build -import com.lambda.task.wrappers.thenAction +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockPos import com.lambda.util.item.ItemUtils.shulkerBoxes @@ -41,7 +41,15 @@ import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction -class PlaceContainerTask @Ta5kBuilder constructor( +@Ta5kBuilder +context(automated: Automated) +fun placeContainer(slot: Slot?) = PlaceContainerTask(slot, automated) + +@Ta5kBuilder +context(automated: Automated) +fun placeContainer(slot: () -> Slot?) = PlaceContainerTask(slot(), automated) + +class PlaceContainerTask @Ta5kBuilder internal constructor( val slot: Slot?, automated: Automated ) : Task(), Automated by automated { @@ -102,15 +110,4 @@ class PlaceContainerTask @Ta5kBuilder constructor( } else -> false } - - @Suppress("unused") - companion object { - @Ta5kBuilder - context(automated: Automated) - fun placeContainer(slot: Slot?) = PlaceContainerTask(slot, automated) - - @Ta5kBuilder - context(automated: Automated) - fun placeContainer(slot: () -> Slot?) = PlaceContainerTask(slot(), automated) - } } diff --git a/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt b/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt index 27b7ad071..5493c61cb 100644 --- a/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt @@ -19,18 +19,17 @@ package com.lambda.task.tasks import com.lambda.context.SafeContext import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder -class SimpleActionTask @Ta5kBuilder constructor( +@Ta5kBuilder +fun simpleAction(name: String, action: SafeContext.() -> Unit) = SimpleActionTask(name, action) + +class SimpleActionTask @Ta5kBuilder internal constructor( override val name: String, - val action: () -> Unit + val action: SafeContext.() -> Unit ) : Task() { override fun SafeContext.onStart() { action() success() } - - companion object { - @Ta5kBuilder - fun simpleAction(name: String, action: () -> Unit) = SimpleActionTask(name, action) - } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt b/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt index 4402252b7..867777ba5 100644 --- a/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/SlotByCacheTask.kt @@ -19,10 +19,14 @@ package com.lambda.task.tasks import com.lambda.context.SafeContext import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder import com.lambda.util.player.SlotUtils.matches import net.minecraft.screen.slot.Slot -class SlotByCacheTask @Ta5kBuilder constructor( +@Ta5kBuilder +fun slotByCache(slotCache: Slot) = SlotByCacheTask(slotCache) + +class SlotByCacheTask @Ta5kBuilder internal constructor( val slotCache: Slot ) : Task() { override val name = "Finding slot by cache: $slotCache" @@ -33,9 +37,4 @@ class SlotByCacheTask @Ta5kBuilder constructor( if (slot != null) success(slot) else failure("Failed to find matching slot by cache: $slotCache") } - - companion object { - @Ta5kBuilder - fun slotByCache(slotCache: Slot) = SlotByCacheTask(slotCache) - } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/wrappers/ActionTask.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/ActionTasks.kt similarity index 69% rename from src/main/kotlin/com/lambda/task/wrappers/ActionTask.kt rename to src/main/kotlin/com/lambda/task/tasks/wrappers/ActionTasks.kt index 01f3af7c2..d1bb7290e 100644 --- a/src/main/kotlin/com/lambda/task/wrappers/ActionTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/wrappers/ActionTasks.kt @@ -15,16 +15,30 @@ * along with this program. If not, see . */ -package com.lambda.task.wrappers +package com.lambda.task.tasks.wrappers import com.lambda.context.SafeContext import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder @Ta5kBuilder -infix fun Task.thenAction(action: SafeContext.(R) -> Unit): Task = +fun actionTask(action: SafeContext.() -> R) = + ActionTask(action) + +@Ta5kBuilder +infix fun Task.thenAction(action: SafeContext.(R) -> R2): Task = SequencedActionTask(this, action) +class ActionTask @Ta5kBuilder internal constructor( + private val action: SafeContext.() -> R +) : Task() { + override val name get() = "Performing action" + + override fun SafeContext.onStart() { + success(action()) + } +} + /** * A task that performs a given task ([innerTask]) and then a given [action]. * @@ -32,17 +46,16 @@ infix fun Task.thenAction(action: SafeContext.(R) -> Unit): Task = * * @see thenAction */ -class SequencedActionTask( +class SequencedActionTask @Ta5kBuilder internal constructor( private val innerTask: Task, - private val action: SafeContext.(R) -> Unit, -) : Task() { + private val action: SafeContext.(R) -> R2, +) : Task() { override val name get() = "Performing action after ${innerTask.name}" override fun SafeContext.onStart() { innerTask .onSuccess { result -> - action(this, result) - success(result) + success(action(this, result)) } .execute(this@SequencedActionTask) } diff --git a/src/main/kotlin/com/lambda/task/tasks/wrappers/BranchTasks.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/BranchTasks.kt new file mode 100644 index 000000000..1228310e9 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/wrappers/BranchTasks.kt @@ -0,0 +1,103 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks.wrappers + +import com.lambda.context.SafeContext +import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator + +@Ta5kBuilder +fun Task.withBranch( + onSuccess: TaskGenerator, + onFailure: TaskGenerator +) = BranchTask(this, onSuccess, onFailure) + +@Ta5kBuilder +fun Task.withBranchOrNull( + onSuccess: TaskOrNullGenerator, + onFailure: TaskOrNullGenerator +) = OptionalBranchTask(this, onSuccess, onFailure) + +/** + * A task that strictly branches into one of two tasks based on the success or failure of the [innerTask]. + * + * @see withBranch + */ +class BranchTask @Ta5kBuilder internal constructor( + private val innerTask: Task, + private val onSuccessGenerator: TaskGenerator, + private val onFailureGenerator: TaskGenerator +) : Task() { + override val name get() = "Branching task for ${innerTask.name}" + + override fun SafeContext.onStart() { + innerTask + .onSuccess { result -> + onSuccessGenerator(this, result) + .onSuccess { success(it) } + .execute(this@BranchTask) + } + .onFailure { cause -> + onFailureGenerator(this, cause) + .onSuccess { success(it) } + .execute(this@BranchTask) + } + .execute(this@BranchTask) + } + + override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { + if (subTask != innerTask) super.onSubTaskFailure(subTask, cause) + } +} + +/** + * A task that strictly branches into one of two optional tasks based on the success or failure of the [innerTask]. + * + * @see withBranchOrNull + */ +class OptionalBranchTask @Ta5kBuilder internal constructor( + private val innerTask: Task, + private val onSuccessGenerator: TaskOrNullGenerator, + private val onFailureGenerator: TaskOrNullGenerator +) : Task() { + override val name get() = "Optional branching task for ${innerTask.name}" + + override fun SafeContext.onStart() { + innerTask + .onSuccess { result -> + onSuccessGenerator(this, result) + ?.onSuccess { success(it) } + ?.execute(this@OptionalBranchTask) + ?: success(null) + } + .onFailure { cause -> + onFailureGenerator(this, cause) + ?.onSuccess { success(it) } + ?.execute(this@OptionalBranchTask) + ?: failure("Optional onFailure task not present for task: ${innerTask.name}") + } + .execute(this@OptionalBranchTask) + } + + override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { + if (subTask != innerTask) super.onSubTaskFailure(subTask, cause) + } +} + diff --git a/src/main/kotlin/com/lambda/task/tasks/wrappers/OnFailTasks.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/OnFailTasks.kt new file mode 100644 index 000000000..a2b242777 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/wrappers/OnFailTasks.kt @@ -0,0 +1,167 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks.wrappers + +import com.lambda.context.SafeContext +import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator +import com.lambda.threading.runSafe + +@Ta5kBuilder +infix fun Task.onFail(handler: TaskGenerator) = + OnFailTask(this, handler) + +@Ta5kBuilder +infix fun Task.onFailOrNull(handler: TaskOrNullGenerator) = + OnFailOrNullTask(this, handler) + +@Ta5kBuilder +infix fun Task.withRecovery(handler: TaskGenerator) = + RecoveryTask(this, handler) + +@Ta5kBuilder +infix fun Task.withRecoveryOrNull(handler: SafeContext.(Throwable) -> Task?) = + OptionalRecoveryTask(this, handler) + +/** + * A task that performs a given [innerTask] with a callback task in the event the [innerTask] fails. + * + * Useful for when you want a certain task to trigger when another task fails. + * If in need of a task that returns the same type to avoid further branching, see [withRecovery] or [withRecoveryOrNull]. + * + * @see onFail + */ +class OnFailTask @Ta5kBuilder internal constructor( + private val innerTask: Task, + private val onFailTaskGenerator: TaskGenerator +) : Task() { + override val name get() = "On fail task for ${innerTask.name}" + + override fun SafeContext.onStart() { + innerTask + .onSuccess { success(it) } + .onFailure { cause -> + onFailTaskGenerator(cause) + .onSuccess { success(null) } + .execute(this@OnFailTask) + } + .execute(this@OnFailTask) + } + + override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { + if (subTask != innerTask) super.onSubTaskFailure(subTask, cause) + } +} + +/** + * A task that performs a given [innerTask] with an optional callback task in the event the [innerTask] fails. + * + * Useful for when you want a certain task to trigger based on a predicate when another task fails. + * If in need of a task that returns the same type to avoid further branching, see [withRecovery] or [withRecoveryOrNull]. + * + * @see onFailOrNull + */ +class OnFailOrNullTask @Ta5kBuilder internal constructor( + private val innerTask: Task, + private val onFailTaskGenerator: TaskOrNullGenerator +) : Task() { + override val name get() = "On fail task for ${innerTask.name}" + + override fun SafeContext.onStart() { + innerTask + .onSuccess { success(it) } + .execute(this@OnFailOrNullTask) + } + + override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { + if (subTask == innerTask) { + runSafe { + onFailTaskGenerator(cause) + ?.onSuccess { success(null) } + ?.execute(this@OnFailOrNullTask) + ?: super.onSubTaskFailure(subTask, cause) + } + } else super.onSubTaskFailure(subTask, cause) + } +} + +/** + * A task that performs a given [innerTask] with a fallback to the task supplied by [recoveryTaskGenerator] in case of failure. + * Both the [innerTask] and the task generated by [recoveryTaskGenerator] have the same result type. + * + * Useful for if you want to have a backup task to return the same result type in case the first fails. + * This leaves the task branch clean of further branching while providing protection against individual task failure. + * + * @see withRecovery + */ +class RecoveryTask @Ta5kBuilder internal constructor( + private val innerTask: Task, + private val recoveryTaskGenerator: TaskGenerator, +) : Task() { + override val name get() = "Recovery task in case of failure for ${innerTask.name}" + + override fun SafeContext.onStart() { + innerTask + .onSuccess { success(it) } + .onFailure { cause -> + recoveryTaskGenerator(this, cause) + .onSuccess { success(it) } + .execute(this@RecoveryTask) + } + .execute(this@RecoveryTask) + } + + override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { + if (subTask != innerTask) super.onSubTaskFailure(subTask, cause) + } +} + +/** + * A task that performs a given [innerTask] with a fallback to the optional task supplied by [recoveryTaskGenerator] in case of failure. + * Both the [innerTask] and the optional task generated by [recoveryTaskGenerator] have the same result type. + * + * Useful for if you want to have an optional backup task to return the same result type in case the first fails. + * This leaves the task branch clean of further branching while providing protection against individual task failure, unless null is returned from [recoveryTaskGenerator]. + * + * @see withRecovery + */ +class OptionalRecoveryTask @Ta5kBuilder internal constructor( + private val innerTask: Task, + private val recoveryTaskGenerator: TaskOrNullGenerator, +) : Task() { + override val name get() = "Optional recovery task in case of failure for ${innerTask.name}" + + override fun SafeContext.onStart() { + innerTask + .onSuccess { success(it) } + .execute(this@OptionalRecoveryTask) + } + + override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { + if (subTask == innerTask) { + runSafe { + recoveryTaskGenerator(this, cause) + ?.onSuccess { success(it) } + ?.execute(this@OptionalRecoveryTask) + ?: super.onSubTaskFailure(subTask, cause) + } + } else super.onSubTaskFailure(subTask, cause) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt new file mode 100644 index 000000000..c846d40a6 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks.wrappers + +import com.lambda.context.SafeContext +import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder + +@Ta5kBuilder +fun successTask(result: R) = + SuccessTask(result) + +@Ta5kBuilder +fun successTask() = successTask(Unit) + +@Ta5kBuilder +fun failureTask(throwable: R) = + FailureTask(throwable) + +@Ta5kBuilder +fun failureTask(cause: String) = + FailureTask(IllegalStateException(cause)) + +class SuccessTask @Ta5kBuilder internal constructor( + val result: R +) : Task() { + override val name = "Success task" + + override fun SafeContext.onStart() { + success(result) + } +} + +class FailureTask @Ta5kBuilder internal constructor( + val throwable: R +) : Task() { + override val name = "Failure task" + + override fun SafeContext.onStart() { + failure(throwable) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/wrappers/SequenceTasks.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/SequenceTasks.kt similarity index 58% rename from src/main/kotlin/com/lambda/task/wrappers/SequenceTasks.kt rename to src/main/kotlin/com/lambda/task/tasks/wrappers/SequenceTasks.kt index c8726880c..ea00d449d 100644 --- a/src/main/kotlin/com/lambda/task/wrappers/SequenceTasks.kt +++ b/src/main/kotlin/com/lambda/task/tasks/wrappers/SequenceTasks.kt @@ -15,21 +15,22 @@ * along with this program. If not, see . */ -package com.lambda.task.wrappers +package com.lambda.task.tasks.wrappers import com.lambda.context.SafeContext import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.TaskGenerator +import com.lambda.task.TaskOrNullGenerator +import com.lambda.task.TaskOrNullSupplier @Ta5kBuilder -infix fun Task.then(supplier: TaskSupplier) = - SequencedTask(this, supplier) +infix fun Task.then(generator: TaskGenerator) = + SequencedTask(this, generator) @Ta5kBuilder -infix fun Task.then(task: Task): Task { - require(task != this) { "Cannot link a task to itself" } - return SequencedTask(this) { task } -} +infix fun Task.then(task: Task): Task = + SequencedTask(this) { task } @Ta5kBuilder fun Task.then(vararg tasks: Task<*>) = @@ -38,19 +39,22 @@ fun Task.then(vararg tasks: Task<*>) = } @Ta5kBuilder -infix fun Task.thenOrNull(supplier: SafeContext.(R) -> Task?) = - OptionalSequencedTask(this, supplier) +infix fun Task.thenOrNull(generator: TaskOrNullGenerator) = + OptionalSequencedTask(this, generator) + +@Ta5kBuilder +fun taskOrNull(supplier: TaskOrNullSupplier) = TaskOrNullTask(supplier) /** - * A task that sequences the [firstTask] with the next task, supplied by [nextTaskSupplier]. + * A task that sequences the [firstTask] with the next task, supplied by [nextTaskGenerator]. * * Useful for when two tasks must be run sequentially. The result of the first task is fed into the supplier for the second. * * @see then */ -class SequencedTask( +class SequencedTask @Ta5kBuilder internal constructor( private val firstTask: Task, - private val nextTaskSupplier: TaskSupplier, + private val nextTaskGenerator: TaskGenerator, ) : Task() { override val name get() = "Chaining ${firstTask.name}" var second: Task? = null @@ -58,7 +62,7 @@ class SequencedTask( override fun SafeContext.onStart() { firstTask .onSuccess { result -> - second = nextTaskSupplier(this, result) + second = nextTaskGenerator(this, result) .onSuccess { success(it) } .execute(this@SequencedTask) } @@ -67,26 +71,46 @@ class SequencedTask( } /** - * A task that sequences the [firstTask] with the next optional task, supplied by [nextTaskSupplier]. + * A task that sequences the [firstTask] with the next optional task, supplied by [nextTaskGenerator]. * * Useful for when you want to sequence a second task after the first based on a predicate. The result of the first task could help shape that outcome. * * @see thenOrNull */ -class OptionalSequencedTask( +class OptionalSequencedTask @Ta5kBuilder internal constructor( private val firstTask: Task, - private val nextTaskSupplier: TaskOrNullSupplier + private val nextTaskGenerator: TaskOrNullGenerator ) : Task() { override val name get() = "Chaining ${firstTask.name}" override fun SafeContext.onStart() { firstTask .onSuccess { result -> - nextTaskSupplier(this, result) + nextTaskGenerator(this, result) ?.onSuccess { success(it) } ?.execute(this@OptionalSequencedTask) ?: success(null) } .execute(this@OptionalSequencedTask) } +} + +/** + * A task that runs an optional task, supplied by [taskOrNullSupplier]. + * + * Useful for starting a task branch where the first task could or could not be skipped. + * + * @see taskOrNull + */ +class TaskOrNullTask @Ta5kBuilder internal constructor( + private val taskOrNullSupplier: TaskOrNullSupplier +) : Task() { + override val name get() = "Optional task" + + override fun SafeContext.onStart() { + taskOrNullSupplier() + ?.onSuccess { success(it) } + ?.execute(this@TaskOrNullTask) + ?: success(null) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/wrappers/SoftFailTask.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/SoftFailTask.kt similarity index 89% rename from src/main/kotlin/com/lambda/task/wrappers/SoftFailTask.kt rename to src/main/kotlin/com/lambda/task/tasks/wrappers/SoftFailTask.kt index 6163a43b0..5a0cb6004 100644 --- a/src/main/kotlin/com/lambda/task/wrappers/SoftFailTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/wrappers/SoftFailTask.kt @@ -15,15 +15,12 @@ * along with this program. If not, see . */ -package com.lambda.task.wrappers +package com.lambda.task.tasks.wrappers import com.lambda.context.SafeContext import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder -typealias TaskSupplier = SafeContext.(R) -> Task -typealias TaskOrNullSupplier = SafeContext.(R) -> Task? - @Ta5kBuilder fun Task.softFail(): Task = SoftFailTask(this) @@ -35,7 +32,7 @@ fun Task.softFail(): Task = * * @see softFail */ -class SoftFailTask( +class SoftFailTask @Ta5kBuilder internal constructor( private val innerTask: Task, ) : Task() { override val name get() = "Soft fail protection for ${innerTask.name}" diff --git a/src/main/kotlin/com/lambda/task/wrappers/RecoveryTasks.kt b/src/main/kotlin/com/lambda/task/wrappers/RecoveryTasks.kt deleted file mode 100644 index 990e526f1..000000000 --- a/src/main/kotlin/com/lambda/task/wrappers/RecoveryTasks.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2026 Lambda - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.lambda.task.wrappers - -import com.lambda.context.SafeContext -import com.lambda.task.Task -import com.lambda.task.Task.Ta5kBuilder -import com.lambda.threading.runSafe - -@Ta5kBuilder -infix fun Task.onFail(handler: SafeContext.(Throwable) -> Task) = - RecoveryTask(this, handler) - -@Ta5kBuilder -infix fun Task.onFailOrNull(handler: SafeContext.(Throwable) -> Task?) = - OptionalRecoveryTask(this, handler) - -/** - * A task that performs a given task ([innerTask]) with a fallback to the task supplied by [recoveryTaskSupplier] in-case of failure. - * - * Useful for if you want to keep the task branch going even in the event an individual task fails. - * - * @see onFail - */ -class RecoveryTask( - private val innerTask: Task, - private val recoveryTaskSupplier: SafeContext.(Throwable) -> Task, -) : Task() { - override val name get() = "Recovery task in case of failure for ${innerTask.name}" - - override fun SafeContext.onStart() { - innerTask - .onSuccess { success(null) } - .execute(this@RecoveryTask) - } - - override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { - if (subTask == innerTask) { - runSafe { - recoveryTaskSupplier(this, cause) - .onSuccess { success(it) } - .execute(this@RecoveryTask) - } - } else super.onSubTaskFailure(subTask, cause) - } -} - -/** - * A task that performs a given task ([innerTask]) with a fallback to the nullable task supplied by [recoveryTaskSupplier] in-case of failure. - * - * Useful for if you want to keep the task branch going even in the event an individual task fails, but want to supply the recovery task based on a predicate. - * - * @see onFailOrNull - */ -class OptionalRecoveryTask( - private val innerTask: Task, - private val recoveryTaskSupplier: SafeContext.(Throwable) -> Task?, -) : Task() { - override val name get() = "Optional recovery task in case of failure for ${innerTask.name}" - - override fun SafeContext.onStart() { - innerTask - .onSuccess { success(null) } - .execute(this@OptionalRecoveryTask) - } - - override fun onSubTaskFailure(subTask: Task<*>, cause: Throwable) { - if (subTask == innerTask) { - runSafe { - recoveryTaskSupplier(this, cause) - ?.onSuccess { success(it) } - ?.execute(this@OptionalRecoveryTask) - ?: super.onSubTaskFailure(subTask, cause) - } - } else super.onSubTaskFailure(subTask, cause) - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/util/world/WorldUtils.kt b/src/main/kotlin/com/lambda/util/world/WorldUtils.kt index e9b3e4fe7..a13fa4684 100644 --- a/src/main/kotlin/com/lambda/util/world/WorldUtils.kt +++ b/src/main/kotlin/com/lambda/util/world/WorldUtils.kt @@ -171,13 +171,13 @@ object WorldUtils { range: FastVector, step: FastVector, ) = sequence { - for (x in -range.x..range.x step step.x) { - for (y in -range.y..range.y step step.y) { - for (z in -range.z..range.z step step.z) { - yield(pos plus fastVectorOf(x, y, z)) - } - } - } + (-range.x..range.x step step.x).forEach { x -> + (-range.y..range.y step step.y).forEach { y -> + (-range.z..range.z step step.z).forEach { z -> + yield(pos plus fastVectorOf(x, y, z)) + } + } + } } } From d008a3603ad6f7aa5f8b030fa0da51f693a4d3c3 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:25:04 +0100 Subject: [PATCH 09/18] cleanup. Last thing left is returning slots for picked up items or something --- .../command/commands/TransferCommand.kt | 12 +- .../lambda/config/blocks/InventoryConfig.kt | 3 +- .../lambda/config/blocks/InventorySettings.kt | 4 +- .../simulation/result/results/BreakResult.kt | 7 +- .../result/results/GenericResult.kt | 7 +- .../construction/simulation/sims/BreakSim.kt | 8 +- .../simulation/sims/InteractSim.kt | 6 +- .../handler/handlers/ContainerHandler.kt | 12 +- .../inventory/ContainerSelection.kt | 5 +- .../inventory/container/Container.kt | 89 ++++----------- .../inventory/container/ContainerRank.kt} | 32 +++--- .../container/OpenedContainerContext.kt | 6 +- .../container/containers/ArmorContainer.kt | 3 +- .../container/containers/CreativeContainer.kt | 5 +- .../containers/HotbarAndInventoryContainer.kt | 3 +- .../container/containers/HotbarContainer.kt | 5 +- .../containers/InventoryContainer.kt | 3 +- .../container/containers/MainHandContainer.kt | 5 +- .../container/containers/OffHandContainer.kt | 5 +- .../container/containers/PlayerContainer.kt | 3 +- .../containers/external/ChestContainer.kt | 12 +- .../external/EnderChestContainer.kt | 19 ++-- .../external/PlacedShulkerBoxContainer.kt | 3 +- .../external/ShulkerBoxContainer.kt | 29 +++-- .../containers/external/StashContainer.kt | 7 +- .../lambda/module/modules/combat/AutoTotem.kt | 2 +- .../module/modules/combat/CrystalAura.kt | 4 +- .../module/modules/debug/ContainerTest.kt | 2 +- .../module/modules/movement/BetterFirework.kt | 2 +- .../elytrafly/modes/GrimControlElytraFly.kt | 2 +- .../task/tasks/AcquirePlacedBlockTask.kt | 2 +- .../com/lambda/task/tasks/AcquireStackTask.kt | 5 +- .../task/tasks/ContainerTransferTask.kt | 103 +++++++++++------- .../kotlin/com/lambda/task/tasks/EatTask.kt | 11 +- .../lambda/task/tasks/FindPlacedBlockTask.kt | 2 +- .../lambda/task/tasks/wrappers/ResultTasks.kt | 57 ---------- 36 files changed, 208 insertions(+), 277 deletions(-) rename src/main/kotlin/com/lambda/{task/tasks/SimpleActionTask.kt => interaction/inventory/container/ContainerRank.kt} (60%) delete mode 100644 src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index a9e046b44..949724141 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -34,6 +34,7 @@ import com.lambda.interaction.handler.handlers.ContainerHandler.findContainersWi import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.task.RootTask import com.lambda.task.Task +import com.lambda.task.tasks.transfer import com.lambda.threading.runSafeAutomated import com.lambda.util.CommunicationUtils.info import com.lambda.util.extension.CommandBuilder @@ -55,7 +56,7 @@ object TransferCommand : LambdaCommand( isItem(stack(ctx).value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val containers = selection.findContainers() + val containers = selection.findContainers().toList() val indexedContainers = containers.withIndex() suggestMatching( @@ -65,7 +66,7 @@ object TransferCommand : LambdaCommand( "\"${index + 1}. ${container.name}\"" }, { (_, container) -> - container.description(selection) + container.descriptionAndStock(selection) } ) } ?: builder.buildFuture() @@ -76,7 +77,7 @@ object TransferCommand : LambdaCommand( isItem(stack(ctx).value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val containers = selection.findContainersWithSpace() + val containers = selection.findContainersWithSpace().toList() val indexedContainers = containers.withIndex() suggestMatching( @@ -86,7 +87,7 @@ object TransferCommand : LambdaCommand( "\"${index + 1}. ${container.name}\"" }, { (_, container) -> - container.description(selection) + container.descriptionAndStock(selection) } ) } ?: builder.buildFuture() @@ -104,7 +105,8 @@ object TransferCommand : LambdaCommand( it.name == to().value().split(".").last().trim() } ?: return@executeWithResult failure("To container not found") - fromContainer.transferByTask(selection, toContainer).execute(RootTask) + transfer(selection, fromContainer, toContainer) + .execute(RootTask) } return@executeWithResult success() } diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 399677cdb..3e839a7af 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -22,6 +22,7 @@ import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.util.Describable import com.lambda.util.NamedEnum import net.minecraft.item.Item @@ -32,7 +33,7 @@ interface InventoryConfig { val accessPriority: Priority val storePriority: Priority - val allowedContainers: Collection + val allowedContainers: Collection val enderChestSearchRadius: Int diff --git a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt index 34b5e2751..f5297f702 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt @@ -21,7 +21,7 @@ import com.lambda.config.Config import com.lambda.config.ConfigBlock import com.lambda.config.Group import com.lambda.event.events.TickEvent.Companion.ALL_STAGES -import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.util.item.ItemUtils class InventorySettings(override val c: Config) : InventoryConfig, ConfigBlock { @@ -33,7 +33,7 @@ class InventorySettings(override val c: Config) : InventoryConfig, ConfigBlock { override val disposables by c.setting("Disposables", ItemUtils.defaultDisposables, description = "Items that will be ignored when checking for a free slot") override val accessPriority by c.setting("Access Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when retrieving the item from") override val storePriority by c.setting("Store Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when storing the item to") - override val allowedContainers by c.setting("Allowed Containers", Container.Rank.entries, description = "What containers are accessible") + override val allowedContainers by c.setting("Allowed Containers", ContainerRank.entries, description = "What containers are accessible") @Group(ENDER_CHEST_GROUP) override val enderChestSearchRadius by c.setting("Initial Search Radius", 10, 0..20, unit = " blocks", description = "Initial search radius to scan for an already placed ender chest. If one isn't found, one will be placed. If an ender chest isn't found in the inventory, it scans the rest of the loaded area to find an already placed one") } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 3be7609de..913060307 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -35,6 +35,7 @@ import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task +import com.lambda.task.tasks.transferTo import com.lambda.task.tasks.wrappers.softFail import net.minecraft.block.BlockState import net.minecraft.item.Item @@ -120,9 +121,9 @@ sealed class BreakResult : BuildResult() { context(task: Task<*>, _: AutomatedSafeContext) override fun resolve() { selectStack { inverted { isItem(badItem) } } - .transfer(HotbarContainer) - ?.softFail() - ?.execute(task) + .transferTo(HotbarContainer) + .softFail() + .execute(task) } override fun compareResult(other: ComparableResult) = diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index fe897f082..ed5b54356 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -30,6 +30,7 @@ import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task +import com.lambda.task.tasks.transferTo import com.lambda.task.tasks.wrappers.softFail import net.minecraft.client.data.TextureMap.side import net.minecraft.item.ItemStack @@ -101,9 +102,9 @@ sealed class GenericResult : BuildResult() { context(task: Task<*>, _: AutomatedSafeContext) override fun resolve() { neededSelection - .transfer(HotbarContainer) - ?.softFail() - ?.execute(task) + .transferTo(HotbarContainer) + .softFail() + .execute(task) } override fun RenderBuilder.render() { diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt index ce5e665b6..74741cd17 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt @@ -33,7 +33,7 @@ import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.sele import com.lambda.interaction.inventory.StackAndSlot import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.manager.managers.hotbar.HotbarManager import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest @@ -138,10 +138,9 @@ class BreakSim internal constructor(simInfo: SimInfo) } private fun AutomatedSafeContext.getSwapStack(): Pair? { - // Stack size 0 to account for attacking with an empty hand. Empty slots have stack size 0 val stackSelection = selectStack { if (breakConfig.efficientOnly) isEfficientForBreaking(state) - if(breakConfig.suitableToolsOnly) isSuitableForBreaking(state) + if (breakConfig.suitableToolsOnly) isSuitableForBreaking(state) if (breakConfig.forceSilkTouch) hasEnchantment(Enchantments.SILK_TOUCH) if (breakConfig.forceFortunePickaxe) hasEnchantment(Enchantments.FORTUNE) sortedWith { @@ -156,12 +155,13 @@ class BreakSim internal constructor(simInfo: SimInfo) } val containerSelection = selectContainer { - ofAnyType(Container.Rank.Hotbar) + ofAnyType(ContainerRank.Hotbar) } val hotbarCandidates = stackSelection .findContainers(containerSelection) .flatMap { stackSelection.filter(it.stacks) } + .toList() if (hotbarCandidates.isEmpty()) { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt index 6374e6947..b1b36ef4d 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt @@ -29,9 +29,9 @@ import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handler.handlers.ContainerHandler.findContainers import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.inventory.select import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation import com.lambda.interaction.manager.managers.rotating.RotationManager @@ -206,7 +206,7 @@ class InteractSim internal constructor(simInfo: InteractSimInfo) } val stackSelection = item?.select() ?: selectStack { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } - val containerSelection = selectContainer { ofAnyType(Container.Rank.Hotbar) } + val containerSelection = selectContainer { ofAnyType(ContainerRank.Hotbar) } val container = stackSelection.findContainers(containerSelection).firstOrNull() ?: run { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index 770ea2850..39fb480a7 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -26,10 +26,10 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.ContainerMarker import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.containers.external.ChestContainer import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer +import com.lambda.interaction.inventory.select import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.ReflectionUtils.getInstances import com.lambda.util.extension.containerStacks @@ -42,8 +42,8 @@ import net.minecraft.screen.ScreenHandlerType // ToDo: Make this a Configurable to save container caches. Should use a cached region based storage system. @Suppress("unused") object ContainerHandler : Loadable { - private val containers: List - get() = compileContainers + runtimeContainers + private val containers: Sequence + get() = compileContainers.asSequence() + runtimeContainers private val compileContainers = getInstances() private val runtimeContainers = mutableSetOf() @@ -52,14 +52,12 @@ object ContainerHandler : Loadable { val filteredContainers get() = containers - .flatMap { setOf(it) + it.shulkerContainers } .filter { automated.inventoryConfig.containerSelection.matches(it) } .sorted() val allContainers get() = containers - .flatMap { setOf(it) + it.shulkerContainers } .sorted() var lastInteractedBlockEntity: BlockEntity? = null @@ -101,10 +99,10 @@ object ContainerHandler : Loadable { @ContainerMarker context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.transfer(destination: Container) = + fun StackSelection.move(destination: Container) = with(automatedSafeContext) { findContainer(inventoryConfig.containerSelection) - ?.transfer(this@transfer, destination) + ?.move(this@move, destination) ?: false } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt index 332783fd3..ef32c4633 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt @@ -18,6 +18,7 @@ package com.lambda.interaction.inventory import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank /** * ContainerSelection is a class that holds a predicate for matching MaterialContainers. @@ -52,11 +53,11 @@ class ContainerSelectionBuilder private constructor() { private var comparator: Comparator = compareBy { it.rank } private var invertNewSelectors = false - fun ofAnyType(vararg types: Container.Rank) { + fun ofAnyType(vararg types: ContainerRank) { appendSelector { container -> types.contains(container.rank) } } - fun noneOfType(vararg types: Container.Rank) { + fun noneOfType(vararg types: ContainerRank) { appendSelector { container -> !types.contains(container.rank) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index c09a5b6db..58563fbcf 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -23,17 +23,13 @@ import com.lambda.context.SafeContext import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.tasks.ContainerTransferTask import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.empty -import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemStackUtils.spaceLeft -import com.lambda.util.item.ItemUtils import com.lambda.util.item.ItemUtils.toItemCount import com.lambda.util.text.TextBuilder import com.lambda.util.text.TextDsl @@ -48,8 +44,11 @@ import net.minecraft.text.Text // ToDo: Make jsonable to persistently store them abstract class Container( - val rank: Rank + val rank: ContainerRank ) : Nameable, Comparable { + override val name: String + get() = buildText { text(description) }.string + abstract val slots: List abstract var stacks: List open val swapMethodPriority = 0 @@ -70,6 +69,13 @@ abstract class Container( it.stack.isStackable } + context(_: SafeContext) + fun descriptionAndStock(selection: StackSelection) = + buildText { + text(description) + stock(selection) + } + @TextDsl context(_: SafeContext) fun TextBuilder.stock(selection: StackSelection) { @@ -87,38 +93,6 @@ abstract class Container( highlighted("${selection.optimalStack?.name?.string}") } - context(_: SafeContext) - fun description(selection: StackSelection) = - buildText { - text(description) - stock(selection) - } - - override val name: String - get() = buildText { text(description) }.string - - //ToDo: Bundles - val shulkerContainers - get() = - slots.takeIf { - it.isEmpty() - }?.filter { - it.stack.item in ItemUtils.shulkerBoxes - }?.map { slot -> - ShulkerBoxContainer( - slot.stack.shulkerBoxStacks, - this@Container, - slot - ) - }?.toSet() - ?: stacks.map { stack -> - ShulkerBoxContainer( - stack.shulkerBoxStacks, - this@Container, - null - ) - }.toSet() - open val isAccessed get() = true fun update(slots: List) { @@ -131,29 +105,25 @@ abstract class Container( PlayerOpenContainerTask(description, ::isAccessed) context(automatedSafeContext: AutomatedSafeContext) - fun transfer(selection: StackSelection, toContainer: Container): Boolean = + internal fun move(selection: StackSelection, toContainer: Container): Boolean = with(automatedSafeContext) { val (fromSlot, toSlot) = getTransferSlots(selection, toContainer) if (fromSlot == null || toSlot == null) return false - return transfer(fromSlot, toSlot, toContainer) + swap(fromSlot, toSlot, toContainer) } - context(_: Automated) - fun getTransferSlots(selection: StackSelection, destination: Container): Pair = - Pair(getSlot(selection), destination.getReplaceSlot()) - context(automatedSafeContext: AutomatedSafeContext) - fun transfer(fromSlot: Slot, toSlot: Slot, toContainer: Container): Boolean { + internal fun swap(fromSlot: Slot, toSlot: Slot, toContainer: Container): Boolean { val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@Container, toContainer) if (transferEvent.post().isCanceled()) return false return automatedSafeContext.inventoryRequest { - if (swapMethodPriority > toContainer.swapMethodPriority) transfer(fromSlot, toSlot) - else with(toContainer) { transfer(toSlot, fromSlot) } + if (swapMethodPriority > toContainer.swapMethodPriority) swap(fromSlot, toSlot) + else with(toContainer) { swap(toSlot, fromSlot) } }.submit().done } context(safeContext: SafeContext) - open fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + protected open fun InvRequestBuilder.swap(fromHere: Slot, toSlot: Slot) { if (fromHere.stack.isEmpty) moveSlot(toSlot.id, fromHere.id) else { moveSlot(fromHere.id, toSlot.id) @@ -161,37 +131,20 @@ abstract class Container( } } - context(automated: Automated) - fun transferByTask(stackSelection: StackSelection, toContainer: Container, failIfNoStack: Boolean = true) = - ContainerTransferTask(this, toContainer, stackSelection, failIfNoStack, automated) - open fun stackCount(selection: StackSelection) = selection.filter(stacks).count open fun spaceAvailable(selection: StackSelection) = selection.filter(stacks).spaceLeft + stacks.empty + context(_: Automated) + fun getTransferSlots(selection: StackSelection, destination: Container): Pair = + Pair(getSlot(selection), destination.getReplaceSlot()) + context(_: Automated) open fun getReplaceSlot() = slots.sortedWith(replaceSorter).firstOrNull() open fun getSlot(selection: StackSelection) = selection.bestMatch(slots) - enum class Rank { - MainHand, - OffHand, - Hotbar, - Inventory, - HotbarAndInventory, - Armor, - Player, - Creative, - ShulkerBox, - EnderChest, - PlacedShulkerBox, - PlacedEnderChest, - Chest, - Stash - } - override fun compareTo(other: Container) = compareBy { it.rank }.compare(this, other) } diff --git a/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/ContainerRank.kt similarity index 60% rename from src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt rename to src/main/kotlin/com/lambda/interaction/inventory/container/ContainerRank.kt index 5493c61cb..2d50d0c47 100644 --- a/src/main/kotlin/com/lambda/task/tasks/SimpleActionTask.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/ContainerRank.kt @@ -15,21 +15,21 @@ * along with this program. If not, see . */ -package com.lambda.task.tasks +package com.lambda.interaction.inventory.container -import com.lambda.context.SafeContext -import com.lambda.task.Task -import com.lambda.task.Task.Ta5kBuilder - -@Ta5kBuilder -fun simpleAction(name: String, action: SafeContext.() -> Unit) = SimpleActionTask(name, action) - -class SimpleActionTask @Ta5kBuilder internal constructor( - override val name: String, - val action: SafeContext.() -> Unit -) : Task() { - override fun SafeContext.onStart() { - action() - success() - } +enum class ContainerRank { + MainHand, + OffHand, + Hotbar, + Inventory, + HotbarAndInventory, + Armor, + Player, + Creative, + ShulkerBox, + EnderChest, + PlacedShulkerBox, + PlacedEnderChest, + Chest, + Stash } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt index 5b615bb86..7b25339e1 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt @@ -20,7 +20,7 @@ package com.lambda.interaction.inventory.container import com.lambda.context.Automated import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.tasks.simpleAction +import com.lambda.task.tasks.wrappers.actionTask interface OpenedContainerContext { @Ta5kBuilder @@ -33,8 +33,8 @@ open class BasicOpenedContainerContext( ) : OpenedContainerContext { context(_: Automated) final override fun close() = - simpleAction("Closing container") { - if (!isAccessed()) return@simpleAction + actionTask { + if (!isAccessed()) return@actionTask player.closeScreen() } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt index b0bafe110..f25f7629e 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt @@ -19,6 +19,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.util.player.SlotUtils.armorSlots import com.lambda.util.player.SlotUtils.armorStacks import com.lambda.util.text.buildText @@ -26,7 +27,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object ArmorContainer : Container(Rank.Armor) { +object ArmorContainer : Container(ContainerRank.Armor) { override val slots: List get() = mc.player?.armorSlots ?: emptyList() override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt index fd0e0135f..e96f0c892 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt @@ -21,6 +21,7 @@ import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.text.buildText import com.lambda.util.text.literal @@ -31,7 +32,7 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.PlayerScreenHandler import net.minecraft.screen.slot.Slot -data object CreativeContainer : Container(Rank.Creative) { +data object CreativeContainer : Container(ContainerRank.Creative) { override val slots = emptyList() override var stacks = emptyList() @@ -40,7 +41,7 @@ data object CreativeContainer : Container(Rank.Creative) { override val description = buildText { literal("Creative") } context(safeContext: SafeContext) - override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + override fun InvRequestBuilder.swap(fromHere: Slot, toSlot: Slot) { clickCreativeStack(fromHere.stack, toSlot.id) safeContext.player.currentScreenHandler.slots.getOrNull(toSlot.id)?.stack = fromHere.stack } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt index b5998dbec..44a6de2b4 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt @@ -19,6 +19,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks import com.lambda.util.text.buildText @@ -26,7 +27,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object HotbarAndInventoryContainer : Container(Rank.HotbarAndInventory) { +object HotbarAndInventoryContainer : Container(ContainerRank.HotbarAndInventory) { override val slots: List get() = mc.player?.hotbarAndInventorySlots ?: emptyList() override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt index 9949c3d88..9533e52cf 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.hotbarSlots import com.lambda.util.player.SlotUtils.hotbarStacks @@ -27,7 +28,7 @@ import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.screen.slot.Slot -object HotbarContainer : Container(Rank.Hotbar) { +object HotbarContainer : Container(ContainerRank.Hotbar) { override val slots: List get() = mc.player?.hotbarSlots ?: emptyList() override var stacks @@ -39,7 +40,7 @@ object HotbarContainer : Container(Rank.Hotbar) { override val description = buildText { literal("Hotbar") } context(safeContext: SafeContext) - override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + override fun InvRequestBuilder.swap(fromHere: Slot, toSlot: Slot) { swapWithHotbar(toSlot.id, safeContext.player.hotbarSlots.indexOf(fromHere)) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt index c54b101e5..d9cec92a0 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt @@ -19,6 +19,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.util.player.SlotUtils.inventorySlots import com.lambda.util.player.SlotUtils.inventoryStacks import com.lambda.util.text.buildText @@ -26,7 +27,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object InventoryContainer : Container(Rank.Inventory) { +object InventoryContainer : Container(ContainerRank.Inventory) { override val slots: List get() = mc.player?.inventorySlots ?: emptyList() override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt index c87db7077..39bcc95b7 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.mainHandSlots import com.lambda.util.text.buildText @@ -27,7 +28,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object MainHandContainer : Container(Rank.MainHand) { +object MainHandContainer : Container(ContainerRank.MainHand) { override val slots: List get() = mc.player?.mainHandSlots ?: emptyList() override var stacks: List @@ -39,7 +40,7 @@ object MainHandContainer : Container(Rank.MainHand) { override val description = buildText { literal("MainHand") } context(safeContext: SafeContext) - override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + override fun InvRequestBuilder.swap(fromHere: Slot, toSlot: Slot) { swapWithHotbar(toSlot.id, safeContext.player.inventory.selectedSlot) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt index cbe16ada8..88e65599b 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.offHandSlots import com.lambda.util.text.buildText @@ -27,7 +28,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object OffHandContainer : Container(Rank.OffHand) { +object OffHandContainer : Container(ContainerRank.OffHand) { override val slots: List get() = mc.player?.offHandSlots ?: emptyList() override var stacks: List @@ -39,7 +40,7 @@ object OffHandContainer : Container(Rank.OffHand) { override val description = buildText { literal("OffHand") } context(_: SafeContext) - override fun InvRequestBuilder.transfer(fromHere: Slot, toSlot: Slot) { + override fun InvRequestBuilder.swap(fromHere: Slot, toSlot: Slot) { swapWithHotbar(toSlot.id, 40) } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt index f33a461a5..736d1e787 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt @@ -19,6 +19,7 @@ package com.lambda.interaction.inventory.container.containers import com.lambda.Lambda.mc import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.util.player.SlotUtils.allSlots import com.lambda.util.player.SlotUtils.allStacks import com.lambda.util.text.buildText @@ -27,7 +28,7 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot @Suppress("unused") -object PlayerContainer : Container(Rank.Player) { +object PlayerContainer : Container(ContainerRank.Player) { override val slots: List get() = mc.player?.allSlots ?: emptyList() override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt index 1b454ba7d..06d553d15 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt @@ -23,6 +23,7 @@ import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.BasicOpenedContainerContext import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.OpenContainerTask import com.lambda.interaction.inventory.container.PlacedContainer @@ -36,7 +37,6 @@ import com.lambda.util.text.literal import net.minecraft.block.ChestBlock import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.item.ItemStack -import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos @@ -45,7 +45,7 @@ data class ChestContainer( val blockPos: BlockPos, override var stacks: List, override val stash: StashContainer? = null -) : Container(Rank.Chest), ExternalContainer, PlacedContainer { +) : Container(ContainerRank.Chest), ExternalContainer, PlacedContainer { override val slots get(): List = lastInteractedBlockEntity?.let { blockEntity -> @@ -82,16 +82,14 @@ data class ChestContainer( override fun SafeContext.onStart() { taskOrNull { if (isAccessed) null - else openContainer(blockPos).onSuccess { sh -> - success(OpenedChestContext(sh)) + else openContainer(blockPos).onSuccess { + success(OpenedChestContext()) } }.execute(this@AccessChestTask) } } - inner class OpenedChestContext( - val screenHandler: ScreenHandler, - ) : BasicOpenedContainerContext(::isAccessed) { + inner class OpenedChestContext : BasicOpenedContainerContext(::isAccessed) { val blockPos = this@ChestContainer.blockPos } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt index d6e71869b..e91df1cf8 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt @@ -22,6 +22,7 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.OpenContainerTask import com.lambda.interaction.inventory.container.OpenedContainerContext @@ -33,9 +34,9 @@ import com.lambda.task.tasks.findBlock import com.lambda.task.tasks.openContainer import com.lambda.task.tasks.placeContainer import com.lambda.task.tasks.wrappers.actionTask -import com.lambda.task.tasks.wrappers.successTask import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.task.tasks.wrappers.then +import com.lambda.task.tasks.wrappers.thenOrNull import com.lambda.task.tasks.wrappers.withBranch import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText @@ -44,11 +45,10 @@ import net.minecraft.block.Blocks import net.minecraft.block.entity.EnderChestBlockEntity import net.minecraft.item.ItemStack import net.minecraft.item.Items -import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.util.math.BlockPos -object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { +object EnderChestContainer : Container(ContainerRank.EnderChest), ExternalContainer { override val slots get() = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() @@ -76,16 +76,16 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { if (isAccessed) null else findBlock(Blocks.ENDER_CHEST, inventoryConfig.enderChestSearchRadius).withBranch( onSuccess = { pos -> - openContainer(pos).onSuccess { sh -> - success(OpenedEnderChestContext(sh, pos, false)) + openContainer(pos).onSuccess { + success(OpenedEnderChestContext(pos, false)) } }, onFailure = { acquireStack(Items.ENDER_CHEST.select(1)) .then { placeContainer(it) } .then { pos -> - openContainer(pos).onSuccess { sh -> - success(OpenedEnderChestContext(sh, pos, true)) + openContainer(pos).onSuccess { + success(OpenedEnderChestContext(pos, true)) } } } @@ -95,7 +95,6 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { } class OpenedEnderChestContext( - val screenHandler: ScreenHandler, val blockPos: BlockPos, val placed: Boolean ) : OpenedContainerContext { @@ -104,9 +103,9 @@ object EnderChestContainer : Container(Rank.EnderChest), ExternalContainer { taskOrNull { if (isAccessed) actionTask { player.closeScreen() } else null - }.then { + }.thenOrNull { if (placed) breakAndCollect(blockPos) - else successTask() + else null } } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt index cb9d53de0..224bb09bc 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt @@ -23,6 +23,7 @@ import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.BasicOpenedContainerContext import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.inventory.container.OpenContainerTask import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.task.Task.Ta5kBuilder @@ -43,7 +44,7 @@ class PlacedShulkerBoxContainer( val block: Block, override val stash: StashContainer?, override var stacks: List -) : Container(Rank.PlacedShulkerBox), PlacedContainer { +) : Container(ContainerRank.PlacedShulkerBox), PlacedContainer { override val slots: List get() = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index 71c79b4f8..3d666905f 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -23,12 +23,13 @@ import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.NestedContainer import com.lambda.interaction.inventory.container.OpenContainerTask import com.lambda.interaction.inventory.container.OpenedContainerContext +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.PlayerContainer import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.breakAndCollect import com.lambda.task.tasks.openContainer @@ -43,7 +44,6 @@ import com.lambda.util.text.highlighted import com.lambda.util.text.literal import net.minecraft.block.entity.ShulkerBoxBlockEntity import net.minecraft.item.ItemStack -import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos @@ -52,7 +52,7 @@ data class ShulkerBoxContainer( override var stacks: List, val containedIn: Container, override val slotCache: Slot, -) : Container(Rank.ShulkerBox), ExternalContainer, NestedContainer { +) : Container(ContainerRank.ShulkerBox), ExternalContainer, NestedContainer { override val slots get(): List = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() @@ -84,23 +84,22 @@ data class ShulkerBoxContainer( automated: Automated ) : OpenContainerTask(description), Automated by automated { override fun SafeContext.onStart() { - transfer( - selectStack { isSlot(slotCache) }, - containedIn, - HotbarContainer - ).then { slot -> placeContainer(slot) } - .then { pos -> - openContainer(pos).onSuccess { sh -> - success(OpenedShulkerBoxContext(pos, sh, containedIn)) - } + transfer( + selectStack { isSlot(slotCache) }, + containedIn, + HotbarContainer + ).then { slot -> placeContainer(slot) } + .then { pos -> + openContainer(pos).onSuccess { + success(OpenedShulkerBoxContext(pos, containedIn)) } - .execute(this@OpenShulkerBoxTask) + } + .execute(this@OpenShulkerBoxTask) } } inner class OpenedShulkerBoxContext( val blockPos: BlockPos, - val screenHandler: ScreenHandler, val fromContainer: Container ) : OpenedContainerContext { context(automated: Automated) @@ -112,7 +111,7 @@ data class ShulkerBoxContainer( .then { slot -> transfer( selectStack { isSlot(slot) }, - PlayerContainer, + HotbarAndInventoryContainer, fromContainer ) } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt index b425a7e66..8c7063980 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt @@ -19,6 +19,7 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.util.math.roundedBlockPos import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -30,7 +31,7 @@ import net.minecraft.util.math.Box data class StashContainer( val chests: Set, val pos: Box, -) : Container(Rank.Stash) { +) : Container(ContainerRank.Stash) { override val slots: List get() = chests.flatMap { it.slots } override var stacks: List @@ -43,7 +44,5 @@ data class StashContainer( } override fun stackCount(selection: StackSelection): Int = - chests.sumOf { - it.stackCount(selection) - } + chests.sumOf { it.stackCount(selection) } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index 8bcc7f89e..ee8fe19c6 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -24,7 +24,7 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.FriendHandler -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select +import com.lambda.interaction.inventory.select import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 04b36128a..f2dc2b411 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -27,7 +27,7 @@ import com.lambda.context.SafeContext import com.lambda.event.events.EntityEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handler.handlers.ContainerHandler.transfer +import com.lambda.interaction.handler.handlers.ContainerHandler.move import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer @@ -492,7 +492,7 @@ object CrystalAura : Module( Hand.MAIN_HAND -> HotbarContainer Hand.OFF_HAND -> OffHandContainer } - if (!selection.transfer(swapTo)) return@runSafe + if (!selection.move(swapTo)) return@runSafe crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.matches(it) } } if (!hotbarRequest(crystalSlot).submit().done) return@runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index ddc1d9205..3bb5ebe6f 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select +import com.lambda.interaction.inventory.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.RootTask.run diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 6455236ac..679ed9a6d 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -29,11 +29,11 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.GlideHandler -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.inventory.select import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt index b84478fbe..e435fdf57 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt @@ -22,9 +22,9 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.PlayerPacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.inventory.select import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.modules.movement.BetterFirework.startFirework diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt index 30a0dbf73..d8c15f21a 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -22,7 +22,7 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.ContainerHandler.findSlots -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.select +import com.lambda.interaction.inventory.select import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.wrappers.softFail diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index 167f4c542..4810c7975 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -25,7 +25,6 @@ import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated import net.minecraft.screen.slot.Slot @@ -49,8 +48,8 @@ class AcquireStackTask @Ta5kBuilder internal constructor( override fun SafeContext.onStart() { runSafeAutomated { selection.findContainer() - ?.transferByTask(selection, HotbarContainer) - ?.thenAction { slot -> success(slot) } + ?.let { transfer(selection, it, HotbarContainer) } + ?.onSuccess { slot -> success(slot) } ?.execute(this@AcquireStackTask) ?: failure(ContainerHandler.NoContainerFound(selection)) // ToDo: Create crafting path } diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index 6207e8af2..a32c3974d 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -18,16 +18,18 @@ package com.lambda.task.tasks import com.lambda.context.Automated +import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.ContainerHandler.findContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer +import com.lambda.interaction.inventory.container.OpenedContainerContext import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.tasks.wrappers.thenAction +import com.lambda.task.tasks.wrappers.then import com.lambda.threading.runSafeAutomated import net.minecraft.screen.slot.Slot @@ -36,69 +38,94 @@ context(automated: Automated) fun transfer( stackSelection: StackSelection, fromContainer: Container, - toContainer: Container, - failIfNoStack: Boolean = true -) = ContainerTransferTask(fromContainer, toContainer, stackSelection, failIfNoStack, automated) + toContainer: Container +) = ContainerTransferTask(fromContainer, toContainer, stackSelection, automated) @Ta5kBuilder -context(automated: Automated) @JvmName("transferByStackSelection") +context(automated: Automated) fun transfer( stackSelection: StackSelection, - toContainer: Container, - failIfNoStack: Boolean = true -) = transfer(stackSelection, stackSelection.findContainer() ?: HotbarAndInventoryContainer, toContainer, failIfNoStack) + toContainer: Container +) = transfer(stackSelection, stackSelection.findContainer() ?: HotbarAndInventoryContainer, toContainer) @Ta5kBuilder -context(automated: Automated) @JvmName("transferExt") +context(automated: Automated) fun StackSelection.transferTo( - toContainer: Container, - failIfNoStack: Boolean = true -) = transfer(this, findContainer() ?: HotbarAndInventoryContainer, toContainer, failIfNoStack) + toContainer: Container +) = transfer(this, findContainer() ?: HotbarAndInventoryContainer, toContainer) class ContainerTransferTask @Ta5kBuilder internal constructor( private var fromContainer: Container, private val toContainer: Container, - private val stackSelection: StackSelection, - private val failIfNoStack: Boolean = false, + private val selection: StackSelection, automated: Automated ) : Task(), Automated by automated { - override val name = "Transferring $stackSelection from $fromContainer to $toContainer" + override val name = "Transferring $selection from $fromContainer to $toContainer" - init { + override fun SafeContext.onStart() { listen { runSafeAutomated { - if (fromContainer is ExternalContainer && toContainer is ExternalContainer) { - fromContainer.accessThen( - afterOpen = { - fromContainer.transferByTask(stackSelection, HotbarAndInventoryContainer, failIfNoStack) - } - ) { - HotbarAndInventoryContainer.transferByTask(stackSelection, toContainer, failIfNoStack) - .thenAction { slot -> success(slot) } - }?.execute(this@ContainerTransferTask) - return@listen - } + when { + fromContainer.isAccessed && toContainer.isAccessed -> + TransferTask() + .onSuccess { success(it) } + .execute(this@ContainerTransferTask) - fromContainer.accessThen { - toContainer.accessThen { - TransferTask().thenAction { slot -> - success(slot) - } - } - }?.execute(this@ContainerTransferTask) + fromContainer !is ExternalContainer -> + openTransferClose(toContainer, fromContainer, toContainer) + + toContainer !is ExternalContainer -> + openTransferClose(fromContainer, fromContainer, toContainer) + + else -> + fromContainer + .access() + .then { fromCtx -> + transfer(selection, fromContainer, HotbarAndInventoryContainer) + .then { fromCtx.close() } + } + .then { toContainer.access() } + .then { toCtx -> transferAndClose(toCtx, HotbarAndInventoryContainer, toContainer) } + .execute(this@ContainerTransferTask) + } } } } - private inner class TransferTask : Task() { + /** + * Opens [containerToOpen], transfers [selection] from [from] to [to], then closes the opened container. + * + * Used when exactly one of the two containers is external and needs to be accessed. + */ + private fun openTransferClose(containerToOpen: Container, from: Container, to: Container) { + containerToOpen + .access() + .then { ctx -> + transferAndClose(ctx, from, to) + } + .execute(this@ContainerTransferTask) + } + + /** + * Transfers [selection] from [from] to [to], then closes the container via [ctx]. + */ + private fun transferAndClose(ctx: OpenedContainerContext, from: Container, to: Container) = + transfer(selection, from, to) + .then { slot -> + ctx + .close() + .onSuccess { success(slot) } + } + + private inner class TransferTask @Ta5kBuilder constructor() : Task() { override val name = "Transferring" init { listen { runSafeAutomated { - val (fromSlot, toSlot) = fromContainer.getTransferSlots(stackSelection, toContainer) + val (fromSlot, toSlot) = fromContainer.getTransferSlots(selection, toContainer) if (fromSlot == null) { checkFail() return@listen @@ -107,7 +134,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( failure("Unable to find a slot to transfer to.") return@listen } - val transferSuccessful = fromContainer.transfer(fromSlot, toSlot, toContainer) + val transferSuccessful = fromContainer.swap(fromSlot, toSlot, toContainer) if (transferSuccessful) success(toSlot) else checkFail() } @@ -115,7 +142,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( } private fun checkFail() { - if (failIfNoStack) failure(NoMaterialAccessException(stackSelection)) + failure(NoMaterialAccessException(selection)) } private inner class NoMaterialAccessException(stackSelection: StackSelection) : IllegalStateException("Unable to access $stackSelection.") diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index c68f4ae24..33fa0172e 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -61,8 +61,8 @@ class EatTask @Ta5kBuilder internal constructor( return@listen } - val foodFinder = reason.selector() - val hotbarSlot = foodFinder.filter(HotbarContainer.slots).firstOrNull() + val selection = reason.selector() + val hotbarSlot = selection.bestMatch(HotbarContainer.slots) if (hotbarSlot != null) { val request = hotbarRequest(hotbarSlot.index) { @@ -70,9 +70,10 @@ class EatTask @Ta5kBuilder internal constructor( }.submit() if (!request.done) return@listen } else { - val inventorySlot = foodFinder.filter(InventoryContainer.slots).firstOrNull() - if (inventorySlot != null) runSafeAutomated { - InventoryContainer.transfer(foodFinder, HotbarContainer) + if (InventoryContainer.slots.any { selection.matches(it) }) { + runSafeAutomated { + transfer(selection, InventoryContainer, HotbarContainer) + } } if (holdingUse) { mc.options.useKey.isPressed = false diff --git a/src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt index 7ec969db0..8b755ef92 100644 --- a/src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/FindPlacedBlockTask.kt @@ -27,7 +27,7 @@ import net.minecraft.util.math.BlockPos @Ta5kBuilder fun findBlock(block: Block, searchRadius: Int) = FindPlacedBlockTask(block, searchRadius) -class FindPlacedBlockTask( +class FindPlacedBlockTask @Ta5kBuilder internal constructor( private val block: Block, private val searchRadius: Int ) : Task() { diff --git a/src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt deleted file mode 100644 index c846d40a6..000000000 --- a/src/main/kotlin/com/lambda/task/tasks/wrappers/ResultTasks.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2026 Lambda - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.lambda.task.tasks.wrappers - -import com.lambda.context.SafeContext -import com.lambda.task.Task -import com.lambda.task.Task.Ta5kBuilder - -@Ta5kBuilder -fun successTask(result: R) = - SuccessTask(result) - -@Ta5kBuilder -fun successTask() = successTask(Unit) - -@Ta5kBuilder -fun failureTask(throwable: R) = - FailureTask(throwable) - -@Ta5kBuilder -fun failureTask(cause: String) = - FailureTask(IllegalStateException(cause)) - -class SuccessTask @Ta5kBuilder internal constructor( - val result: R -) : Task() { - override val name = "Success task" - - override fun SafeContext.onStart() { - success(result) - } -} - -class FailureTask @Ta5kBuilder internal constructor( - val throwable: R -) : Task() { - override val name = "Failure task" - - override fun SafeContext.onStart() { - failure(throwable) - } -} \ No newline at end of file From 94536451a11e1e527896d55c05a11d090a844666 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sat, 29 Aug 2026 20:32:47 +0100 Subject: [PATCH 10/18] fix memory leak (?) and general bugs --- .../lambda/mixin/MinecraftClientMixin.java | 1 - .../mixin/entity/ClientPlayerEntityMixin.java | 2 +- .../ClientPlayNetworkHandlerMixin.java | 2 +- .../simulation/sims/InteractSim.kt | 3 +- .../interaction/inventory/StackSelection.kt | 40 +++++++-- .../external/ShulkerBoxContainer.kt | 13 ++- src/main/kotlin/com/lambda/task/Task.kt | 9 +- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 42 +++------ .../com/lambda/task/tasks/CollectDropsTask.kt | 88 +++++++++++++++++++ .../task/tasks/ContainerTransferTask.kt | 15 +--- 10 files changed, 157 insertions(+), 58 deletions(-) create mode 100644 src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt diff --git a/src/main/java/com/lambda/mixin/MinecraftClientMixin.java b/src/main/java/com/lambda/mixin/MinecraftClientMixin.java index 5bd7ef16f..a503297cf 100644 --- a/src/main/java/com/lambda/mixin/MinecraftClientMixin.java +++ b/src/main/java/com/lambda/mixin/MinecraftClientMixin.java @@ -22,7 +22,6 @@ import com.lambda.event.events.*; import com.lambda.gui.DearImGui; import com.lambda.gui.components.ClickGuiLayout; -import com.lambda.interaction.handlers.TimerHandler; import com.lambda.module.modules.movement.BetterFirework; import com.lambda.module.modules.player.Interact; import com.lambda.module.modules.player.InventoryMove; diff --git a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java index e1036c4c3..136c9d2d4 100644 --- a/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java @@ -56,7 +56,7 @@ import java.util.Objects; import static com.lambda.Lambda.getMc; -import static com.lambda.interaction.managers.rotating.Rotation.dist; +import static com.lambda.interaction.manager.managers.rotating.Rotation.dist; @Mixin(value = ClientPlayerEntity.class, priority = Integer.MAX_VALUE) public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity { diff --git a/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java b/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java index 7976b71bf..54a5b4ef3 100644 --- a/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java @@ -24,7 +24,7 @@ import com.lambda.event.events.PlayerEvent; import com.lambda.event.events.WorldEvent; import com.lambda.interaction.manager.managers.inventory.InventoryManager; -import com.lambda.interaction.managers.rotating.RotationManager; +import com.lambda.interaction.manager.managers.rotating.RotationManager; import com.lambda.module.modules.movement.Velocity; import com.lambda.module.modules.render.NoRender; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt index b1b36ef4d..d46136cbe 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt @@ -60,6 +60,7 @@ import net.minecraft.entity.Entity import net.minecraft.item.BlockItem import net.minecraft.item.Item import net.minecraft.item.ItemPlacementContext +import net.minecraft.item.Items import net.minecraft.screen.slot.Slot import net.minecraft.state.property.Properties import net.minecraft.util.Hand @@ -204,7 +205,7 @@ class InteractSim internal constructor(simInfo: InteractSimInfo) supervisorScope.cancel() return null } - val stackSelection = item?.select() + val stackSelection = item?.select(if (item == Items.AIR) 0 else 1) ?: selectStack { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } val containerSelection = selectContainer { ofAnyType(ContainerRank.Hotbar) } val container = stackSelection.findContainers(containerSelection).firstOrNull() ?: run { diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index 2be088cc1..ce1a4f5ae 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -33,6 +33,7 @@ import net.minecraft.item.consume.UseAction import net.minecraft.registry.RegistryKey import net.minecraft.registry.tag.TagKey import net.minecraft.screen.slot.Slot +import net.minecraft.text.Text import java.util.* @ContainerMarker @@ -96,7 +97,7 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { private var item: Item? = null private var stackByRef = false private var itemStack: ItemStack? = null - private var comparator: Comparator> = compareBy { it.stack.count } + private var comparator: Comparator>? = null private var inShulkerBoxesOnly: Boolean = false private var invertNewSelectors = false @@ -132,6 +133,16 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { appendSelector { stack, _ -> !items.contains(stack.item) } } + fun isShulkerBox() { + appendSelector { stack, _ -> stack.item in ItemUtils.shulkerBoxes } + } + + fun hasCustomName(name: Text) { + appendSelector { stack, _ -> + stack.get(DataComponentTypes.CUSTOM_NAME)?.string == name.string + } + } + fun isOneOfStacks(stacks: Collection) { appendSelector { stack, _ -> stacks.contains(stack) } } @@ -217,12 +228,31 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { invertNewSelectors = false } - fun sortedWith(comparator: Comparator>) { - this.comparator = comparator + fun sortedWith(newComparator: Comparator>) { + comparator = comparator?.thenComparing(newComparator) ?: newComparator } fun sortedWith(comparatorSupplier: () -> Comparator>) { - this.comparator = comparatorSupplier() + val newComparator = comparatorSupplier() + comparator = comparator?.thenComparing(newComparator) ?: newComparator + } + + fun sortedByBestContentMatch(expectedContents: List) { + val expectedFrequencies = expectedContents + .filter { !it.isEmpty } + .groupingBy { it.item } + .eachCount() + sortedWith( + compareByDescending { stackAndSlot -> + val currentFrequencies = stackAndSlot.stack.shulkerBoxStacks + .filter { !it.isEmpty } + .groupingBy { it.item } + .eachCount() + expectedFrequencies.asSequence().fold(0) { acc, (item, count) -> + acc + minOf(count, currentFrequencies[item] ?: 0) + } + } + ) } @PublishedApi @@ -240,7 +270,7 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { item, itemStack, inShulkerBoxesOnly, - comparator, + comparator ?: compareBy { it.stack.count }, selector ) diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index 3d666905f..78030e4cf 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -42,6 +42,7 @@ import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted import com.lambda.util.text.literal +import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import net.minecraft.block.entity.ShulkerBoxBlockEntity import net.minecraft.item.ItemStack import net.minecraft.screen.ScreenHandlerType @@ -102,15 +103,23 @@ data class ShulkerBoxContainer( val blockPos: BlockPos, val fromContainer: Container ) : OpenedContainerContext { + private val shulkerItem = slotCache.stack.item + private val customName = slotCache.stack.get(net.minecraft.component.DataComponentTypes.CUSTOM_NAME) + private val originalContents = slotCache.stack.shulkerBoxStacks + context(automated: Automated) override fun close() = taskOrNull { if (!isAccessed) null else actionTask { player.closeScreen() } }.then { breakAndCollect(blockPos) } - .then { slot -> + .then { transfer( - selectStack { isSlot(slot) }, + selectStack { + isItem(shulkerItem) + if (customName != null) hasCustomName(customName) + sortedByBestContentMatch(originalContents) + }, HotbarAndInventoryContainer, fromContainer ) diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index 8aaba1110..3ae287ed5 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -36,7 +36,6 @@ import kotlin.time.toDuration @Suppress("unused") abstract class Task : Nameable, Muteable { var parent: Task<*>? = null - var parentPausing = false val subTasks = mutableListOf>() var state = State.Init override val isMuted: Boolean get() = state == State.Paused || state == State.Init @@ -118,7 +117,6 @@ abstract class Task : Nameable, Muteable { parent = owner if (verboseDebug) LOG.info("${owner.name} started $name") if (pauseParent) { - parentPausing = true if (verboseDebug) LOG.info("$name pausing parent ${owner.name}") if (owner !is RootTask) owner.pause() } @@ -131,7 +129,6 @@ abstract class Task : Nameable, Muteable { protected fun success(result: Result) { unsubscribe() state = State.Completed - parent?.subTasks?.remove(this) parent?.onSubTaskSuccess(this) parent?.onSubTaskCompletion(this) @@ -140,6 +137,8 @@ abstract class Task : Nameable, Muteable { successCallbacks.forEach { it.invoke(this, result) } completionCallbacks.forEach { it.invoke(this) } } + + parent?.subTasks?.remove(this) } @Ta5kBuilder @@ -176,6 +175,8 @@ abstract class Task : Nameable, Muteable { failureCallbacks.forEach { it.invoke(this, e) } completionCallbacks.forEach { it.invoke(this) } } + + parent?.subTasks?.remove(this) } @Ta5kBuilder @@ -201,7 +202,7 @@ abstract class Task : Nameable, Muteable { runSafe { onCancel() } cancelSubTasks() if (removeFromParent) parent?.subTasks?.remove(this) - if (parentPausing) parent?.activate() + parent?.activate() if (this is RootTask) return if (state == State.Completed || state == State.Cancelled) return state = State.Cancelled diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index 5053c5649..fc6ee0651 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -17,7 +17,6 @@ package com.lambda.task.tasks -import baritone.api.pathing.goals.GoalBlock import com.lambda.Lambda.LOG import com.lambda.config.blocks.EatConfig.Companion.reasonEating import com.lambda.context.Automated @@ -47,10 +46,8 @@ import com.lambda.interaction.construction.simulation.result.results.PreSimResul import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.manager.managers.breaking.breakRequest import com.lambda.interaction.manager.managers.interacting.interactRequest -import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.modules.client.Client import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder @@ -63,7 +60,6 @@ import com.lambda.util.EntityUtils.getClosestPointTo import com.lambda.util.EntityUtils.getPositionsWithinBox import com.lambda.util.FormattingUtils.format import com.lambda.util.extension.Structure -import com.lambda.util.extension.playerSlots import com.lambda.util.math.dist import kotlinx.coroutines.Job import kotlinx.coroutines.runBlocking @@ -141,6 +137,7 @@ class BuildTask @Ta5kBuilder internal constructor( private var breaks = 0 private val dropsToCollect = mutableSetOf() var eatTask: Task<*>? = null + var collectDropsTask: Task<*>? = null private val onItemDrop: ((item: ItemEntity) -> Unit)? get() = if (collectDrops) { item -> @@ -354,34 +351,15 @@ class BuildTask @Ta5kBuilder internal constructor( } } - private fun SafeContext.collectDrops() = - dropsToCollect - .firstOrNull() - ?.let { itemDrop -> - if (pendingInteractions.isNotEmpty()) return@let true - - if (!world.entities.contains(itemDrop)) { - dropsToCollect.remove(itemDrop) - BaritoneHandler.cancel() - return@let true - } - - if (HotbarAndInventoryContainer.stacks.none { it.isEmpty }) { - val stackToThrow = player.currentScreenHandler.playerSlots.firstOrNull { - it.stack.item in inventoryConfig.disposables - } ?: run { - failure("No item in inventory to throw but inventory is full and cant pick up item drop") - return@let true - } - inventoryRequest { - throwStack(stackToThrow.id) - }.submit() - return@let true - } - - BaritoneHandler.setGoalAndPath(GoalBlock(itemDrop.blockPos)) - true - } ?: false + private fun AutomatedSafeContext.collectDrops(): Boolean { + if (dropsToCollect.isEmpty()) return false + if (pendingInteractions.isNotEmpty()) return true + if (collectDropsTask != null) return true + collectDropsTask = collectDrops(dropsToCollect) + .thenAction { collectDropsTask = null } + .execute(this@BuildTask) + return true + } private fun iteratePropagating() = if (blueprint is PropagatingBlueprint) { diff --git a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt new file mode 100644 index 000000000..a3e7f5c45 --- /dev/null +++ b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt @@ -0,0 +1,88 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.task.tasks + +import baritone.api.pathing.goals.GoalBlock +import com.lambda.context.Automated +import com.lambda.context.SafeContext +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.task.Task +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.threading.runSafeAutomated +import com.lambda.util.extension.playerSlots +import net.minecraft.entity.ItemEntity + +@Ta5kBuilder +context(automated: Automated) +fun collectDrops(drops: MutableSet) = CollectDropsTask(drops, automated) + +/** + * A task that collects a set of item entity drops by walking to them. + * + * Items are considered collected when they despawn from the world (picked up by the player). + * If inventory is full, disposable items are thrown to make space. + * + * Succeeds when all drops have been collected. + */ +class CollectDropsTask @Ta5kBuilder internal constructor( + private val drops: MutableSet, + automated: Automated +) : Task(), Automated by automated { + override val name get() = "Collecting ${drops.size} item drop(s)" + + override fun SafeContext.onStart() { + listen { + runSafeAutomated { + val target = drops.firstOrNull() ?: run { + BaritoneHandler.cancel() + success() + return@listen + } + + if (!world.entities.contains(target)) { + drops.remove(target) + BaritoneHandler.cancel() + return@listen + } + + if (HotbarAndInventoryContainer.stacks.none { it.isEmpty }) { + val stackToThrow = player.currentScreenHandler.playerSlots.firstOrNull { + it.stack.item in inventoryConfig.disposables + } ?: run { + failure("Inventory is full and no disposable items to throw") + return@listen + } + inventoryRequest { + throwStack(stackToThrow.id) + }.submit() + return@listen + } + + BaritoneHandler.setGoalAndPath(GoalBlock(target.blockPos)) + } + } + } + + override fun SafeContext.onCancel() { + BaritoneHandler.cancel() + } +} diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index a32c3974d..52a667374 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -18,7 +18,6 @@ package com.lambda.task.tasks import com.lambda.context.Automated -import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.ContainerHandler.findContainer @@ -64,14 +63,13 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( ) : Task(), Automated by automated { override val name = "Transferring $selection from $fromContainer to $toContainer" - override fun SafeContext.onStart() { + init { listen { runSafeAutomated { when { fromContainer.isAccessed && toContainer.isAccessed -> TransferTask() .onSuccess { success(it) } - .execute(this@ContainerTransferTask) fromContainer !is ExternalContainer -> openTransferClose(toContainer, fromContainer, toContainer) @@ -88,8 +86,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( } .then { toContainer.access() } .then { toCtx -> transferAndClose(toCtx, HotbarAndInventoryContainer, toContainer) } - .execute(this@ContainerTransferTask) - } + }.execute(this@ContainerTransferTask) } } } @@ -99,14 +96,10 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( * * Used when exactly one of the two containers is external and needs to be accessed. */ - private fun openTransferClose(containerToOpen: Container, from: Container, to: Container) { + private fun openTransferClose(containerToOpen: Container, from: Container, to: Container) = containerToOpen .access() - .then { ctx -> - transferAndClose(ctx, from, to) - } - .execute(this@ContainerTransferTask) - } + .then { ctx -> transferAndClose(ctx, from, to) } /** * Transfers [selection] from [from] to [to], then closes the container via [ctx]. From ccd3a089c7cce47a6014ca2f02bc601b5d78f95c Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Tue, 1 Sep 2026 00:33:28 +0100 Subject: [PATCH 11/18] better container caching, etc --- .../lambda/mixin/MinecraftClientMixin.java | 2 +- .../lambda/command/commands/BuildCommand.kt | 8 +- .../command/commands/TransferCommand.kt | 8 +- .../construction/blueprint/StaticBlueprint.kt | 6 +- .../simulation/result/Resolvable.kt | 6 +- .../simulation/result/results/BreakResult.kt | 11 +- .../result/results/GenericResult.kt | 11 +- .../construction/simulation/sims/BreakSim.kt | 2 +- .../simulation/sims/InteractSim.kt | 2 +- .../construction/verify/TargetState.kt | 2 +- .../handler/handlers/ContainerHandler.kt | 302 ++++++++++++------ .../handlers/breaking/BrokenBlockHandler.kt | 2 +- .../handlers/breaking/RebreakHandler.kt | 14 +- .../handlers/breaking/RebreakResult.kt | 2 +- .../interacting/InteractedBlockHandler.kt | 2 +- .../handlers/packet/PacketLimitHandler.kt | 2 +- .../interaction/inventory/StackSelection.kt | 12 +- .../inventory/container/Container.kt | 4 +- .../inventory/container/NestedContainer.kt | 7 +- .../inventory/container/OpenContainerTask.kt | 2 +- .../container/OpenedContainerContext.kt | 8 +- .../inventory/container/PlacedContainer.kt | 6 +- .../containers/external/ChestContainer.kt | 42 +-- .../external/DoubleChestContainer.kt | 95 ++++++ .../external/EnderChestContainer.kt | 45 ++- .../external/PlacedShulkerBoxContainer.kt | 26 +- .../external/ShulkerBoxContainer.kt | 47 ++- .../manager/managers/breaking/BreakInfo.kt | 6 +- .../module/modules/combat/CrystalAura.kt | 2 +- .../module/modules/combat/PlayerTrap.kt | 5 +- .../lambda/module/modules/combat/Surround.kt | 5 +- .../module/modules/debug/ContainerTest.kt | 7 +- .../lambda/module/modules/player/AutoEat.kt | 6 +- .../module/modules/player/InventoryTweaks.kt | 87 +++-- .../lambda/module/modules/world/AutoPortal.kt | 8 +- .../module/modules/world/AutoVillagerCycle.kt | 8 +- .../module/modules/world/HighwayTools.kt | 4 +- .../com/lambda/module/modules/world/Nuker.kt | 4 +- .../lambda/module/modules/world/Printer.kt | 5 +- .../lambda/module/modules/world/StashMover.kt | 4 +- src/main/kotlin/com/lambda/task/RootTask.kt | 19 +- src/main/kotlin/com/lambda/task/Task.kt | 63 ++-- .../task/tasks/AcquirePlacedBlockTask.kt | 2 +- .../com/lambda/task/tasks/AcquireStackTask.kt | 9 +- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 5 +- .../com/lambda/task/tasks/CollectDropsTask.kt | 24 +- .../task/tasks/ContainerTransferTask.kt | 64 ++-- .../lambda/task/tasks/PlaceContainerTask.kt | 7 +- src/main/kotlin/com/lambda/util/BlockUtils.kt | 5 +- .../com/lambda/util/player/SlotUtils.kt | 8 +- 50 files changed, 632 insertions(+), 401 deletions(-) create mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/DoubleChestContainer.kt diff --git a/src/main/java/com/lambda/mixin/MinecraftClientMixin.java b/src/main/java/com/lambda/mixin/MinecraftClientMixin.java index a503297cf..fe7c740ae 100644 --- a/src/main/java/com/lambda/mixin/MinecraftClientMixin.java +++ b/src/main/java/com/lambda/mixin/MinecraftClientMixin.java @@ -141,7 +141,7 @@ private void onScreenOpen(@Nullable Screen screen, CallbackInfo ci) { } } - @Inject(method = "setScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;removed()V", shift = At.Shift.AFTER)) + @Inject(method = "setScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;removed()V", shift = At.Shift.BEFORE)) private void onScreenRemove(@Nullable Screen screen, CallbackInfo ci) { if (currentScreen == null) return; if (currentScreen instanceof ScreenHandlerProvider handledScreen) { diff --git a/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt b/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt index 71f458664..ccd2212ab 100644 --- a/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt @@ -28,8 +28,8 @@ import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig import com.lambda.interaction.construction.StructureRegistry import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure -import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint -import com.lambda.task.RootTask.run +import com.lambda.interaction.construction.blueprint.toBlueprint +import com.lambda.task.start import com.lambda.task.tasks.BuildTask import com.lambda.task.tasks.build import com.lambda.threading.runSafe @@ -62,12 +62,12 @@ object BuildCommand : LambdaCommand( .loadStructureByRelativePath(Path.of(pathString)) .let { template -> info("Building structure $pathString with dimensions ${template.size.toShortString()} created by ${template.author}") - lastBuildTask = with(AutomationConfig.Companion.DEFAULT) { + lastBuildTask = with(AutomationConfig.DEFAULT) { template.toStructure() .move(player.blockPos) .toBlueprint() .build() - .run() + .start() } return@executeWithResult success() diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index 949724141..0e0d4babb 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -29,11 +29,11 @@ import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig import com.lambda.interaction.handler.handlers.ContainerHandler -import com.lambda.interaction.handler.handlers.ContainerHandler.findContainers -import com.lambda.interaction.handler.handlers.ContainerHandler.findContainersWithSpace +import com.lambda.interaction.handler.handlers.findContainers +import com.lambda.interaction.handler.handlers.findContainersWithSpace import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.task.RootTask import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.transfer import com.lambda.threading.runSafeAutomated import com.lambda.util.CommunicationUtils.info @@ -106,7 +106,7 @@ object TransferCommand : LambdaCommand( } ?: return@executeWithResult failure("To container not found") transfer(selection, fromContainer, toContainer) - .execute(RootTask) + .start() } return@executeWithResult success() } diff --git a/src/main/kotlin/com/lambda/interaction/construction/blueprint/StaticBlueprint.kt b/src/main/kotlin/com/lambda/interaction/construction/blueprint/StaticBlueprint.kt index f06de623e..f5e6e3176 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/blueprint/StaticBlueprint.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/blueprint/StaticBlueprint.kt @@ -23,8 +23,6 @@ data class StaticBlueprint( override val structure: Structure, ) : Blueprint() { override fun toString() = "Static Blueprint at ${center?.toShortString()}" - - companion object { - fun Structure.toBlueprint() = StaticBlueprint(this) - } } + +fun Structure.toBlueprint() = StaticBlueprint(this) diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Resolvable.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Resolvable.kt index 533123ef0..496faa8cc 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Resolvable.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/Resolvable.kt @@ -17,13 +17,13 @@ package com.lambda.interaction.construction.simulation.result -import com.lambda.context.AutomatedSafeContext +import com.lambda.context.Automated import com.lambda.task.Task /** * Represents a [BuildResult] with a resolvable [Task] */ interface Resolvable { - context(task: Task<*>, _: AutomatedSafeContext) - fun resolve() + context(_: Automated) + fun resolve(): Task<*> } diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 913060307..769f2b102 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.construction.simulation.result.results import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalInverted -import com.lambda.context.AutomatedSafeContext +import com.lambda.context.Automated import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.util.DirectionMask.mask import com.lambda.interaction.construction.simulation.context.BreakContext @@ -34,9 +34,7 @@ import com.lambda.interaction.construction.simulation.result.Resolvable import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.task.Task import com.lambda.task.tasks.transferTo -import com.lambda.task.tasks.wrappers.softFail import net.minecraft.block.BlockState import net.minecraft.item.Item import net.minecraft.util.math.BlockPos @@ -118,13 +116,10 @@ sealed class BreakResult : BuildResult() { ) : Resolvable, BreakResult() { override val rank = Rank.BreakItemCantMine - context(task: Task<*>, _: AutomatedSafeContext) - override fun resolve() { + context(_: Automated) + override fun resolve() = selectStack { inverted { isItem(badItem) } } .transferTo(HotbarContainer) - .softFail() - .execute(task) - } override fun compareResult(other: ComparableResult) = when (other) { diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index ed5b54356..69dc06081 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -18,7 +18,7 @@ package com.lambda.interaction.construction.simulation.result.results import baritone.api.pathing.goals.GoalNear -import com.lambda.context.AutomatedSafeContext +import com.lambda.context.Automated import com.lambda.graphics.mc.RenderBuilder import com.lambda.interaction.construction.simulation.result.BuildResult import com.lambda.interaction.construction.simulation.result.ComparableResult @@ -29,9 +29,7 @@ import com.lambda.interaction.construction.simulation.result.Resolvable import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.task.Task import com.lambda.task.tasks.transferTo -import com.lambda.task.tasks.wrappers.softFail import net.minecraft.client.data.TextureMap.side import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos @@ -99,13 +97,10 @@ sealed class GenericResult : BuildResult() { override val rank = Rank.WrongItem private val color = Color(3, 252, 169, 25) - context(task: Task<*>, _: AutomatedSafeContext) - override fun resolve() { + context(_: Automated) + override fun resolve() = neededSelection .transferTo(HotbarContainer) - .softFail() - .execute(task) - } override fun RenderBuilder.render() { val center = pos.toCenterPos() diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt index 74741cd17..6c179d68c 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt @@ -28,7 +28,7 @@ import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handler.handlers.ContainerHandler.findContainers +import com.lambda.interaction.handler.handlers.findContainers import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackAndSlot import com.lambda.interaction.inventory.StackSelection diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt index d46136cbe..10d9b0629 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt @@ -27,7 +27,7 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.handler.handlers.ContainerHandler.findContainers +import com.lambda.interaction.handler.handlers.findContainers import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.ContainerRank diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index f6ccb54ee..cf594ccb8 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.construction.verify import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext -import com.lambda.interaction.handler.handlers.ContainerHandler.findDisposable +import com.lambda.interaction.handler.handlers.findDisposable import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.emptyState import com.lambda.util.BlockUtils.isEmpty diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index 39fb480a7..ced2c4d1c 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -19,147 +19,271 @@ package com.lambda.interaction.handler.handlers import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext +import com.lambda.context.SafeContext import com.lambda.core.Loadable import com.lambda.event.events.InventoryEvent -import com.lambda.event.events.PlayerEvent +import com.lambda.event.events.PacketEvent +import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.handler.handlers.ContainerHandler.filteredContainers import com.lambda.interaction.inventory.ContainerMarker import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.inventory.container.NestedContainer +import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.interaction.inventory.container.containers.external.ChestContainer +import com.lambda.interaction.inventory.container.containers.external.DoubleChestContainer import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer +import com.lambda.interaction.inventory.container.containers.external.PlacedShulkerBoxContainer +import com.lambda.interaction.inventory.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.inventory.select import com.lambda.util.BlockUtils.blockEntity +import com.lambda.util.BlockUtils.blockState import com.lambda.util.ReflectionUtils.getInstances import com.lambda.util.extension.containerStacks +import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks +import com.lambda.util.item.ItemUtils.shulkerBoxes +import com.lambda.util.player.SlotUtils.typeSafe +import net.minecraft.block.ChestBlock import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.block.entity.EnderChestBlockEntity -import net.minecraft.screen.GenericContainerScreenHandler +import net.minecraft.block.entity.ShulkerBoxBlockEntity +import net.minecraft.block.enums.ChestType +import net.minecraft.inventory.Inventory +import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket +import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType +import net.minecraft.state.property.Properties +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.ChunkPos -// ToDo: Make this a Configurable to save container caches. Should use a cached region based storage system. @Suppress("unused") object ContainerHandler : Loadable { private val containers: Sequence - get() = compileContainers.asSequence() + runtimeContainers + get() = compileContainers.asSequence() + + placedContainers.values.asSequence().flatMap { it.values } + + storedContainers.values.asSequence().flatMap { it.values } - private val compileContainers = getInstances() - private val runtimeContainers = mutableSetOf() + val compileContainers = getInstances() + val placedContainers = mutableMapOf>() + val storedContainers = mutableMapOf>() context(automated: Automated) val filteredContainers - get() = - containers - .filter { automated.inventoryConfig.containerSelection.matches(it) } - .sorted() + get() = containers + .filter { automated.inventoryConfig.containerSelection.matches(it) } + .sorted() val allContainers - get() = - containers - .sorted() + get() = containers.sorted() var lastInteractedBlockEntity: BlockEntity? = null override fun load() = "Loaded ${compileContainers.size} containers" init { - listen { - lastInteractedBlockEntity = blockEntity(it.blockHitResult.blockPos) + listen { event -> + val packet = event.packet as? PlayerInteractBlockC2SPacket ?: return@listen + lastInteractedBlockEntity = blockEntity(packet.blockHitResult.blockPos) } listen { event -> - if (event.screenHandler !is GenericContainerScreenHandler) return@listen + val sh = event.screenHandler + onContainerUpdate(sh) + if (sh.syncId != 0) lastInteractedBlockEntity = null + } + listen { onContainerUpdate() } + listen { onContainerUpdate() } + + listen { event -> + val pos = event.pos + val containersInChunk = placedContainers[ChunkPos(pos)] ?: return@listen + val cachedContainer = containersInChunk[pos] ?: return@listen + val currentState = blockState(cachedContainer.pos) + if (currentState.block != event.newState.block) { + containersInChunk.remove(pos) + } + } - val handler = event.screenHandler + listen { event -> + val chunk = event.chunk + val cachedContainers = placedContainers[chunk.pos] ?: return@listen + cachedContainers.values.retainAll { container -> + val matchingEntity = chunk.blockEntities[container.pos] ?: return@retainAll false + blockState(container.pos).block == matchingEntity.cachedState.block + } + } + } - when (val block = lastInteractedBlockEntity) { - is EnderChestBlockEntity -> { - if (handler.type != ScreenHandlerType.GENERIC_9X3) return@listen + private fun SafeContext.onContainerUpdate(sh: ScreenHandler = player.currentScreenHandler) { + val blockEntity = lastInteractedBlockEntity + if (blockEntity != null) updatePlacedContainer(sh, blockEntity) + } - EnderChestContainer.update(handler.containerStacks) + private fun updatePlacedContainer( + sh: ScreenHandler, + blockEntity: BlockEntity + ) { + val pos = blockEntity.pos + when (blockEntity) { + is EnderChestBlockEntity -> { + if (sh.typeSafe != ScreenHandlerType.GENERIC_9X3) return + EnderChestContainer.apply { + update(sh.containerStacks) + scanContainerContents() } + } + + is ChestBlockEntity -> { + val state = blockEntity.cachedState + if (state.block !is ChestBlock) return + + val stacks = blockEntity.stacks + val chestType = state.get(Properties.CHEST_TYPE) ?: return + val chunkPos = ChunkPos(pos) + + if (chestType == ChestType.SINGLE) { + if (sh.typeSafe != ScreenHandlerType.GENERIC_9X3) return + (chunkPos.getPlacedContainer(pos) as? ChestContainer) + ?.update(stacks) + ?: run { chunkPos.setPlacedContainer(pos, ChestContainer(pos, stacks)) } + } else { + if (sh.typeSafe != ScreenHandlerType.GENERIC_9X6) return + val facing = state.get(Properties.HORIZONTAL_FACING) ?: return + val otherPos = + when (chestType) { + ChestType.LEFT -> pos.offset(facing.rotateYClockwise()) + ChestType.RIGHT -> pos.offset(facing.rotateYCounterclockwise()) + } + val leftPos = if (chestType == ChestType.LEFT) pos else otherPos + val leftChunkPos = ChunkPos(leftPos) + val rightPos = if (chestType == ChestType.RIGHT) pos else otherPos + val rightChunkPos = ChunkPos(rightPos) - is ChestBlockEntity -> { - // ToDo: Handle double chests and single chests - if (handler.type != ScreenHandlerType.GENERIC_9X6) return@listen - val stacks = handler.containerStacks + val existing = (leftChunkPos.getPlacedContainer(leftPos) as? DoubleChestContainer) + ?: (rightChunkPos.getPlacedContainer(rightPos) as? DoubleChestContainer) - containers - .filterIsInstance() - .find { - it.blockPos == block.pos - }?.update(stacks) ?: runtimeContainers.add(ChestContainer(block.pos, stacks)) + if (existing != null) { + existing.update(stacks) + leftChunkPos.setPlacedContainer(leftPos, existing) + rightChunkPos.setPlacedContainer(rightPos, existing) + } else { + val doubleChest = DoubleChestContainer(pos, leftPos, rightPos, stacks) + leftChunkPos.setPlacedContainer(leftPos, doubleChest) + rightChunkPos.setPlacedContainer(rightPos, doubleChest) + } } + + chunkPos.getPlacedContainer(pos)?.scanContainerContents() + } + + is ShulkerBoxBlockEntity -> { + if (sh.typeSafe != ScreenHandlerType.SHULKER_BOX) return + val stacks = blockEntity.stacks + val chunkPos = ChunkPos(pos) + (chunkPos.getPlacedContainer(pos) as? PlacedShulkerBoxContainer) + ?.update(stacks) + ?: run { + chunkPos.setPlacedContainer( + pos, + PlacedShulkerBoxContainer(pos, blockEntity.cachedState.block, null, stacks) + ) + } + + chunkPos.getPlacedContainer(pos)?.scanContainerContents() } - lastInteractedBlockEntity = null } } - @ContainerMarker - context(automatedSafeContext: AutomatedSafeContext) - fun StackSelection.move(destination: Container) = - with(automatedSafeContext) { - findContainer(inventoryConfig.containerSelection) - ?.move(this@move, destination) - ?: false + private fun Container.scanContainerContents() { + val storageCache = storedContainers.getOrPut(this) { mutableMapOf() } + slots.forEach { slot -> + val stack = slot.stack + val index = slot.index + if (stack.item in shulkerBoxes) { + storageCache[index] = + ShulkerBoxContainer( + stack.name.string, + stack.item, + stack.shulkerBoxStacks, + this, + index + ).also { it.scanContainerContents() } + } else storageCache.remove(index) } + } - @ContainerMarker - context(_: Automated) - fun findContainer(block: (Container) -> Boolean) = filteredContainers.find(block) + private fun getPlacedContainer(pos: BlockPos) = placedContainers[ChunkPos(pos)]?.get(pos) + private fun ChunkPos.getPlacedContainer(pos: BlockPos) = placedContainers[this]?.get(pos) + private fun setPlacedContainer(pos: BlockPos, container: PlacedContainer) = + placedContainers.getOrPut(ChunkPos(pos)) { mutableMapOf() }.put(pos, container) + private fun ChunkPos.setPlacedContainer(pos: BlockPos, container: PlacedContainer) = + placedContainers.getOrPut(this) { mutableMapOf() }.put(pos, container) - @ContainerMarker - context(automated: Automated) - fun StackSelection.findContainer( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection - ) = findContainers(containerSelection).firstOrNull() + private val Inventory.stacks + get() = iterator().asSequence().toList() +} - @ContainerMarker - context(automated: Automated) - fun StackSelection.findContainers( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection - ) = - filteredContainers - .filter { containerSelection.matches(it) } - .filter { it.stackCount(this) >= count } - .sortedWith(automated.inventoryConfig.accessPriority.materialComparator(this)) - - @ContainerMarker - context(automated: Automated) - fun StackSelection.findContainerWithSpace( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection - ) = findContainersWithSpace(containerSelection).firstOrNull() +@ContainerMarker +context(automatedSafeContext: AutomatedSafeContext) +fun StackSelection.move(destination: Container) = + with(automatedSafeContext) { + findContainer(inventoryConfig.containerSelection) + ?.move(this@move, destination) + ?: false + } - @ContainerMarker - context(automated: Automated) - fun StackSelection.findContainersWithSpace( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection - ) = - filteredContainers - .filter { containerSelection.matches(it) } - .filter { it.spaceAvailable(this) >= count } - .sortedWith(automated.inventoryConfig.accessPriority.spaceComparator(this)) - - @ContainerMarker - context(automated: Automated) - fun StackSelection.findSlot( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection - ) = findSlots(containerSelection).firstOrNull() +@ContainerMarker +context(_: Automated) +fun findContainer(predicate: (Container) -> Boolean) = filteredContainers.find(predicate) - @ContainerMarker - context(automated: Automated) - fun StackSelection.findSlots( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection - ) = findContainers(containerSelection).flatMap { filter(it.slots) } +@ContainerMarker +context(automated: Automated) +fun StackSelection.findContainer( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection +) = findContainers(containerSelection).firstOrNull() - @ContainerMarker - context(automated: Automated) - fun findDisposable() = - filteredContainers.find { container -> - automated.inventoryConfig.disposables.any { container.stackCount(it.asItem().select(1)) > 0 } - } +@ContainerMarker +context(automated: Automated) +fun StackSelection.findContainers( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection +) = filteredContainers + .filter { containerSelection.matches(it) } + .filter { it.stackCount(this) >= count } + .sortedWith(automated.inventoryConfig.accessPriority.materialComparator(this)) + +@ContainerMarker +context(automated: Automated) +fun StackSelection.findContainerWithSpace( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection +) = findContainersWithSpace(containerSelection).firstOrNull() + +@ContainerMarker +context(automated: Automated) +fun StackSelection.findContainersWithSpace( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection +) = filteredContainers + .filter { containerSelection.matches(it) } + .filter { it.spaceAvailable(this) >= count } + .sortedWith(automated.inventoryConfig.accessPriority.spaceComparator(this)) + +@ContainerMarker +context(automated: Automated) +fun StackSelection.findSlot( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection +) = findSlots(containerSelection).firstOrNull() + +@ContainerMarker +context(automated: Automated) +fun StackSelection.findSlots( + containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection +) = findContainers(containerSelection).flatMap { filter(it.slots) } - class NoContainerFound(selection: StackSelection) : Exception("No container found matching $selection") -} \ No newline at end of file +@ContainerMarker +context(automated: Automated) +fun findDisposable() = + filteredContainers.find { container -> + automated.inventoryConfig.disposables.any { container.stackCount(it.asItem().select(1)) > 0 } + } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt index 681358860..bd1241726 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/BrokenBlockHandler.kt @@ -51,7 +51,7 @@ import net.minecraft.util.math.ChunkSectionPos * * @see com.lambda.interaction.managers.breaking.BreakManager */ -object BrokenBlockHandler : PostActionHandler() { +internal object BrokenBlockHandler : PostActionHandler() { override val pendingActions = LimitedDecayQueue( DEFAULT.buildConfig.maxPendingActions, DEFAULT.buildConfig.actionTimeout * 50L ) { info -> diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt index 84c82a11f..5817eb84c 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt @@ -40,7 +40,7 @@ import net.minecraft.util.Hand * Designed to track the latest primary-broken [BreakInfo] in order to exploit a flaw in Minecraft's code that allows * the user to break any block placed in said position using the progress from the previously broken block. */ -object RebreakHandler { +internal object RebreakHandler { var reBreak: BreakInfo? = null init { @@ -134,12 +134,12 @@ object RebreakHandler { RebreakResult.StillBreaking(reBreak) } } +} - enum class RebreakPotential { - Instant, - PartialProgress, - None; +enum class RebreakPotential { + Instant, + PartialProgress, + None; - fun isPossible() = this != None - } + fun isPossible() = this != None } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakResult.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakResult.kt index c98b4a6bf..67982cf31 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakResult.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.handler.handlers.breaking import com.lambda.interaction.manager.managers.breaking.BreakInfo -sealed class RebreakResult { +internal sealed class RebreakResult { data object Ignored : RebreakResult() data object Rebroke : RebreakResult() diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt index 59aeaa843..b5dc73358 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt @@ -30,7 +30,7 @@ import com.lambda.util.BlockUtils.matches import com.lambda.util.CommunicationUtils.warn import com.lambda.util.collections.LimitedDecayQueue -object InteractedBlockHandler : PostActionHandler() { +internal object InteractedBlockHandler : PostActionHandler() { override val pendingActions = LimitedDecayQueue( AutomationConfig.DEFAULT.buildConfig.maxPendingActions, AutomationConfig.DEFAULT.buildConfig.actionTimeout * 50L diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt index 2b6fdf428..6229e1e29 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt @@ -26,7 +26,7 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import kotlin.time.TimeSource -object PacketLimitHandler { +internal object PacketLimitHandler { private val packetLimitMap = PacketType.entries.associateWith { LimitHandler() } init { diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt index ce1a4f5ae..9e27c08fd 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt @@ -33,7 +33,6 @@ import net.minecraft.item.consume.UseAction import net.minecraft.registry.RegistryKey import net.minecraft.registry.tag.TagKey import net.minecraft.screen.slot.Slot -import net.minecraft.text.Text import java.util.* @ContainerMarker @@ -137,9 +136,9 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { appendSelector { stack, _ -> stack.item in ItemUtils.shulkerBoxes } } - fun hasCustomName(name: Text) { + fun hasCustomName(name: String) { appendSelector { stack, _ -> - stack.get(DataComponentTypes.CUSTOM_NAME)?.string == name.string + stack.name.string == name } } @@ -218,6 +217,10 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { appendSelector { _, s -> s === slot } } + fun inIndex(index: Int) { + appendSelector { _, s -> s?.index == index } + } + fun custom(predicate: (ItemStack, Slot?) -> Boolean) { appendSelector { stack, slot -> predicate(stack, slot) } } @@ -233,8 +236,7 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { } fun sortedWith(comparatorSupplier: () -> Comparator>) { - val newComparator = comparatorSupplier() - comparator = comparator?.thenComparing(newComparator) ?: newComparator + sortedWith(comparatorSupplier()) } fun sortedByBestContentMatch(expectedContents: List) { diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index 58563fbcf..c652128ef 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -47,7 +47,7 @@ abstract class Container( val rank: ContainerRank ) : Nameable, Comparable { override val name: String - get() = buildText { text(description) }.string + get() = description.string abstract val slots: List abstract var stacks: List @@ -101,7 +101,7 @@ abstract class Container( @Ta5kBuilder context(automated: Automated) - open fun access(): OpenContainerTask<*> = + open fun access(): OpenContainerTask<*>? = PlayerOpenContainerTask(description, ::isAccessed) context(automatedSafeContext: AutomatedSafeContext) diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt index 67f861999..039fe429f 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt @@ -17,8 +17,7 @@ package com.lambda.interaction.inventory.container -import net.minecraft.screen.slot.Slot - -interface NestedContainer { - val slotCache: Slot? +abstract class NestedContainer(rank: ContainerRank) : Container(rank) { + abstract val containedIn: Container + abstract val index: Int } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt index 2954b10a3..e871641fa 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt @@ -23,7 +23,7 @@ import net.minecraft.text.Text abstract class OpenContainerTask @Ta5kBuilder internal constructor( description: Text -) : Task() { +) : Task() { override val name = "accessing container: ${description.string}" } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt index 7b25339e1..a58ba8990 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt @@ -25,7 +25,7 @@ import com.lambda.task.tasks.wrappers.actionTask interface OpenedContainerContext { @Ta5kBuilder context(automated: Automated) - fun close(): Task<*> + fun close(): Task<*>? } open class BasicOpenedContainerContext( @@ -33,8 +33,6 @@ open class BasicOpenedContainerContext( ) : OpenedContainerContext { context(_: Automated) final override fun close() = - actionTask { - if (!isAccessed()) return@actionTask - player.closeScreen() - } + if (!isAccessed()) null + else actionTask { player.closeScreen() } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt index 7d6d9d051..85ab71da3 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt @@ -18,7 +18,9 @@ package com.lambda.interaction.inventory.container import com.lambda.interaction.inventory.container.containers.external.StashContainer +import net.minecraft.util.math.BlockPos -interface PlacedContainer { - val stash: StashContainer? +abstract class PlacedContainer(rank: ContainerRank) : Container(rank), ExternalContainer { + abstract val pos: BlockPos + abstract val stash: StashContainer? } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt index 06d553d15..abdb79b94 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt @@ -22,42 +22,37 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.BasicOpenedContainerContext -import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.inventory.container.ExternalContainer import com.lambda.interaction.inventory.container.OpenContainerTask +import com.lambda.interaction.inventory.container.OpenedContainerContext import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.openContainer -import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.util.extension.containerSlots +import com.lambda.util.player.SlotUtils.typeSafe import com.lambda.util.text.buildText import com.lambda.util.text.highlighted import com.lambda.util.text.literal import net.minecraft.block.ChestBlock -import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.item.ItemStack import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos data class ChestContainer( - val blockPos: BlockPos, + override val pos: BlockPos, override var stacks: List, override val stash: StashContainer? = null -) : Container(ContainerRank.Chest), ExternalContainer, PlacedContainer { +) : PlacedContainer(ContainerRank.Chest) { override val slots get(): List = - lastInteractedBlockEntity?.let { blockEntity -> - if (blockEntity is ChestBlockEntity && blockEntity.pos == blockPos) { - mc.player?.currentScreenHandler?.containerSlots - } else emptyList() - } ?: emptyList() + if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() + else emptyList() override val description = buildText { literal("Chest at ") - highlighted(blockPos.toShortString()) + highlighted(pos.toShortString()) stash?.let { stash -> literal(" (contained in ") highlighted(stash.name) @@ -67,29 +62,24 @@ data class ChestContainer( override val isAccessed get() = lastInteractedBlockEntity?.let { blockEntity -> - blockEntity.pos == blockPos && + blockEntity.pos == pos && blockEntity.cachedState.block is ChestBlock && - mc.player?.currentScreenHandler?.type == ScreenHandlerType.GENERIC_9X3 + mc.player?.currentScreenHandler?.typeSafe == ScreenHandlerType.GENERIC_9X3 } ?: false @Ta5kBuilder context(automated: Automated) - override fun access() = AccessChestTask(automated) + override fun access() = + if (isAccessed) null + else AccessChestTask(automated) inner class AccessChestTask @Ta5kBuilder internal constructor( automated: Automated - ) : OpenContainerTask(description), Automated by automated { + ) : OpenContainerTask(description), Automated by automated { override fun SafeContext.onStart() { - taskOrNull { - if (isAccessed) null - else openContainer(blockPos).onSuccess { - success(OpenedChestContext()) - } - }.execute(this@AccessChestTask) + openContainer(pos) + .onSuccess { success(BasicOpenedContainerContext(::isAccessed)) } + .start() } } - - inner class OpenedChestContext : BasicOpenedContainerContext(::isAccessed) { - val blockPos = this@ChestContainer.blockPos - } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/DoubleChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/DoubleChestContainer.kt new file mode 100644 index 000000000..3a4a138dd --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/DoubleChestContainer.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.inventory.container.containers.external + +import com.lambda.Lambda.mc +import com.lambda.context.Automated +import com.lambda.context.SafeContext +import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity +import com.lambda.interaction.inventory.container.BasicOpenedContainerContext +import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.inventory.container.OpenContainerTask +import com.lambda.interaction.inventory.container.PlacedContainer +import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.openContainer +import com.lambda.task.tasks.wrappers.withRecovery +import com.lambda.util.extension.containerSlots +import com.lambda.util.math.distSq +import com.lambda.util.player.SlotUtils.typeSafe +import com.lambda.util.text.buildText +import com.lambda.util.text.highlighted +import com.lambda.util.text.literal +import net.minecraft.block.ChestBlock +import net.minecraft.item.ItemStack +import net.minecraft.screen.ScreenHandlerType +import net.minecraft.screen.slot.Slot +import net.minecraft.util.math.BlockPos + +data class DoubleChestContainer( + override val pos: BlockPos, + val leftPos: BlockPos, + val rightPos: BlockPos, + override var stacks: List, + override val stash: StashContainer? = null +) : PlacedContainer(ContainerRank.Chest) { + override val slots + get(): List = + if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() + else emptyList() + + override val description = + buildText { + literal("Double Chest at ") + highlighted(leftPos.toShortString()) + literal(" and ") + highlighted(rightPos.toShortString()) + stash?.let { stash -> + literal(" (contained in ") + highlighted(stash.name) + literal(")") + } + } + + override val isAccessed + get() = lastInteractedBlockEntity?.let { blockEntity -> + (blockEntity.pos == leftPos || blockEntity.pos == rightPos) && + blockEntity.cachedState.block is ChestBlock && + mc.player?.currentScreenHandler?.typeSafe == ScreenHandlerType.GENERIC_9X6 + } ?: false + + @Ta5kBuilder + context(automated: Automated) + override fun access() = + if (isAccessed) null + else AccessChestTask(automated) + + inner class AccessChestTask @Ta5kBuilder internal constructor( + automated: Automated + ) : OpenContainerTask(description), Automated by automated { + override fun SafeContext.onStart() { + val leftDist = leftPos distSq player.pos + val rightDist = rightPos distSq player.pos + val closestPos = if (leftDist <= rightDist) leftPos else rightPos + val farthestPos = if (leftDist > rightDist) leftPos else rightPos + openContainer(closestPos) + .withRecovery { openContainer(farthestPos) } + .onSuccess { success(BasicOpenedContainerContext(::isAccessed)) } + .start() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt index e91df1cf8..38b15b9c4 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt @@ -39,6 +39,7 @@ import com.lambda.task.tasks.wrappers.then import com.lambda.task.tasks.wrappers.thenOrNull import com.lambda.task.tasks.wrappers.withBranch import com.lambda.util.extension.containerSlots +import com.lambda.util.player.SlotUtils.typeSafe import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.block.Blocks @@ -61,42 +62,40 @@ object EnderChestContainer : Container(ContainerRank.EnderChest), ExternalContai get() = lastInteractedBlockEntity?.let { blockEntity -> blockEntity is EnderChestBlockEntity && - mc.player?.currentScreenHandler?.type == ScreenHandlerType.GENERIC_9X3 + mc.player?.currentScreenHandler?.typeSafe == ScreenHandlerType.GENERIC_9X3 } ?: false @Ta5kBuilder context(automated: Automated) - override fun access() = OpenEnderChestContainerTask(automated) + override fun access() = + if (isAccessed) null + else OpenEnderChestContainerTask(automated) class OpenEnderChestContainerTask @Ta5kBuilder internal constructor( automated: Automated ) : OpenContainerTask(description), Automated by automated { override fun SafeContext.onStart() { - taskOrNull { - if (isAccessed) null - else findBlock(Blocks.ENDER_CHEST, inventoryConfig.enderChestSearchRadius).withBranch( - onSuccess = { pos -> - openContainer(pos).onSuccess { - success(OpenedEnderChestContext(pos, false)) - } - }, - onFailure = { - acquireStack(Items.ENDER_CHEST.select(1)) - .then { placeContainer(it) } - .then { pos -> - openContainer(pos).onSuccess { - success(OpenedEnderChestContext(pos, true)) - } - } + findBlock(Blocks.ENDER_CHEST, inventoryConfig.enderChestSearchRadius).withBranch( + onSuccess = { pos -> + openContainer(pos).onSuccess { + success(OpenedEnderChestContext(null)) } - ) - }.execute(this@OpenEnderChestContainerTask) + }, + onFailure = { + acquireStack(Items.ENDER_CHEST.select(1)) + .then { placeContainer(it) } + .then { pos -> + openContainer(pos).onSuccess { + success(OpenedEnderChestContext(pos)) + } + } + } + ).start() } } class OpenedEnderChestContext( - val blockPos: BlockPos, - val placed: Boolean + val blockPos: BlockPos? ) : OpenedContainerContext { context(_: Automated) override fun close() = @@ -104,7 +103,7 @@ object EnderChestContainer : Container(ContainerRank.EnderChest), ExternalContai if (isAccessed) actionTask { player.closeScreen() } else null }.thenOrNull { - if (placed) breakAndCollect(blockPos) + if (blockPos != null) breakAndCollect(blockPos) else null } } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt index 224bb09bc..3bf8c2188 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt @@ -22,14 +22,13 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.container.BasicOpenedContainerContext -import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.inventory.container.OpenContainerTask import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.openContainer -import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.util.extension.containerSlots +import com.lambda.util.player.SlotUtils.typeSafe import com.lambda.util.text.buildText import com.lambda.util.text.highlighted import com.lambda.util.text.literal @@ -40,11 +39,11 @@ import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos class PlacedShulkerBoxContainer( - val blockPos: BlockPos, + override val pos: BlockPos, val block: Block, override val stash: StashContainer?, override var stacks: List -) : Container(ContainerRank.PlacedShulkerBox), PlacedContainer { +) : PlacedContainer(ContainerRank.PlacedShulkerBox) { override val slots: List get() = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() @@ -53,7 +52,7 @@ class PlacedShulkerBoxContainer( override val description = buildText { literal("Placed shulker box at ") - highlighted(blockPos.toShortString()) + highlighted(pos.toShortString()) stash?.let { stash -> literal(" (contained in ") highlighted(stash.name) @@ -63,25 +62,24 @@ class PlacedShulkerBoxContainer( override val isAccessed get() = lastInteractedBlockEntity?.let { blockEntity -> - blockEntity.pos == blockPos && + blockEntity.pos == pos && blockEntity.cachedState.block == block && - mc.player?.currentScreenHandler?.type == ScreenHandlerType.SHULKER_BOX + mc.player?.currentScreenHandler?.typeSafe == ScreenHandlerType.SHULKER_BOX } ?: false @Ta5kBuilder context(automated: Automated) - override fun access() = OpenPlacedShulkerBoxTask(automated) + override fun access() = + if (isAccessed) null + else OpenPlacedShulkerBoxTask(automated) inner class OpenPlacedShulkerBoxTask @Ta5kBuilder internal constructor( automated: Automated ) : OpenContainerTask(description), Automated by automated { override fun SafeContext.onStart() { - taskOrNull { - if (isAccessed) null - else openContainer(blockPos) - }.onSuccess { - success(BasicOpenedContainerContext(::isAccessed)) - }.execute(this@OpenPlacedShulkerBoxTask) + openContainer(pos) + .onSuccess { success(BasicOpenedContainerContext(::isAccessed)) } + .start() } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt index 78030e4cf..a179fe27d 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt @@ -20,7 +20,6 @@ package com.lambda.interaction.inventory.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ContainerRank @@ -42,18 +41,19 @@ import com.lambda.util.extension.containerSlots import com.lambda.util.text.buildText import com.lambda.util.text.highlighted import com.lambda.util.text.literal -import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks -import net.minecraft.block.entity.ShulkerBoxBlockEntity +import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.Slot import net.minecraft.util.math.BlockPos +import java.util.Objects.hash data class ShulkerBoxContainer( + val itemName: String, + val shulkerItem: Item, override var stacks: List, - val containedIn: Container, - override val slotCache: Slot, -) : Container(ContainerRank.ShulkerBox), ExternalContainer, NestedContainer { + override val containedIn: Container, + override val index: Int, +) : NestedContainer(ContainerRank.ShulkerBox), ExternalContainer { override val slots get(): List = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() @@ -61,21 +61,13 @@ data class ShulkerBoxContainer( override val description = buildText { - highlighted(slotCache.stack.name.string) + highlighted(itemName) literal(" in ") highlighted(containedIn.name) - literal(" in slot $slotCache") + literal(" in slot index $index") } - private var blockPos: BlockPos? = null - - override val isAccessed - get() = - lastInteractedBlockEntity?.let { blockEntity -> - blockEntity is ShulkerBoxBlockEntity && - blockEntity.pos == blockPos && - mc.player?.currentScreenHandler?.type == ScreenHandlerType.SHULKER_BOX - } ?: false + override val isAccessed = false @Ta5kBuilder context(automated: Automated) @@ -86,7 +78,7 @@ data class ShulkerBoxContainer( ) : OpenContainerTask(description), Automated by automated { override fun SafeContext.onStart() { transfer( - selectStack { isSlot(slotCache) }, + selectStack { inIndex(index); isItem(shulkerItem) }, containedIn, HotbarContainer ).then { slot -> placeContainer(slot) } @@ -95,7 +87,7 @@ data class ShulkerBoxContainer( success(OpenedShulkerBoxContext(pos, containedIn)) } } - .execute(this@OpenShulkerBoxTask) + .start() } } @@ -103,10 +95,6 @@ data class ShulkerBoxContainer( val blockPos: BlockPos, val fromContainer: Container ) : OpenedContainerContext { - private val shulkerItem = slotCache.stack.item - private val customName = slotCache.stack.get(net.minecraft.component.DataComponentTypes.CUSTOM_NAME) - private val originalContents = slotCache.stack.shulkerBoxStacks - context(automated: Automated) override fun close() = taskOrNull { @@ -117,12 +105,19 @@ data class ShulkerBoxContainer( transfer( selectStack { isItem(shulkerItem) - if (customName != null) hasCustomName(customName) - sortedByBestContentMatch(originalContents) + hasCustomName(itemName) + sortedByBestContentMatch(stacks) }, HotbarAndInventoryContainer, fromContainer ) } } + + override fun hashCode() = hash(containedIn.hashCode(), index) + + override fun equals(other: Any?) = + other is ShulkerBoxContainer && + containedIn == other.containedIn && + index == other.index } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt index d1830a959..f789d0253 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakInfo.kt @@ -21,7 +21,7 @@ import com.lambda.config.blocks.BreakConfig import com.lambda.config.blocks.BreakConfig.BreakMode import com.lambda.context.SafeContext import com.lambda.interaction.construction.simulation.context.BreakContext -import com.lambda.interaction.handler.handlers.breaking.RebreakHandler +import com.lambda.interaction.handler.handlers.breaking.RebreakPotential import com.lambda.interaction.manager.ActionInfo import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Primary import com.lambda.interaction.manager.managers.breaking.BreakInfo.BreakType.Rebreak @@ -51,7 +51,7 @@ data class BreakInfo( // Pre Processing var shouldProgress = false - var rebreakPotential = RebreakHandler.RebreakPotential.None + var rebreakPotential = RebreakPotential.None var swapInfo = SwapInfo.EMPTY var swapStack: ItemStack = ItemStack.EMPTY @@ -163,7 +163,5 @@ data class BreakInfo( } } - fun getBreakDelay() = if (!bypassedDelay) 6 else breakConfig.breakDelay - override fun toString() = "$type, ${context.cachedState}, ${context.blockPos}" } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index f2dc2b411..bff695058 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -27,7 +27,7 @@ import com.lambda.context.SafeContext import com.lambda.event.events.EntityEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handler.handlers.ContainerHandler.move +import com.lambda.interaction.handler.handlers.move import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.inventory.container.containers.OffHandContainer diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index 1bd195dc3..1f949ba97 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -28,8 +28,8 @@ import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.util.BlockUtils.blockState import com.lambda.util.extension.shrinkByEpsilon @@ -78,7 +78,8 @@ object PlayerTrap : Module( player.eyePos.flooredBlockPos ).firstOrNull { friends || !isFriend(it.gameProfile) } ?: return@tickingBlueprint emptyMap() getTrapPositions(targetPlayer).associateWith { TargetState.Block(block) } - }.build(finishOnDone = false).run() + }.build(finishOnDone = false) + .start() } onDisable { task?.cancel(); task = null } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt index 394a9b8f6..d54b1285d 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt @@ -27,8 +27,8 @@ import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryC import com.lambda.module.Module import com.lambda.module.modules.combat.PlayerTrap.getTrapPositions import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.util.item.ItemUtils.block import net.minecraft.block.Blocks @@ -65,7 +65,8 @@ object Surround : Module( getTrapPositions(player) .filter { it.y <= player.blockPos.y } .associateWith { TargetState.Block(block) } - }.build(finishOnDone = false).run() + }.build(finishOnDone = false) + .start() } onDisable { task?.cancel(); task = null } } diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index 3bb5ebe6f..d4b479b3c 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -22,7 +22,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.inventory.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run +import com.lambda.task.start import com.lambda.task.tasks.acquireStack import net.minecraft.item.Items @@ -38,9 +38,8 @@ object ContainerTest : Module( } onEnable { - acquireStack { - Items.OBSIDIAN.select() - }.run() + acquireStack { Items.OBSIDIAN.select() } + .start() } } } diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt index e1e3af19c..6d2997dca 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt @@ -25,8 +25,8 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.eat import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated @@ -49,7 +49,9 @@ object AutoEat : Module( val reason = runSafeAutomated { reasonEating() } if (eatTask != null || !reason.shouldEat()) return@listen - eatTask = eat().thenAction { eatTask = null }.run() + eatTask = eat() + .thenAction { eatTask = null } + .start() } onDisable { diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index a3339ba7a..09ad928bc 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -23,21 +23,21 @@ import com.lambda.config.withEdits import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.handler.handlers.ContainerHandler +import com.lambda.interaction.inventory.container.OpenedContainerContext +import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task -import com.lambda.task.tasks.PlaceContainerTask -import com.lambda.task.tasks.breakAndCollect -import com.lambda.task.tasks.openContainer +import com.lambda.task.start import com.lambda.task.tasks.wrappers.then -import com.lambda.task.tasks.wrappers.thenAction import com.lambda.util.item.ItemUtils.shulkerBoxes import net.minecraft.item.Items import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.SlotActionType -import net.minecraft.util.math.BlockPos +import java.util.* +@Suppress("unused") object InventoryTweaks : Module( name = "InventoryTweaks", tag = ModuleTag.PLAYER, @@ -45,10 +45,10 @@ object InventoryTweaks : Module( private val instantShulker by setting("Instant Shulker", true, description = "Right-click shulker boxes in your inventory to instantly place them and open them.") 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 placeAndOpen: Task<*>? = null - private var lastBreak: Task<*>? = null - private var lastOpenScreen: ScreenHandler? = null + private var openTask: Task<*>? = null + private val openContexts = LinkedList() + var lastOpenScreen: ScreenHandler? = null + private var isClosing = false init { setDefaultAutomationConfig() @@ -56,32 +56,63 @@ object InventoryTweaks : Module( hideAllExcept(::breakConfig, ::interactConfig, ::inventoryConfig, ::hotbarConfig) } - listen { - if (it.action != SlotActionType.PICKUP || it.button != 1) return@listen - val slot = it.screenHandler.getSlot(it.slot) - if (!(instantShulker && slot.stack.item in shulkerBoxes) && !(instantEChest && slot.stack.item == Items.ENDER_CHEST)) return@listen - it.cancel() - lastOpenScreen = null - placeAndOpen = PlaceContainerTask(slot, this@InventoryTweaks).then { placePos -> - placedPos = placePos - openContainer(placePos).thenAction { screenHandler -> - lastOpenScreen = screenHandler + listen { event -> + if (event.action != SlotActionType.PICKUP || event.button != 1) return@listen + val slot = event.screenHandler.getSlot(event.slot) ?: return@listen + val stack = slot.stack + + when (stack.item) { + in shulkerBoxes if (!instantShulker) -> return@listen + Items.ENDER_CHEST if (!instantEChest) -> return@listen + } + + val targetContainer = + if (stack.item == Items.ENDER_CHEST) EnderChestContainer + else { + ContainerHandler.storedContainers.values + .asSequence() + .flatMap { it.values } + .firstOrNull { container -> container.index == slot.index } + ?: return@listen + } + + event.cancel() + + openTask = targetContainer + .access() + ?.onSuccess { ctx -> + openContexts.push(ctx) + lastOpenScreen = player.currentScreenHandler + openTask = null } - }.run() + ?.start() } listen { event -> - if (event.screenHandler != lastOpenScreen) return@listen - lastOpenScreen = null - placedPos?.let { - lastBreak = breakAndCollect(it).run() - placedPos = null + if (isClosing || openTask != null) return@listen + if (event.screenHandler != lastOpenScreen || openContexts.isEmpty()) return@listen + + isClosing = true + val contextsToClose = mutableListOf() + while (openContexts.isNotEmpty()) { + contextsToClose.add(openContexts.pop()) } + + val closeTask = + contextsToClose.fold?>(null) { acc, ctx -> + val task = ctx.close() ?: return@fold acc + acc?.then(task) ?: task + } + + closeTask + ?.onCompletion { isClosing = false } + ?.start() + ?: run { isClosing = false } } onDisable { - placeAndOpen?.cancel() - lastBreak?.cancel() + openContexts.clear() + isClosing = false } } } diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 8bde75a8b..4fa82ba7f 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -47,8 +47,8 @@ import com.lambda.module.modules.world.AutoPortal.PosHandler.obiPositions import com.lambda.module.modules.world.AutoPortal.PosHandler.portalPositions import com.lambda.module.modules.world.AutoPortal.PosHandler.prevAnchorPos import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.task.tasks.wrappers.thenOrNull import com.lambda.threading.runSafe @@ -103,9 +103,9 @@ object AutoPortal : Module( .thenOrNull { if (light) LightTask(currAnchorPos.up(), walkIn) else null - }.onCompletion { - buildTask = null - }.run() + } + .onCompletion { buildTask = null } + .start() } private val corners by setting("Corners", false) private val light by setting("Light", true, "Attempts to automatically light the portal after building") diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt index 75e1ba526..82751cce5 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt @@ -28,14 +28,14 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure -import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint +import com.lambda.interaction.construction.blueprint.toBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.sound.SoundHandler.playSound -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated @@ -220,7 +220,7 @@ object AutoVillagerCycle : Module( .thenAction { switchState(CycleState.OpenVillager) } - .run() + .start() } switchState(CycleState.WaitLectern) } @@ -281,7 +281,7 @@ object AutoVillagerCycle : Module( lecternPos.toStructure(TargetState.Empty) .build(finishOnDone = true) .thenAction { switchState(CycleState.PlaceLectern) } - .run() + .start() } switchState(CycleState.WaitBreak) return diff --git a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt index 0972a2a43..b3c89f8f1 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt @@ -26,8 +26,8 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.util.CommunicationUtils.info import com.lambda.util.Describable @@ -131,7 +131,7 @@ object HighwayTools : Module( emptyStructure() } }.build(collectDrops = buildConfig.collectDrops, lifeMaintenance = true) - .run() + .start() } private fun generateSlice(): Structure { diff --git a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt index 026b3851d..6f79fafb3 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt @@ -26,8 +26,8 @@ import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion. import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.util.BlockUtils.blockPos import com.lambda.util.PlayerBuildLayerUtils.FlattenMode @@ -98,7 +98,7 @@ object Nuker : Module( selection }.build(finishOnDone = false, async = async) - .run() + .start() } private fun SafeContext.isWithinDigDirection(pos: BlockPos): Boolean { diff --git a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt index f2e2332e8..6b8639976 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt @@ -34,8 +34,8 @@ import com.lambda.interaction.construction.simulation.result.results.InteractRes import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.util.BlockUtils.blockPos import com.lambda.util.CommunicationUtils.logError @@ -149,7 +149,8 @@ object Printer : Module( .filter { DataManager.getRenderLayerRange().isPositionWithinRange(it) && inSchematic(it) } .associateWith { TargetState.State(schematicWorld.getBlockState(it)) } .filter { air || !it.value.blockState.isAir } - }.build(finishOnDone = false, async = async) { filterBuildResults(it) }.run() + }.build(finishOnDone = false, async = async) { filterBuildResults(it) } + .start() } /** diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index 0bdd2d006..e3b98d24f 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -52,8 +52,8 @@ import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag -import com.lambda.task.RootTask.run import com.lambda.task.Task +import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.task.tasks.openContainer import com.lambda.task.tasks.wrappers.thenAction @@ -361,7 +361,7 @@ object StashMover : Module( ) task = null } - .run() + .start() } fun pauseUnpause() { diff --git a/src/main/kotlin/com/lambda/task/RootTask.kt b/src/main/kotlin/com/lambda/task/RootTask.kt index fac5f6208..db4abda1e 100644 --- a/src/main/kotlin/com/lambda/task/RootTask.kt +++ b/src/main/kotlin/com/lambda/task/RootTask.kt @@ -17,21 +17,12 @@ package com.lambda.task -import com.lambda.threading.runSafe +import com.lambda.task.Task.Ta5kBuilder object RootTask : Task() { override val name get() = "Root Task" - - @Ta5kBuilder - inline fun > T.run(): T { - execute(this@RootTask) - return this - } - - @Ta5kBuilder - fun Task<*>.run(task: TaskGenerator) { - runSafe { - task(Unit).execute(this@run) - } - } } + +@Ta5kBuilder +inline fun > T.start(): T = + apply { execute(RootTask) } diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index 3ae287ed5..e17939859 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -28,21 +28,22 @@ import com.lambda.task.tasks.wrappers.withRecovery import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.logError import com.lambda.util.Nameable -import com.lambda.util.StringUtils.capitalize import kotlin.time.Duration.Companion.milliseconds import kotlin.time.DurationUnit import kotlin.time.toDuration @Suppress("unused") abstract class Task : Nameable, Muteable { - var parent: Task<*>? = null - val subTasks = mutableListOf>() var state = State.Init - override val isMuted: Boolean get() = state == State.Paused || state == State.Init var age = 0 + + var parent: Task<*>? = null + val subTasks = mutableListOf>() private val depth: Int get() = parent?.depth?.plus(1) ?: 0 val size: Int get() = subTasks.sumOf { it.size } + 1 + override val isMuted: Boolean get() = state == State.Paused || state == State.Init + private val successCallbacks = mutableListOf Unit>() private val completionCallbacks = mutableListOf Unit>() private val failureCallbacks = mutableListOf Unit>() @@ -59,8 +60,6 @@ abstract class Task : Nameable, Muteable { Cancelled, Failed, Completed; - - val display get() = name.lowercase().capitalize() } init { @@ -98,6 +97,11 @@ abstract class Task : Nameable, Muteable { @Ta5kBuilder protected open fun SafeContext.onCancel() {} + @Ta5kBuilder + context(parentTask: Task<*>) + fun start(pauseParent: Boolean = true) = + this.execute(parentTask, pauseParent) + /** * Executes the current task as a subtask of the specified owner task. * @@ -127,8 +131,10 @@ abstract class Task : Nameable, Muteable { @Ta5kBuilder protected fun success(result: Result) { + if (state != State.Running && state != State.Paused) return unsubscribe() state = State.Completed + cancelSubTasks() parent?.onSubTaskSuccess(this) parent?.onSubTaskCompletion(this) @@ -151,15 +157,16 @@ abstract class Task : Nameable, Muteable { e: Throwable, stacktrace: MutableList> = mutableListOf(), ) { - state = State.Failed + if (state != State.Running && state != State.Failed) return unsubscribe() + state = State.Failed cancelSubTasks() stacktrace.add(this) parent?.onSubTaskFailure(this, e) ?: run { if (!verboseDebug) return@run - val message = + logError( buildString { val first = stacktrace.firstOrNull() ?: return@buildString append("${first.name} failed: ${e.message}\n") @@ -167,7 +174,7 @@ abstract class Task : Nameable, Muteable { append(" -> ${it.name}\n") } } - logError(message) + ) } parent?.onSubTaskCompletion(this) @@ -182,38 +189,40 @@ abstract class Task : Nameable, Muteable { @Ta5kBuilder protected fun failure(message: String) = failure(IllegalStateException(message)) - @Ta5kBuilder - fun activate() { - if (state != State.Paused) return - state = State.Running - } - - @Ta5kBuilder - fun pause() { - if (state != State.Running) return - state = State.Paused - } - @Ta5kBuilder fun cancel() = internalCancel(true) + @Ta5kBuilder private fun internalCancel(removeFromParent: Boolean = true) { + if (state != State.Running && state != State.Paused) return + if (this is RootTask) return unsubscribe() - runSafe { onCancel() } + state = State.Cancelled cancelSubTasks() + runSafe { onCancel() } + if (removeFromParent) parent?.subTasks?.remove(this) parent?.activate() - if (this is RootTask) return - if (state == State.Completed || state == State.Cancelled) return - state = State.Cancelled } @Ta5kBuilder - fun cancelSubTasks() { + private fun cancelSubTasks() { subTasks.forEach { it.internalCancel(removeFromParent = false) } subTasks.clear() } + @Ta5kBuilder + fun activate() { + if (state != State.Paused) return + state = State.Running + } + + @Ta5kBuilder + fun pause() { + if (state != State.Running) return + state = State.Paused + } + @Ta5kBuilder protected open fun onSubTaskSuccess(subTask: Task<*>) { activate() @@ -265,7 +274,7 @@ abstract class Task : Nameable, Muteable { private fun StringBuilder.appendTaskTree(task: Task<*>, level: Int = 0, maxEntries: Int = 10) { if (task.state == State.Cancelled) return - appendLine("${" ".repeat(level * 4)}${task.name}" + if (task !is RootTask) " [${task.state.display}] ${(task.age * 50).milliseconds}" else "") + appendLine("${" ".repeat(level * 4)}${task.name}" + if (task !is RootTask) " [${task.state.name}] ${(task.age * 50).milliseconds}" else "") val left = task.subTasks.size - maxEntries if (left > 0) { appendLine("${" ".repeat((level + 1) * 4)}...and $left more tasks") diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt index d8c15f21a..1bef1abf5 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -21,7 +21,7 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handler.handlers.ContainerHandler.findSlots +import com.lambda.interaction.handler.handlers.findSlots import com.lambda.interaction.inventory.select import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index 4810c7975..e50591500 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -19,8 +19,7 @@ package com.lambda.task.tasks import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.handler.handlers.ContainerHandler -import com.lambda.interaction.handler.handlers.ContainerHandler.findContainer +import com.lambda.interaction.handler.handlers.findContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task @@ -50,8 +49,10 @@ class AcquireStackTask @Ta5kBuilder internal constructor( selection.findContainer() ?.let { transfer(selection, it, HotbarContainer) } ?.onSuccess { slot -> success(slot) } - ?.execute(this@AcquireStackTask) - ?: failure(ContainerHandler.NoContainerFound(selection)) // ToDo: Create crafting path + ?.start() + ?: failure(NoContainerFound(selection)) // ToDo: Create crafting path } } } + +class NoContainerFound(selection: StackSelection) : Exception("No container found matching $selection") diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index fc6ee0651..8f64d39b1 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -28,8 +28,8 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.blueprint.Blueprint import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.PropagatingBlueprint -import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.blueprint.TickingBlueprint +import com.lambda.interaction.construction.blueprint.toBlueprint import com.lambda.interaction.construction.simulation.BuildGoal import com.lambda.interaction.construction.simulation.Simulation.Companion.simulation import com.lambda.interaction.construction.simulation.context.BuildContext @@ -51,6 +51,7 @@ import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.module.modules.client.Client import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.wrappers.softFail import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runConcurrent import com.lambda.threading.runSafe @@ -347,6 +348,8 @@ class BuildTask @Ta5kBuilder internal constructor( is Resolvable -> { LOG.info("Resolving: ${result.name}") result.resolve() + .softFail() + .start() } } } diff --git a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt index a3e7f5c45..7287e2c89 100644 --- a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt @@ -52,11 +52,12 @@ class CollectDropsTask @Ta5kBuilder internal constructor( override fun SafeContext.onStart() { listen { runSafeAutomated { - val target = drops.firstOrNull() ?: run { - BaritoneHandler.cancel() - success() - return@listen - } + val target = + drops.firstOrNull() ?: run { + BaritoneHandler.cancel() + success() + return@listen + } if (!world.entities.contains(target)) { drops.remove(target) @@ -65,12 +66,13 @@ class CollectDropsTask @Ta5kBuilder internal constructor( } if (HotbarAndInventoryContainer.stacks.none { it.isEmpty }) { - val stackToThrow = player.currentScreenHandler.playerSlots.firstOrNull { - it.stack.item in inventoryConfig.disposables - } ?: run { - failure("Inventory is full and no disposable items to throw") - return@listen - } + val stackToThrow = + player.currentScreenHandler.playerSlots.firstOrNull { + it.stack.item in inventoryConfig.disposables + } ?: run { + failure("Inventory is full and no disposable items to throw") + return@listen + } inventoryRequest { throwStack(stackToThrow.id) }.submit() diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index 52a667374..65d05f7d6 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -18,9 +18,10 @@ package com.lambda.task.tasks import com.lambda.context.Automated +import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handler.handlers.ContainerHandler.findContainer +import com.lambda.interaction.handler.handlers.findContainer import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container import com.lambda.interaction.inventory.container.ExternalContainer @@ -28,7 +29,9 @@ import com.lambda.interaction.inventory.container.OpenedContainerContext import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder +import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.task.tasks.wrappers.then +import com.lambda.task.tasks.wrappers.thenOrNull import com.lambda.threading.runSafeAutomated import net.minecraft.screen.slot.Slot @@ -63,32 +66,27 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( ) : Task(), Automated by automated { override val name = "Transferring $selection from $fromContainer to $toContainer" - init { - listen { - runSafeAutomated { - when { - fromContainer.isAccessed && toContainer.isAccessed -> - TransferTask() - .onSuccess { success(it) } - - fromContainer !is ExternalContainer -> - openTransferClose(toContainer, fromContainer, toContainer) - - toContainer !is ExternalContainer -> - openTransferClose(fromContainer, fromContainer, toContainer) - - else -> - fromContainer - .access() - .then { fromCtx -> - transfer(selection, fromContainer, HotbarAndInventoryContainer) - .then { fromCtx.close() } - } - .then { toContainer.access() } - .then { toCtx -> transferAndClose(toCtx, HotbarAndInventoryContainer, toContainer) } - }.execute(this@ContainerTransferTask) - } - } + override fun SafeContext.onStart() { + when { + fromContainer.isAccessed && toContainer.isAccessed -> + TransferTask() + .onSuccess { success(it) } + + fromContainer !is ExternalContainer -> + openTransferClose(toContainer, fromContainer, toContainer) + + toContainer !is ExternalContainer -> + openTransferClose(fromContainer, fromContainer, toContainer) + + else -> + taskOrNull { fromContainer.access() } + .then { fromCtx -> + transfer(selection, fromContainer, HotbarAndInventoryContainer) + .thenOrNull { fromCtx?.close() } + } + .thenOrNull { toContainer.access() } + .then { toCtx -> transferAndClose(toCtx, HotbarAndInventoryContainer, toContainer) } + }?.start() } /** @@ -96,20 +94,22 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( * * Used when exactly one of the two containers is external and needs to be accessed. */ + @Ta5kBuilder private fun openTransferClose(containerToOpen: Container, from: Container, to: Container) = containerToOpen .access() - .then { ctx -> transferAndClose(ctx, from, to) } + ?.then { ctx -> transferAndClose(ctx, from, to) } /** * Transfers [selection] from [from] to [to], then closes the container via [ctx]. */ - private fun transferAndClose(ctx: OpenedContainerContext, from: Container, to: Container) = + @Ta5kBuilder + private fun transferAndClose(ctx: OpenedContainerContext?, from: Container, to: Container) = transfer(selection, from, to) - .then { slot -> + .thenOrNull { slot -> ctx - .close() - .onSuccess { success(slot) } + ?.close() + ?.onSuccess { success(slot) } } private inner class TransferTask @Ta5kBuilder constructor() : Task() { diff --git a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt index 92a451718..9311f9a5b 100644 --- a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt @@ -20,7 +20,7 @@ package com.lambda.task.tasks import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure -import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint +import com.lambda.interaction.construction.blueprint.toBlueprint import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.simulation.sim @@ -28,7 +28,6 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.manager.ManagerUtils import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder -import com.lambda.task.tasks.wrappers.thenAction import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockPos import com.lambda.util.item.ItemUtils.shulkerBoxes @@ -88,8 +87,8 @@ class PlaceContainerTask @Ta5kBuilder internal constructor( .toStructure(TargetState.Stack(slot.stack)) .toBlueprint() .build(finishOnDone = true, collectDrops = false) - .thenAction { success(containerPosition) } - .execute(this@PlaceContainerTask) + .onSuccess { success(containerPosition) } + .start() } private fun SafeContext.canBeOpened( diff --git a/src/main/kotlin/com/lambda/util/BlockUtils.kt b/src/main/kotlin/com/lambda/util/BlockUtils.kt index 5da12fb6b..6ae3b7a78 100644 --- a/src/main/kotlin/com/lambda/util/BlockUtils.kt +++ b/src/main/kotlin/com/lambda/util/BlockUtils.kt @@ -273,9 +273,8 @@ object BlockUtils { fun SafeContext.blockEntity(pos: BlockPos) = world.getBlockEntity(pos) fun BlockState.matches(state: BlockState, ignoredProperties: Collection> = emptySet()) = - this.block == state.block && this.properties.all { - this[it] == state[it] || it in ignoredProperties - } + this.block == state.block && + this.properties.all { this[it] == state[it] || it in ignoredProperties } fun SafeContext.instantBreakable(blockState: BlockState, blockPos: BlockPos, breakThreshold: Float): Boolean { val ticksNeeded = 1 / (blockState.calcBlockBreakingDelta(player, world, blockPos) / breakThreshold) diff --git a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt index c8cece603..740520939 100644 --- a/src/main/kotlin/com/lambda/util/player/SlotUtils.kt +++ b/src/main/kotlin/com/lambda/util/player/SlotUtils.kt @@ -22,6 +22,8 @@ import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen import net.minecraft.client.network.ClientPlayerEntity import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemStack +import net.minecraft.screen.ScreenHandler +import net.minecraft.screen.ScreenHandlerType import net.minecraft.screen.slot.ArmorSlot import net.minecraft.screen.slot.Slot import net.minecraft.screen.slot.SlotActionType @@ -58,6 +60,9 @@ object SlotUtils { val ClientPlayerEntity.inventoryStacks: List get() = inventory.mainStacks.slice(9..35) val ClientPlayerEntity.hotbarAndInventoryStacks: List get() = inventory.mainStacks + val ScreenHandler.typeSafe: ScreenHandlerType<*>? + get() = try { this.type } catch (_: Throwable) { null } + fun SafeContext.clickSlot(slotId: Int, button: Int, actionType: SlotActionType) { val syncId = player.currentScreenHandler?.syncId ?: return interaction.clickSlot(syncId, slotId, button, actionType, player) @@ -68,6 +73,5 @@ object SlotUtils { inventory::class == slot.inventory::class && id == slot.id && x == slot.x && - y == slot.y && - ItemStack.areEqual(stack, slot.stack) + y == slot.y } From 415223087b2acc8ede9e5a88303d40481fc7ebf3 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Tue, 1 Sep 2026 11:42:23 +0100 Subject: [PATCH 12/18] fixes n stuff --- .../handler/handlers/ContainerHandler.kt | 42 ++++++++++++++----- .../inventory/container/Container.kt | 2 + .../module/modules/player/InventoryTweaks.kt | 8 ++-- src/main/kotlin/com/lambda/task/Task.kt | 16 +++---- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index ced2c4d1c..c21085f12 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -30,7 +30,6 @@ import com.lambda.interaction.inventory.ContainerMarker import com.lambda.interaction.inventory.ContainerSelection import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.NestedContainer import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.interaction.inventory.container.containers.external.ChestContainer import com.lambda.interaction.inventory.container.containers.external.DoubleChestContainer @@ -62,13 +61,20 @@ import net.minecraft.util.math.ChunkPos @Suppress("unused") object ContainerHandler : Loadable { private val containers: Sequence - get() = compileContainers.asSequence() + - placedContainers.values.asSequence().flatMap { it.values } + - storedContainers.values.asSequence().flatMap { it.values } + get() { + fun Container.allNested(): Sequence = + sequence { + val nested = storedContainers.values + yieldAll(nested) + nested.forEach { yieldAll(it.allNested()) } + } + val baseContainers = compileContainers.asSequence() + + placedContainers.values.asSequence().flatMap { it.values } + return baseContainers + baseContainers.flatMap { it.allNested() } + } - val compileContainers = getInstances() + val compileContainers = getInstances() val placedContainers = mutableMapOf>() - val storedContainers = mutableMapOf>() context(automated: Automated) val filteredContainers @@ -80,20 +86,32 @@ object ContainerHandler : Loadable { get() = containers.sorted() var lastInteractedBlockEntity: BlockEntity? = null + var pendingInteractedBlockEntity: BlockEntity? = null override fun load() = "Loaded ${compileContainers.size} containers" init { listen { event -> val packet = event.packet as? PlayerInteractBlockC2SPacket ?: return@listen - lastInteractedBlockEntity = blockEntity(packet.blockHitResult.blockPos) + val entity = blockEntity(packet.blockHitResult.blockPos) + pendingInteractedBlockEntity = entity + lastInteractedBlockEntity = entity } listen { event -> val sh = event.screenHandler onContainerUpdate(sh) - if (sh.syncId != 0) lastInteractedBlockEntity = null + if (sh.syncId != 0 && pendingInteractedBlockEntity == null) { + lastInteractedBlockEntity = null + } + } + + listen { + if (it.screenHandler.syncId != 0) { + pendingInteractedBlockEntity = null + } } + listen { onContainerUpdate() } listen { onContainerUpdate() } @@ -198,12 +216,11 @@ object ContainerHandler : Loadable { } private fun Container.scanContainerContents() { - val storageCache = storedContainers.getOrPut(this) { mutableMapOf() } slots.forEach { slot -> val stack = slot.stack val index = slot.index if (stack.item in shulkerBoxes) { - storageCache[index] = + storedContainers[index] = ShulkerBoxContainer( stack.name.string, stack.item, @@ -211,14 +228,17 @@ object ContainerHandler : Loadable { this, index ).also { it.scanContainerContents() } - } else storageCache.remove(index) + } else storedContainers.remove(index) } } private fun getPlacedContainer(pos: BlockPos) = placedContainers[ChunkPos(pos)]?.get(pos) + private fun ChunkPos.getPlacedContainer(pos: BlockPos) = placedContainers[this]?.get(pos) + private fun setPlacedContainer(pos: BlockPos, container: PlacedContainer) = placedContainers.getOrPut(ChunkPos(pos)) { mutableMapOf() }.put(pos, container) + private fun ChunkPos.setPlacedContainer(pos: BlockPos, container: PlacedContainer) = placedContainers.getOrPut(this) { mutableMapOf() }.put(pos, container) diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt index c652128ef..cc2889eec 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt @@ -51,6 +51,8 @@ abstract class Container( abstract val slots: List abstract var stacks: List + val storedContainers = mutableMapOf() + open val swapMethodPriority = 0 abstract val description: Text diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index 09ad928bc..ce8c6a92d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -24,6 +24,7 @@ import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.ContainerHandler +import com.lambda.interaction.inventory.container.NestedContainer import com.lambda.interaction.inventory.container.OpenedContainerContext import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.module.Module @@ -69,9 +70,8 @@ object InventoryTweaks : Module( val targetContainer = if (stack.item == Items.ENDER_CHEST) EnderChestContainer else { - ContainerHandler.storedContainers.values - .asSequence() - .flatMap { it.values } + ContainerHandler.allContainers + .filterIsInstance() .firstOrNull { container -> container.index == slot.index } ?: return@listen } @@ -85,7 +85,7 @@ object InventoryTweaks : Module( lastOpenScreen = player.currentScreenHandler openTask = null } - ?.start() + openTask?.start() } listen { event -> diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index e17939859..599c84373 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -109,20 +109,20 @@ abstract class Task : Nameable, Muteable { * logs the execution details, and invokes the necessary lifecycle hooks. Additionally, * it manages the state of the parent task and starts any required listeners for execution. * - * @param owner The parent task that will execute this task as a sub task. Must not be the same as this task. + * @param parent The parent task that will execute this task as a sub task. Must not be the same as this task. * @param pauseParent Defines whether the parent task should be paused during the execution of this task. Defaults to `true`. * @return The current task instance as a `Task` to support chaining or further configuration. * @throws IllegalArgumentException if the owner task is the same as the task being executed. */ @Ta5kBuilder - fun execute(owner: Task<*>, pauseParent: Boolean = true): Task { - require(owner != this) { "Cannot execute a task as a sub task of itself" } - owner.subTasks.add(this) - parent = owner - if (verboseDebug) LOG.info("${owner.name} started $name") + fun execute(parent: Task<*>, pauseParent: Boolean = true): Task { + require(parent != this) { "Cannot execute a task as a sub task of itself" } + parent.subTasks.add(this) + this@Task.parent = parent + if (verboseDebug) LOG.info("${parent.name} started $name") if (pauseParent) { - if (verboseDebug) LOG.info("$name pausing parent ${owner.name}") - if (owner !is RootTask) owner.pause() + if (verboseDebug) LOG.info("$name pausing parent ${parent.name}") + if (parent !is RootTask) parent.pause() } state = State.Running runSafe { runCatching { onStart() }.onFailure { failure(it) } } From e393250f9b835464c57c5388291ea75deadfc4e3 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Thu, 3 Sep 2026 11:42:57 +0100 Subject: [PATCH 13/18] remove inventory package and move container up --- .../command/commands/TransferCommand.kt | 2 +- .../com/lambda/config/blocks/EatConfig.kt | 4 +- .../lambda/config/blocks/InventoryConfig.kt | 24 +- .../lambda/config/blocks/InventorySettings.kt | 6 +- .../com/lambda/event/events/ContainerEvent.kt | 2 +- .../simulation/context/BreakContext.kt | 2 +- .../simulation/result/results/BreakResult.kt | 4 +- .../result/results/GenericResult.kt | 4 +- .../construction/simulation/sims/BreakSim.kt | 12 +- .../simulation/sims/InteractSim.kt | 10 +- .../construction/verify/TargetState.kt | 6 +- .../{inventory => }/container/Container.kt | 16 +- .../ContainerMarker.kt | 2 +- .../ContainerType.kt} | 8 +- .../container/ExternalContainer.kt | 2 +- .../container/NestedContainer.kt | 4 +- .../container/OpenContainerTask.kt | 2 +- .../container/OpenedContainerContext.kt | 2 +- .../container/PlacedContainer.kt | 6 +- .../container/containers/ArmorContainer.kt | 8 +- .../container/containers/CreativeContainer.kt | 10 +- .../containers/CursorContainer.kt} | 18 +- .../container/containers/HotbarContainer.kt | 8 +- .../containers/InventoryContainer.kt | 8 +- .../container/containers/OffHandContainer.kt | 8 +- .../containers/external/ChestContainer.kt | 14 +- .../external/DoubleChestContainer.kt | 12 +- .../external/EnderChestContainer.kt | 16 +- .../external/PlacedShulkerBoxContainer.kt | 12 +- .../external/ShulkerBoxContainer.kt | 27 +- .../containers/external/StashContainer.kt | 10 +- .../selection}/ContainerSelection.kt | 64 ++++- .../selection}/StackSelection.kt | 24 +- .../handler/handlers/ContainerHandler.kt | 104 ++++---- .../handler/handlers/GlideHandler.kt | 11 +- .../containers/HotbarAndInventoryContainer.kt | 38 --- .../container/containers/MainHandContainer.kt | 46 ---- .../manager/managers/breaking/BreakManager.kt | 2 +- .../lambda/module/modules/combat/AutoArmor.kt | 3 +- .../lambda/module/modules/combat/AutoTotem.kt | 3 +- .../module/modules/combat/CrystalAura.kt | 7 +- .../lambda/module/modules/combat/KillAura.kt | 4 +- .../module/modules/combat/PlayerTrap.kt | 1 - .../lambda/module/modules/combat/Surround.kt | 1 - .../module/modules/debug/ContainerTest.kt | 2 +- .../module/modules/movement/BetterFirework.kt | 9 +- .../movement/elytrafly/ElytraFlyMode.kt | 3 +- .../elytrafly/modes/GrimControlElytraFly.kt | 6 +- .../module/modules/player/AutoElytraSwap.kt | 3 +- .../module/modules/player/InventoryTweaks.kt | 11 +- .../module/modules/player/StackReplenish.kt | 4 +- .../lambda/module/modules/player/ToolSaver.kt | 4 +- .../module/modules/render/ContainerPreview.kt | 10 +- .../lambda/module/modules/world/AutoPortal.kt | 5 +- .../module/modules/world/MapDownloader.kt | 1 - .../lambda/module/modules/world/Scaffold.kt | 4 +- .../lambda/module/modules/world/StashMover.kt | 9 +- .../task/tasks/AcquirePlacedBlockTask.kt | 2 +- .../com/lambda/task/tasks/AcquireStackTask.kt | 4 +- .../com/lambda/task/tasks/CollectDropsTask.kt | 1 - .../task/tasks/ContainerTransferTask.kt | 130 +++++---- .../kotlin/com/lambda/task/tasks/EatTask.kt | 4 +- .../lambda/task/tasks/PlaceContainerTask.kt | 4 +- .../kotlin/com/lambda/util/item/ItemUtils.kt | 249 +++++++++--------- 64 files changed, 514 insertions(+), 528 deletions(-) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/Container.kt (90%) rename src/main/kotlin/com/lambda/interaction/{inventory => container}/ContainerMarker.kt (94%) rename src/main/kotlin/com/lambda/interaction/{inventory/container/ContainerRank.kt => container/ContainerType.kt} (87%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/ExternalContainer.kt (93%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/NestedContainer.kt (84%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/OpenContainerTask.kt (96%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/OpenedContainerContext.kt (95%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/PlacedContainer.kt (77%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/ArmorContainer.kt (84%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/CreativeContainer.kt (89%) rename src/main/kotlin/com/lambda/interaction/{inventory/container/containers/PlayerContainer.kt => container/containers/CursorContainer.kt} (62%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/HotbarContainer.kt (86%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/InventoryContainer.kt (83%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/OffHandContainer.kt (85%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/external/ChestContainer.kt (85%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/external/DoubleChestContainer.kt (88%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/external/EnderChestContainer.kt (86%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/external/PlacedShulkerBoxContainer.kt (86%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/external/ShulkerBoxContainer.kt (81%) rename src/main/kotlin/com/lambda/interaction/{inventory => }/container/containers/external/StashContainer.kt (83%) rename src/main/kotlin/com/lambda/interaction/{inventory => container/selection}/ContainerSelection.kt (56%) rename src/main/kotlin/com/lambda/interaction/{inventory => container/selection}/StackSelection.kt (91%) delete mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt delete mode 100644 src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index 0e0d4babb..9077ebe4d 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -28,10 +28,10 @@ import com.lambda.brigadier.executeWithResult import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.handler.handlers.ContainerHandler import com.lambda.interaction.handler.handlers.findContainers import com.lambda.interaction.handler.handlers.findContainersWithSpace -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.transfer diff --git a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt index 10af94609..721b5470e 100644 --- a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt @@ -19,8 +19,8 @@ package com.lambda.config.blocks import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext -import com.lambda.interaction.inventory.StackAndSlot -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackAndSlot +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.threading.runSafe import com.lambda.util.Describable import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 3e839a7af..5ac44e036 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -18,11 +18,10 @@ package com.lambda.config.blocks import com.lambda.event.events.TickEvent -import com.lambda.interaction.inventory.ContainerSelection -import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.StackSelection import com.lambda.util.Describable import com.lambda.util.NamedEnum import net.minecraft.item.Item @@ -33,13 +32,12 @@ interface InventoryConfig { val accessPriority: Priority val storePriority: Priority - val allowedContainers: Collection - - val enderChestSearchRadius: Int - + val allowedContainers: Collection val containerSelection: ContainerSelection get() = selectContainer { ofAnyType(*allowedContainers.toTypedArray()) } + val enderChestSearchRadius: Int + enum class Priority( override val displayName: String, override val description: String @@ -49,22 +47,22 @@ interface InventoryConfig { fun materialComparator(selection: StackSelection) = when (this) { - WithMaxItems -> compareBy { it.rank } + WithMaxItems -> compareBy { it.type } .thenByDescending { it.stackCount(selection) } .thenBy { it.name } - WithMinItems -> compareBy { it.rank } + WithMinItems -> compareBy { it.type } .thenBy { it.stackCount(selection) } .thenBy { it.name } } fun spaceComparator(selection: StackSelection) = when (this) { - WithMaxItems -> compareBy { it.rank } + WithMaxItems -> compareBy { it.type } .thenByDescending { it.spaceAvailable(selection) } .thenBy { it.name } - WithMinItems -> compareBy { it.rank } + WithMinItems -> compareBy { it.type } .thenBy { it.spaceAvailable(selection) } .thenBy { it.name } } diff --git a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt index f5297f702..2659c92f1 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt @@ -21,7 +21,7 @@ import com.lambda.config.Config import com.lambda.config.ConfigBlock import com.lambda.config.Group import com.lambda.event.events.TickEvent.Companion.ALL_STAGES -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.ContainerType import com.lambda.util.item.ItemUtils class InventorySettings(override val c: Config) : InventoryConfig, ConfigBlock { @@ -30,10 +30,10 @@ class InventorySettings(override val c: Config) : InventoryConfig, ConfigBlock { } override val tickStageMask by c.setting("Inventory Stage Mask", ALL_STAGES.toSet(), description = "The sub-tick timing at which inventory actions are performed", displayClassName = true) - override val disposables by c.setting("Disposables", ItemUtils.defaultDisposables, description = "Items that will be ignored when checking for a free slot") + override val disposables by c.setting("Disposables", ItemUtils.DEFAULT_DISPOSABLES, description = "Items that will be ignored when checking for a free slot") override val accessPriority by c.setting("Access Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when retrieving the item from") override val storePriority by c.setting("Store Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when storing the item to") - override val allowedContainers by c.setting("Allowed Containers", ContainerRank.entries, description = "What containers are accessible") + override val allowedContainers by c.setting("Allowed Containers", ContainerType.entries, description = "What containers are accessible") @Group(ENDER_CHEST_GROUP) override val enderChestSearchRadius by c.setting("Initial Search Radius", 10, 0..20, unit = " blocks", description = "Initial search radius to scan for an already placed ender chest. If one isn't found, one will be placed. If an ender chest isn't found in the inventory, it scans the rest of the loaded area to find an already placed one") } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt b/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt index f586dd52a..0bfdb1899 100644 --- a/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt +++ b/src/main/kotlin/com/lambda/event/events/ContainerEvent.kt @@ -19,7 +19,7 @@ package com.lambda.event.events import com.lambda.event.callback.Cancellable import com.lambda.event.callback.ICancellable -import com.lambda.interaction.inventory.container.Container +import com.lambda.interaction.container.Container import net.minecraft.screen.slot.Slot sealed class ContainerEvent { diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt index a11a43628..d3b142bcf 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/context/BreakContext.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.construction.simulation.context import com.lambda.context.Automated import com.lambda.graphics.mc.RenderBuilder -import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.manager.managers.rotating.RotationRequest import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.emptyState diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 769f2b102..361763443 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -31,9 +31,9 @@ import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.tasks.transferTo import net.minecraft.block.BlockState import net.minecraft.item.Item diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index 69dc06081..0e06d44da 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -26,9 +26,9 @@ import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.tasks.transferTo import net.minecraft.client.data.TextureMap.side import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt index 6c179d68c..06f5e8c1c 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt @@ -28,12 +28,12 @@ import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.result.results.GenericResult import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.StackAndSlot +import com.lambda.interaction.container.selection.StackSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.handler.handlers.findContainers -import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer -import com.lambda.interaction.inventory.StackAndSlot -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.ContainerRank import com.lambda.interaction.manager.managers.hotbar.HotbarManager import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest @@ -155,7 +155,7 @@ class BreakSim internal constructor(simInfo: SimInfo) } val containerSelection = selectContainer { - ofAnyType(ContainerRank.Hotbar) + ofAnyType(ContainerType.Hotbar) } val hotbarCandidates = stackSelection diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt index 10d9b0629..341a15e8e 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt @@ -27,11 +27,11 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.findContainers -import com.lambda.interaction.inventory.ContainerSelectionBuilder.Companion.selectContainer -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.inventory.select import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation import com.lambda.interaction.manager.managers.rotating.RotationManager @@ -207,7 +207,7 @@ class InteractSim internal constructor(simInfo: InteractSimInfo) } val stackSelection = item?.select(if (item == Items.AIR) 0 else 1) ?: selectStack { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } - val containerSelection = selectContainer { ofAnyType(ContainerRank.Hotbar) } + val containerSelection = selectContainer { ofAnyType(ContainerType.Hotbar) } val container = stackSelection.findContainers(containerSelection).firstOrNull() ?: run { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index cf594ccb8..1ba987fc8 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.construction.verify import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext -import com.lambda.interaction.handler.handlers.findDisposable +import com.lambda.interaction.handler.handlers.findContainerWithDisposable import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.emptyState import com.lambda.util.BlockUtils.isEmpty @@ -86,7 +86,7 @@ sealed class TargetState : StateMatcher { context(automatedSafeContext: AutomatedSafeContext) override fun getStack(pos: BlockPos) = with(automatedSafeContext) { - findDisposable()?.stacks?.firstOrNull { + findContainerWithDisposable()?.stacks?.firstOrNull { it.item in inventoryConfig.disposables && it.item.block !in replace } ?: ItemStack(Items.NETHERRACK) } @@ -113,7 +113,7 @@ sealed class TargetState : StateMatcher { context(automatedSafeContext: AutomatedSafeContext) override fun getStack(pos: BlockPos) = with(automatedSafeContext) { - findDisposable()?.stacks?.firstOrNull { + findContainerWithDisposable()?.stacks?.firstOrNull { it.item in inventoryConfig.disposables } ?: ItemStack(Items.NETHERRACK) } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt b/src/main/kotlin/com/lambda/interaction/container/Container.kt similarity index 90% rename from src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt rename to src/main/kotlin/com/lambda/interaction/container/Container.kt index cc2889eec..d8dd36dd5 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/container/Container.kt @@ -15,14 +15,14 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container +package com.lambda.interaction.container import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent -import com.lambda.interaction.inventory.StackSelection +import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task.Ta5kBuilder @@ -44,7 +44,7 @@ import net.minecraft.text.Text // ToDo: Make jsonable to persistently store them abstract class Container( - val rank: ContainerRank + val type: ContainerType ) : Nameable, Comparable { override val name: String get() = description.string @@ -106,14 +106,6 @@ abstract class Container( open fun access(): OpenContainerTask<*>? = PlayerOpenContainerTask(description, ::isAccessed) - context(automatedSafeContext: AutomatedSafeContext) - internal fun move(selection: StackSelection, toContainer: Container): Boolean = - with(automatedSafeContext) { - val (fromSlot, toSlot) = getTransferSlots(selection, toContainer) - if (fromSlot == null || toSlot == null) return false - swap(fromSlot, toSlot, toContainer) - } - context(automatedSafeContext: AutomatedSafeContext) internal fun swap(fromSlot: Slot, toSlot: Slot, toContainer: Container): Boolean { val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@Container, toContainer) @@ -148,5 +140,5 @@ abstract class Container( open fun getSlot(selection: StackSelection) = selection.bestMatch(slots) - override fun compareTo(other: Container) = compareBy { it.rank }.compare(this, other) + override fun compareTo(other: Container) = compareBy { it.type }.compare(this, other) } diff --git a/src/main/kotlin/com/lambda/interaction/inventory/ContainerMarker.kt b/src/main/kotlin/com/lambda/interaction/container/ContainerMarker.kt similarity index 94% rename from src/main/kotlin/com/lambda/interaction/inventory/ContainerMarker.kt rename to src/main/kotlin/com/lambda/interaction/container/ContainerMarker.kt index fa8982066..9b56dc2c7 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/ContainerMarker.kt +++ b/src/main/kotlin/com/lambda/interaction/container/ContainerMarker.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory +package com.lambda.interaction.container @DslMarker annotation class ContainerMarker \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/ContainerRank.kt b/src/main/kotlin/com/lambda/interaction/container/ContainerType.kt similarity index 87% rename from src/main/kotlin/com/lambda/interaction/inventory/container/ContainerRank.kt rename to src/main/kotlin/com/lambda/interaction/container/ContainerType.kt index 2d50d0c47..cfc76c5f5 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/ContainerRank.kt +++ b/src/main/kotlin/com/lambda/interaction/container/ContainerType.kt @@ -15,16 +15,14 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container +package com.lambda.interaction.container -enum class ContainerRank { - MainHand, +enum class ContainerType { OffHand, Hotbar, + Cursor, Inventory, - HotbarAndInventory, Armor, - Player, Creative, ShulkerBox, EnderChest, diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt b/src/main/kotlin/com/lambda/interaction/container/ExternalContainer.kt similarity index 93% rename from src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/ExternalContainer.kt index bad12fdb3..500d2f6e2 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/ExternalContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/ExternalContainer.kt @@ -15,6 +15,6 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container +package com.lambda.interaction.container interface ExternalContainer \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt b/src/main/kotlin/com/lambda/interaction/container/NestedContainer.kt similarity index 84% rename from src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/NestedContainer.kt index 039fe429f..e71c7033e 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/NestedContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/NestedContainer.kt @@ -15,9 +15,9 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container +package com.lambda.interaction.container -abstract class NestedContainer(rank: ContainerRank) : Container(rank) { +abstract class NestedContainer(type: ContainerType) : Container(type), ExternalContainer { abstract val containedIn: Container abstract val index: Int } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt b/src/main/kotlin/com/lambda/interaction/container/OpenContainerTask.kt similarity index 96% rename from src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt rename to src/main/kotlin/com/lambda/interaction/container/OpenContainerTask.kt index e871641fa..61a07e5d7 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenContainerTask.kt +++ b/src/main/kotlin/com/lambda/interaction/container/OpenContainerTask.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container +package com.lambda.interaction.container import com.lambda.context.SafeContext import com.lambda.task.Task diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt b/src/main/kotlin/com/lambda/interaction/container/OpenedContainerContext.kt similarity index 95% rename from src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt rename to src/main/kotlin/com/lambda/interaction/container/OpenedContainerContext.kt index a58ba8990..4deafbcb0 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/OpenedContainerContext.kt +++ b/src/main/kotlin/com/lambda/interaction/container/OpenedContainerContext.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container +package com.lambda.interaction.container import com.lambda.context.Automated import com.lambda.task.Task diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt b/src/main/kotlin/com/lambda/interaction/container/PlacedContainer.kt similarity index 77% rename from src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/PlacedContainer.kt index 85ab71da3..98c5b8f38 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/PlacedContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/PlacedContainer.kt @@ -15,12 +15,12 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container +package com.lambda.interaction.container -import com.lambda.interaction.inventory.container.containers.external.StashContainer +import com.lambda.interaction.container.containers.external.StashContainer import net.minecraft.util.math.BlockPos -abstract class PlacedContainer(rank: ContainerRank) : Container(rank), ExternalContainer { +abstract class PlacedContainer(type: ContainerType) : Container(type), ExternalContainer { abstract val pos: BlockPos abstract val stash: StashContainer? } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/ArmorContainer.kt similarity index 84% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/ArmorContainer.kt index f25f7629e..bd54eebf8 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/ArmorContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/ArmorContainer.kt @@ -15,11 +15,11 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.container.containers import com.lambda.Lambda.mc -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType import com.lambda.util.player.SlotUtils.armorSlots import com.lambda.util.player.SlotUtils.armorStacks import com.lambda.util.text.buildText @@ -27,7 +27,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object ArmorContainer : Container(ContainerRank.Armor) { +object ArmorContainer : Container(ContainerType.Armor) { override val slots: List get() = mc.player?.armorSlots ?: emptyList() override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/CreativeContainer.kt similarity index 89% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/CreativeContainer.kt index e96f0c892..2c53447d1 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/CreativeContainer.kt @@ -15,13 +15,13 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.text.buildText import com.lambda.util.text.literal @@ -32,7 +32,7 @@ import net.minecraft.item.ItemStack import net.minecraft.screen.PlayerScreenHandler import net.minecraft.screen.slot.Slot -data object CreativeContainer : Container(ContainerRank.Creative) { +data object CreativeContainer : Container(ContainerType.Creative) { override val slots = emptyList() override var stacks = emptyList() diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/CursorContainer.kt similarity index 62% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/CursorContainer.kt index 736d1e787..5211c5d90 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/PlayerContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/CursorContainer.kt @@ -15,25 +15,21 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.container.containers import com.lambda.Lambda.mc -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.util.player.SlotUtils.allSlots -import com.lambda.util.player.SlotUtils.allStacks +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -@Suppress("unused") -object PlayerContainer : Container(ContainerRank.Player) { - override val slots: List - get() = mc.player?.allSlots ?: emptyList() +object CursorContainer : Container(ContainerType.Cursor) { + override val slots: List = emptyList() override var stacks: List - get() = mc.player?.allStacks ?: emptyList() + get() = mc.player?.currentScreenHandler?.cursorStack?.let { listOf(it) } ?: emptyList() set(_) {} - override val description = buildText { literal("Player") } + override val description = buildText { literal("Cursor") } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/HotbarContainer.kt similarity index 86% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/HotbarContainer.kt index 9533e52cf..3e5ba3744 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/HotbarContainer.kt @@ -15,12 +15,12 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.hotbarSlots import com.lambda.util.player.SlotUtils.hotbarStacks @@ -28,7 +28,7 @@ import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.screen.slot.Slot -object HotbarContainer : Container(ContainerRank.Hotbar) { +object HotbarContainer : Container(ContainerType.Hotbar) { override val slots: List get() = mc.player?.hotbarSlots ?: emptyList() override var stacks diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/InventoryContainer.kt similarity index 83% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/InventoryContainer.kt index d9cec92a0..f1c56e1cf 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/InventoryContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/InventoryContainer.kt @@ -15,11 +15,11 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.container.containers import com.lambda.Lambda.mc -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType import com.lambda.util.player.SlotUtils.inventorySlots import com.lambda.util.player.SlotUtils.inventoryStacks import com.lambda.util.text.buildText @@ -27,7 +27,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object InventoryContainer : Container(ContainerRank.Inventory) { +object InventoryContainer : Container(ContainerType.Inventory) { override val slots: List get() = mc.player?.inventorySlots ?: emptyList() override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/OffHandContainer.kt similarity index 85% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/OffHandContainer.kt index 88e65599b..400af4860 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/OffHandContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/OffHandContainer.kt @@ -15,12 +15,12 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers +package com.lambda.interaction.container.containers import com.lambda.Lambda.mc import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.util.player.SlotUtils.offHandSlots import com.lambda.util.text.buildText @@ -28,7 +28,7 @@ import com.lambda.util.text.literal import net.minecraft.item.ItemStack import net.minecraft.screen.slot.Slot -object OffHandContainer : Container(ContainerRank.OffHand) { +object OffHandContainer : Container(ContainerType.OffHand) { override val slots: List get() = mc.player?.offHandSlots ?: emptyList() override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/ChestContainer.kt similarity index 85% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/external/ChestContainer.kt index abdb79b94..ab545dea2 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/ChestContainer.kt @@ -15,17 +15,17 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers.external +package com.lambda.interaction.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.Automated import com.lambda.context.SafeContext +import com.lambda.interaction.container.BasicOpenedContainerContext +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.OpenContainerTask +import com.lambda.interaction.container.OpenedContainerContext +import com.lambda.interaction.container.PlacedContainer import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity -import com.lambda.interaction.inventory.container.BasicOpenedContainerContext -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.inventory.container.OpenContainerTask -import com.lambda.interaction.inventory.container.OpenedContainerContext -import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.openContainer import com.lambda.util.extension.containerSlots @@ -43,7 +43,7 @@ data class ChestContainer( override val pos: BlockPos, override var stacks: List, override val stash: StashContainer? = null -) : PlacedContainer(ContainerRank.Chest) { +) : PlacedContainer(ContainerType.Chest) { override val slots get(): List = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/DoubleChestContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/DoubleChestContainer.kt similarity index 88% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/DoubleChestContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/external/DoubleChestContainer.kt index 3a4a138dd..f9a9ff386 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/DoubleChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/DoubleChestContainer.kt @@ -15,16 +15,16 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers.external +package com.lambda.interaction.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.Automated import com.lambda.context.SafeContext +import com.lambda.interaction.container.BasicOpenedContainerContext +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.OpenContainerTask +import com.lambda.interaction.container.PlacedContainer import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity -import com.lambda.interaction.inventory.container.BasicOpenedContainerContext -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.inventory.container.OpenContainerTask -import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.openContainer import com.lambda.task.tasks.wrappers.withRecovery @@ -46,7 +46,7 @@ data class DoubleChestContainer( val rightPos: BlockPos, override var stacks: List, override val stash: StashContainer? = null -) : PlacedContainer(ContainerRank.Chest) { +) : PlacedContainer(ContainerType.Chest) { override val slots get(): List = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/EnderChestContainer.kt similarity index 86% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/external/EnderChestContainer.kt index 38b15b9c4..925cf1aaa 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/EnderChestContainer.kt @@ -15,18 +15,18 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers.external +package com.lambda.interaction.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.Automated import com.lambda.context.SafeContext +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.ExternalContainer +import com.lambda.interaction.container.OpenContainerTask +import com.lambda.interaction.container.OpenedContainerContext +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.interaction.inventory.container.OpenContainerTask -import com.lambda.interaction.inventory.container.OpenedContainerContext -import com.lambda.interaction.inventory.select import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.acquireStack import com.lambda.task.tasks.breakAndCollect @@ -49,7 +49,7 @@ import net.minecraft.item.Items import net.minecraft.screen.ScreenHandlerType import net.minecraft.util.math.BlockPos -object EnderChestContainer : Container(ContainerRank.EnderChest), ExternalContainer { +object EnderChestContainer : Container(ContainerType.EnderChest), ExternalContainer { override val slots get() = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/PlacedShulkerBoxContainer.kt similarity index 86% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/external/PlacedShulkerBoxContainer.kt index 3bf8c2188..716e2489e 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/PlacedShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/PlacedShulkerBoxContainer.kt @@ -15,16 +15,16 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers.external +package com.lambda.interaction.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.Automated import com.lambda.context.SafeContext +import com.lambda.interaction.container.BasicOpenedContainerContext +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.OpenContainerTask +import com.lambda.interaction.container.PlacedContainer import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity -import com.lambda.interaction.inventory.container.BasicOpenedContainerContext -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.inventory.container.OpenContainerTask -import com.lambda.interaction.inventory.container.PlacedContainer import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.openContainer import com.lambda.util.extension.containerSlots @@ -43,7 +43,7 @@ class PlacedShulkerBoxContainer( val block: Block, override val stash: StashContainer?, override var stacks: List -) : PlacedContainer(ContainerRank.PlacedShulkerBox) { +) : PlacedContainer(ContainerType.PlacedShulkerBox) { override val slots: List get() = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt similarity index 81% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt index a179fe27d..d2e67c234 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt @@ -15,25 +15,25 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers.external +package com.lambda.interaction.container.containers.external import com.lambda.Lambda.mc import com.lambda.context.Automated import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.interaction.inventory.container.NestedContainer -import com.lambda.interaction.inventory.container.OpenContainerTask -import com.lambda.interaction.inventory.container.OpenedContainerContext -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.ExternalContainer +import com.lambda.interaction.container.NestedContainer +import com.lambda.interaction.container.OpenContainerTask +import com.lambda.interaction.container.OpenedContainerContext +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.breakAndCollect import com.lambda.task.tasks.openContainer import com.lambda.task.tasks.placeContainer import com.lambda.task.tasks.transfer +import com.lambda.task.tasks.transferTo import com.lambda.task.tasks.wrappers.actionTask import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.task.tasks.wrappers.then @@ -53,7 +53,7 @@ data class ShulkerBoxContainer( override var stacks: List, override val containedIn: Container, override val index: Int, -) : NestedContainer(ContainerRank.ShulkerBox), ExternalContainer { +) : NestedContainer(ContainerType.ShulkerBox), ExternalContainer { override val slots get(): List = if (isAccessed) mc.player?.currentScreenHandler?.containerSlots ?: emptyList() @@ -102,6 +102,11 @@ data class ShulkerBoxContainer( else actionTask { player.closeScreen() } }.then { breakAndCollect(blockPos) } .then { + selectStack { + isItem(shulkerItem) + hasCustomName(itemName) + sortedByBestContentMatch(stacks) + }.transferTo() transfer( selectStack { isItem(shulkerItem) diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/StashContainer.kt similarity index 83% rename from src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt rename to src/main/kotlin/com/lambda/interaction/container/containers/external/StashContainer.kt index 8c7063980..bd3420298 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/external/StashContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/StashContainer.kt @@ -15,11 +15,11 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory.container.containers.external +package com.lambda.interaction.container.containers.external -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.selection.StackSelection import com.lambda.util.math.roundedBlockPos import com.lambda.util.text.buildText import com.lambda.util.text.highlighted @@ -31,7 +31,7 @@ import net.minecraft.util.math.Box data class StashContainer( val chests: Set, val pos: Box, -) : Container(ContainerRank.Stash) { +) : Container(ContainerType.Stash) { override val slots: List get() = chests.flatMap { it.slots } override var stacks: List diff --git a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt similarity index 56% rename from src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt rename to src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt index ef32c4633..39f72b7fa 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt @@ -15,10 +15,18 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory - -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank +package com.lambda.interaction.container.selection + +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerMarker +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.containers.ArmorContainer +import com.lambda.interaction.container.containers.CreativeContainer +import com.lambda.interaction.container.containers.CursorContainer +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer +import com.lambda.interaction.container.containers.OffHandContainer +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer /** * ContainerSelection is a class that holds a predicate for matching MaterialContainers. @@ -26,7 +34,9 @@ import com.lambda.interaction.inventory.container.ContainerRank @Suppress("unused") class ContainerSelection( val selector: (Container) -> Boolean, - val comparator: Comparator = compareBy { it.rank } + val containersWhitelist: Collection = emptyList(), + val accessedOnly: Boolean = false, + val comparator: Comparator = compareBy { it.type } ) { @ContainerMarker fun bestMatch(containers: Iterable) = filter(containers).firstOrNull() @@ -36,13 +46,29 @@ class ContainerSelection( @ContainerMarker fun filter(containers: Iterable) = - containers - .filter(selector) + run { + containersWhitelist + .takeIf { it.isNotEmpty() } + ?.filter { it in containers && (!accessedOnly || it.isAccessed) } + ?: containers + }.filter(selector) .sortedWith(comparator) companion object { val EVERYTHING = ContainerSelection({ true }) val NOTHING = ContainerSelection({ false }) + val HOTBAR_AND_INVENTORY = selectContainer { ofAny(HotbarContainer, InventoryContainer) } + val PLAYER = + selectContainer { + ofAny( + HotbarContainer, + InventoryContainer, + OffHandContainer, + CursorContainer, + ArmorContainer, + CreativeContainer + ) + } } } @@ -50,15 +76,22 @@ class ContainerSelection( @ContainerMarker class ContainerSelectionBuilder private constructor() { private var selector: (Container) -> Boolean = { true } - private var comparator: Comparator = compareBy { it.rank } + private var containersWhitelist = mutableListOf() + private var accessedOnly = false + private var comparator: Comparator = compareBy { it.type } private var invertNewSelectors = false - fun ofAnyType(vararg types: ContainerRank) { - appendSelector { container -> types.contains(container.rank) } + fun ofAny(vararg container: Container) { + containersWhitelist.addAll(container) + appendSelector { container -> container in containersWhitelist } + } + + fun ofAnyType(vararg types: ContainerType) { + appendSelector { container -> types.contains(container.type) } } - fun noneOfType(vararg types: ContainerRank) { - appendSelector { container -> !types.contains(container.rank) } + fun noneOfType(vararg types: ContainerType) { + appendSelector { container -> !types.contains(container.type) } } fun matches(stackSelection: StackSelection) { @@ -69,6 +102,11 @@ class ContainerSelectionBuilder private constructor() { appendSelector { container -> containerSelection.matches(container) } } + fun isAccessed() { + accessedOnly = true + appendSelector { it.isAccessed } + } + fun custom(predicate: (Container) -> Boolean) { appendSelector { predicate(it) } } @@ -93,7 +131,7 @@ class ContainerSelectionBuilder private constructor() { this.selector = { currentSelector(it) && selector(it) xor invert } } - private fun build() = ContainerSelection(selector, comparator) + private fun build() = ContainerSelection(selector, containersWhitelist, accessedOnly, comparator) companion object { fun selectContainer( diff --git a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt similarity index 91% rename from src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt rename to src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt index 9e27c08fd..b1c403288 100644 --- a/src/main/kotlin/com/lambda/interaction/inventory/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt @@ -15,9 +15,10 @@ * along with this program. If not, see . */ -package com.lambda.interaction.inventory +package com.lambda.interaction.container.selection -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.ContainerMarker +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils @@ -43,6 +44,7 @@ fun ItemStack.select(count: Int = 0) = selectStack(count) { isItemStack(this@sel @Suppress("unused") class StackSelection( + val whitelistedSlots: Collection = emptyList(), val count: Int = 0, val item: Item? = null, val itemStack: ItemStack? = null, @@ -54,6 +56,7 @@ class StackSelection( @ContainerMarker fun bestMatch(stacks: Iterable) = filter(stacks).firstOrNull() + @ContainerMarker fun bestMatch(slots: Iterable) = filter(slots).firstOrNull() @@ -61,6 +64,7 @@ class StackSelection( fun matches(stack: ItemStack) = if (inShulkerBox) stack.shulkerBoxStacks.any { selector(it, null) } else selector(stack, null) + @ContainerMarker fun matches(slot: Slot): Boolean = if (inShulkerBox) slot.stack.shulkerBoxStacks.any { selector(it, null) } @@ -70,14 +74,19 @@ class StackSelection( @JvmName("filter1") fun filter(stacks: Iterable) = stacks + .let { if (whitelistedSlots.isNotEmpty()) emptyList() else it } .filter(::matches) .map { StackAndSlot(it, null) } .sortedWith(comparator) .map { it.stack } + @ContainerMarker @JvmName("filter2") fun filter(slots: Iterable) = slots + .let { slots -> + if (whitelistedSlots.isNotEmpty()) whitelistedSlots.filter { it in slots } else slots + } .filter(::matches) .map { StackAndSlot(it.stack, it) } .sortedWith(comparator) @@ -92,6 +101,7 @@ class StackSelection( @Suppress("unused") @ContainerMarker class StackSelectionBuilder private constructor(private val count: Int = 0) { + private val whitelistedSlots = mutableListOf() private var selector: (ItemStack, Slot?) -> Boolean = { _, _ -> true } private var item: Item? = null private var stackByRef = false @@ -133,7 +143,7 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { } fun isShulkerBox() { - appendSelector { stack, _ -> stack.item in ItemUtils.shulkerBoxes } + appendSelector { stack, _ -> stack.item in ItemUtils.SHULKER_BOXES } } fun hasCustomName(name: String) { @@ -153,7 +163,7 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { fun isEfficientForBreaking(blockState: BlockState) { appendSelector { itemStack, _ -> val hasEfficientTool = efficientToolCache.getOrPut(blockState) { - ItemUtils.tools.any { it.getMiningSpeed(it.defaultStack, blockState) > 1f } + ItemUtils.TOOLS.any { it.getMiningSpeed(it.defaultStack, blockState) > 1f } } if (hasEfficientTool) itemStack.item.getMiningSpeed(itemStack, blockState) > 1f else true @@ -208,12 +218,11 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { } fun isSlot(slot: Slot) { - appendSelector { _, s -> - s != null && s matches slot - } + appendSelector { _, s -> s != null && s matches slot } } fun isSlotByReference(slot: Slot) { + whitelistedSlots.add(slot) appendSelector { _, s -> s === slot } } @@ -268,6 +277,7 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { private fun build() = StackSelection( + whitelistedSlots, count, item, itemStack, diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index c21085f12..1740a2eea 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -18,31 +18,31 @@ package com.lambda.interaction.handler.handlers import com.lambda.context.Automated -import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.core.Loadable import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PacketEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ContainerMarker +import com.lambda.interaction.container.PlacedContainer +import com.lambda.interaction.container.containers.external.ChestContainer +import com.lambda.interaction.container.containers.external.DoubleChestContainer +import com.lambda.interaction.container.containers.external.EnderChestContainer +import com.lambda.interaction.container.containers.external.PlacedShulkerBoxContainer +import com.lambda.interaction.container.containers.external.ShulkerBoxContainer +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.StackSelection +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.ContainerHandler.filteredContainers -import com.lambda.interaction.inventory.ContainerMarker -import com.lambda.interaction.inventory.ContainerSelection -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.PlacedContainer -import com.lambda.interaction.inventory.container.containers.external.ChestContainer -import com.lambda.interaction.inventory.container.containers.external.DoubleChestContainer -import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer -import com.lambda.interaction.inventory.container.containers.external.PlacedShulkerBoxContainer -import com.lambda.interaction.inventory.container.containers.external.ShulkerBoxContainer -import com.lambda.interaction.inventory.select import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.BlockUtils.blockState import com.lambda.util.ReflectionUtils.getInstances import com.lambda.util.extension.containerStacks import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks -import com.lambda.util.item.ItemUtils.shulkerBoxes +import com.lambda.util.item.ItemUtils.SHULKER_BOXES import com.lambda.util.player.SlotUtils.typeSafe import net.minecraft.block.ChestBlock import net.minecraft.block.entity.BlockEntity @@ -60,7 +60,7 @@ import net.minecraft.util.math.ChunkPos @Suppress("unused") object ContainerHandler : Loadable { - private val containers: Sequence + val containers: Sequence get() { fun Container.allNested(): Sequence = sequence { @@ -82,9 +82,6 @@ object ContainerHandler : Loadable { .filter { automated.inventoryConfig.containerSelection.matches(it) } .sorted() - val allContainers - get() = containers.sorted() - var lastInteractedBlockEntity: BlockEntity? = null var pendingInteractedBlockEntity: BlockEntity? = null @@ -158,7 +155,7 @@ object ContainerHandler : Loadable { val state = blockEntity.cachedState if (state.block !is ChestBlock) return - val stacks = blockEntity.stacks + val stacks = blockEntity.stacks() val chestType = state.get(Properties.CHEST_TYPE) ?: return val chunkPos = ChunkPos(pos) @@ -199,7 +196,7 @@ object ContainerHandler : Loadable { is ShulkerBoxBlockEntity -> { if (sh.typeSafe != ScreenHandlerType.SHULKER_BOX) return - val stacks = blockEntity.stacks + val stacks = blockEntity.stacks() val chunkPos = ChunkPos(pos) (chunkPos.getPlacedContainer(pos) as? PlacedShulkerBoxContainer) ?.update(stacks) @@ -219,7 +216,7 @@ object ContainerHandler : Loadable { slots.forEach { slot -> val stack = slot.stack val index = slot.index - if (stack.item in shulkerBoxes) { + if (stack.item in SHULKER_BOXES) { storedContainers[index] = ShulkerBoxContainer( stack.name.string, @@ -242,33 +239,25 @@ object ContainerHandler : Loadable { private fun ChunkPos.setPlacedContainer(pos: BlockPos, container: PlacedContainer) = placedContainers.getOrPut(this) { mutableMapOf() }.put(pos, container) - private val Inventory.stacks - get() = iterator().asSequence().toList() + private fun Inventory.stacks() = iterator().asSequence().toList() } -@ContainerMarker -context(automatedSafeContext: AutomatedSafeContext) -fun StackSelection.move(destination: Container) = - with(automatedSafeContext) { - findContainer(inventoryConfig.containerSelection) - ?.move(this@move, destination) - ?: false - } - @ContainerMarker context(_: Automated) -fun findContainer(predicate: (Container) -> Boolean) = filteredContainers.find(predicate) +fun findContainer( + selection: ContainerSelection +) = filteredContainers.find(selection) @ContainerMarker context(automated: Automated) fun StackSelection.findContainer( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection -) = findContainers(containerSelection).firstOrNull() + selection: ContainerSelection = ContainerSelection.EVERYTHING +) = findContainers(selection).firstOrNull() @ContainerMarker context(automated: Automated) fun StackSelection.findContainers( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING ) = filteredContainers .filter { containerSelection.matches(it) } .filter { it.stackCount(this) >= count } @@ -277,33 +266,50 @@ fun StackSelection.findContainers( @ContainerMarker context(automated: Automated) fun StackSelection.findContainerWithSpace( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING ) = findContainersWithSpace(containerSelection).firstOrNull() @ContainerMarker context(automated: Automated) fun StackSelection.findContainersWithSpace( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING ) = filteredContainers .filter { containerSelection.matches(it) } .filter { it.spaceAvailable(this) >= count } .sortedWith(automated.inventoryConfig.accessPriority.spaceComparator(this)) -@ContainerMarker -context(automated: Automated) -fun StackSelection.findSlot( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection -) = findSlots(containerSelection).firstOrNull() - @ContainerMarker context(automated: Automated) fun StackSelection.findSlots( - containerSelection: ContainerSelection = automated.inventoryConfig.containerSelection -) = findContainers(containerSelection).flatMap { filter(it.slots) } + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +) = + findContainers( + selectContainer { + matches(containerSelection) + isAccessed() + } + ).flatMap { filter(it.slots) } @ContainerMarker context(automated: Automated) -fun findDisposable() = - filteredContainers.find { container -> - automated.inventoryConfig.disposables.any { container.stackCount(it.asItem().select(1)) > 0 } - } \ No newline at end of file +fun findContainerWithDisposable( + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +) = + with(automated) { + findContainer( + selectContainer { + matches(containerSelection) + custom { container -> + inventoryConfig.disposables.any { container.stackCount(it.asItem().select(1)) > 0 } + } + } + ) + } + +private fun getSearchContainers(scope: ContainerSearchScope): Collection { + +} + +private enum class ContainerSearchScope { + +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt index 56fe6eb36..87225c54f 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt @@ -20,9 +20,8 @@ package com.lambda.interaction.handler.handlers import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.StackAndSlot -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.container.selection.StackAndSlot +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.modules.movement.elytrafly.ElytraFly import com.lambda.module.modules.movement.elytrafly.ElytraFly.mode @@ -171,10 +170,8 @@ object GlideHandler { val fakeFly = ElytraFly.isEnabled && ElytraFly.fakeFly val canGlideAlready = player.canGlideWithChestPiece() != fakeFly if (!autoSwapChecking || canGlideAlready) return canGlideAlready - return HotbarAndInventoryContainer.slots.let { slots -> - if (fakeFly) CHESTPLATE_SELECTION.filter(slots).isNotEmpty() - else ELYTRA_SELECTION.filter(slots).isNotEmpty() - } + val selection = if (fakeFly) CHESTPLATE_SELECTION else ELYTRA_SELECTION + return selection.findContainers(HOTBAR_AND_INVENTORY_CONTAINERS) } private class PendingGlideAction( diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt deleted file mode 100644 index 44a6de2b4..000000000 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/HotbarAndInventoryContainer.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2026 Lambda - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.lambda.interaction.inventory.container.containers - -import com.lambda.Lambda.mc -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.util.player.SlotUtils.hotbarAndInventorySlots -import com.lambda.util.player.SlotUtils.hotbarAndInventoryStacks -import com.lambda.util.text.buildText -import com.lambda.util.text.literal -import net.minecraft.item.ItemStack -import net.minecraft.screen.slot.Slot - -object HotbarAndInventoryContainer : Container(ContainerRank.HotbarAndInventory) { - override val slots: List - get() = mc.player?.hotbarAndInventorySlots ?: emptyList() - override var stacks: List - get() = mc.player?.hotbarAndInventoryStacks ?: emptyList() - set(_) {} - - override val description = buildText { literal("Hotbar and Inventory") } -} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt b/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt deleted file mode 100644 index 39bcc95b7..000000000 --- a/src/main/kotlin/com/lambda/interaction/inventory/container/containers/MainHandContainer.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2026 Lambda - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.lambda.interaction.inventory.container.containers - -import com.lambda.Lambda.mc -import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ContainerRank -import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder -import com.lambda.util.player.SlotUtils.mainHandSlots -import com.lambda.util.text.buildText -import com.lambda.util.text.literal -import net.minecraft.item.ItemStack -import net.minecraft.screen.slot.Slot - -object MainHandContainer : Container(ContainerRank.MainHand) { - override val slots: List - get() = mc.player?.mainHandSlots ?: emptyList() - override var stacks: List - get() = mc.player?.mainHandStack?.let { listOf(it) } ?: emptyList() - set(_) {} - - override val swapMethodPriority = 10 - - override val description = buildText { literal("MainHand") } - - context(safeContext: SafeContext) - override fun InvRequestBuilder.swap(fromHere: Slot, toSlot: Slot) { - swapWithHotbar(toSlot.id, safeContext.player.inventory.selectedSlot) - } -} diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt index 33c04927c..64ab9cd82 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt @@ -34,6 +34,7 @@ import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.pendingActions @@ -43,7 +44,6 @@ import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.getRebrea import com.lambda.interaction.handler.handlers.breaking.RebreakResult import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler import com.lambda.interaction.handler.handlers.packet.PacketType -import com.lambda.interaction.inventory.StackSelection import com.lambda.interaction.manager.Manager import com.lambda.interaction.manager.ManagerUtils.isPosBlocked import com.lambda.interaction.manager.PositionBlocking diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt index b338e2602..bbb40e5ce 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt @@ -25,8 +25,7 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.container.containers.ArmorContainer -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer +import com.lambda.interaction.container.containers.ArmorContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index ee8fe19c6..40ff8980a 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -23,8 +23,9 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.FriendHandler -import com.lambda.interaction.inventory.select +import com.lambda.interaction.inventory.container.select import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index bff695058..09a6e4a44 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -27,10 +27,9 @@ import com.lambda.context.SafeContext import com.lambda.event.events.EntityEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handler.handlers.move -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.OffHandContainer +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.OffHandContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.interaction.manager.managers.rotating.RotationManager diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index 5f9713ab1..8bee87050 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -28,8 +28,8 @@ import com.lambda.context.SafeContext import com.lambda.event.events.InventoryEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index 1f949ba97..761c0bf67 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -25,7 +25,6 @@ import com.lambda.context.SafeContext import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handler.handlers.FriendHandler.isFriend -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.Task diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt index d54b1285d..fe24c73f8 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt @@ -23,7 +23,6 @@ import com.lambda.config.hideBlock import com.lambda.config.withEdits import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.module.Module import com.lambda.module.modules.combat.PlayerTrap.getTrapPositions import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index d4b479b3c..5bcea7fb9 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.select +import com.lambda.interaction.container.selection.select import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.start diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 679ed9a6d..2298bf1f2 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -28,12 +28,11 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.GlideHandler -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.inventory.select import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt index c13b358c9..c2f816622 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt @@ -24,9 +24,8 @@ import com.lambda.event.Muteable import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.containers.ArmorContainer import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION -import com.lambda.interaction.inventory.container.containers.ArmorContainer -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt index e435fdf57..bf3bc8b28 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/GrimControlElytraFly.kt @@ -22,9 +22,9 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.PlayerPacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.inventory.select +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer +import com.lambda.interaction.container.selection.select import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.modules.movement.BetterFirework.startFirework diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt index 92fc44463..2bde07f67 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt @@ -18,12 +18,11 @@ package com.lambda.module.modules.player import com.lambda.context.SafeContext +import com.lambda.interaction.container.containers.ArmorContainer import com.lambda.interaction.handler.handlers.GlideHandler.CHESTPLATE_SELECTION import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION import com.lambda.interaction.handler.handlers.GlideHandler.manuallySwapped import com.lambda.interaction.handler.handlers.GlideHandler.swapped -import com.lambda.interaction.inventory.container.containers.ArmorContainer -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.modules.combat.AutoArmor diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index ce8c6a92d..cb82dbc01 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -23,20 +23,21 @@ import com.lambda.config.withEdits import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.NestedContainer +import com.lambda.interaction.container.OpenedContainerContext +import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.interaction.handler.handlers.ContainerHandler -import com.lambda.interaction.inventory.container.NestedContainer -import com.lambda.interaction.inventory.container.OpenedContainerContext -import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.wrappers.then -import com.lambda.util.item.ItemUtils.shulkerBoxes +import com.lambda.util.item.ItemUtils.SHULKER_BOXES import net.minecraft.item.Items import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.SlotActionType import java.util.* +import kotlin.collections.fold @Suppress("unused") object InventoryTweaks : Module( @@ -63,7 +64,7 @@ object InventoryTweaks : Module( val stack = slot.stack when (stack.item) { - in shulkerBoxes if (!instantShulker) -> return@listen + in SHULKER_BOXES if (!instantShulker) -> return@listen Items.ENDER_CHEST if (!instantEChest) -> return@listen } diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index dabfd131b..fb411189d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -24,8 +24,8 @@ import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt index c7746137b..77de50df6 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt @@ -23,8 +23,8 @@ import com.lambda.config.withEdits import com.lambda.event.events.ContainerEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt index deef6f9ce..66634e981 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt @@ -21,7 +21,7 @@ import com.lambda.Lambda.mc import com.lambda.config.Tab import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.config.settings.complex.Bind -import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer +import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe @@ -29,8 +29,8 @@ import com.lambda.util.InputUtils.isSatisfied import com.lambda.util.KeyCode import com.lambda.util.item.ItemStackUtils.bundleStacks import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks -import com.lambda.util.item.ItemUtils.bundles -import com.lambda.util.item.ItemUtils.shulkerBoxes +import com.lambda.util.item.ItemUtils.BUNDLES +import com.lambda.util.item.ItemUtils.SHULKER_BOXES import com.lambda.util.text.buildText import com.lambda.util.text.literal import net.minecraft.block.ShulkerBoxBlock @@ -379,7 +379,7 @@ object ContainerPreview : Module( } @JvmStatic - fun isShulkerBox(stack: ItemStack) = stack.item in shulkerBoxes + fun isShulkerBox(stack: ItemStack) = stack.item in SHULKER_BOXES @JvmStatic fun isEnderChest(stack: ItemStack) = stack.item == Items.ENDER_CHEST && EnderChestContainer.stacks.isNotEmpty() @@ -388,7 +388,7 @@ object ContainerPreview : Module( fun isPreviewableContainer(stack: ItemStack) = isShulkerBox(stack) || isEnderChest(stack) @JvmStatic - fun isBundle(stack: ItemStack) = stack.item in bundles + fun isBundle(stack: ItemStack) = stack.item in BUNDLES @JvmStatic fun drawOnItem(drawContext: DrawContext, state: GuiRenderState, entity: LivingEntity?, world: World?, stack: ItemStack, x: Int, y: Int, seed: Int) { diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index 4fa82ba7f..e9154a9f8 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -35,10 +35,9 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.util.DirectionMask import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module diff --git a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt index 4c6ed0869..7ced3f6a3 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt @@ -19,7 +19,6 @@ package com.lambda.module.modules.world import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.container.containers.PlayerContainer import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.FileUtils.locationBoundDirectory diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index dd30460a3..b0e8f5c6d 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -30,8 +30,8 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState -import com.lambda.interaction.inventory.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.inventory.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.module.Module import com.lambda.module.tag.ModuleTag diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index e3b98d24f..804f3648d 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -38,12 +38,11 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer +import com.lambda.interaction.container.containers.OffHandContainer +import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer -import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.InventoryContainer -import com.lambda.interaction.inventory.container.containers.OffHandContainer -import com.lambda.interaction.inventory.container.containers.external.EnderChestContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.interaction.manager.managers.rotating.Rotation diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt index 1bef1abf5..71c0fb03b 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -21,8 +21,8 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.findSlots -import com.lambda.interaction.inventory.select import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.wrappers.softFail diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index e50591500..e8db24cd2 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -19,9 +19,9 @@ package com.lambda.task.tasks import com.lambda.context.Automated import com.lambda.context.SafeContext +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.handler.handlers.findContainer -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.containers.HotbarContainer import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.threading.runSafeAutomated diff --git a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt index 7287e2c89..c165f9000 100644 --- a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt @@ -23,7 +23,6 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index 65d05f7d6..275a02318 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -21,12 +21,12 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.Container +import com.lambda.interaction.container.ExternalContainer +import com.lambda.interaction.container.OpenedContainerContext +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.handler.handlers.findContainer -import com.lambda.interaction.inventory.StackSelection -import com.lambda.interaction.inventory.container.Container -import com.lambda.interaction.inventory.container.ExternalContainer -import com.lambda.interaction.inventory.container.OpenedContainerContext -import com.lambda.interaction.inventory.container.containers.HotbarAndInventoryContainer import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.wrappers.taskOrNull @@ -38,54 +38,53 @@ import net.minecraft.screen.slot.Slot @Ta5kBuilder context(automated: Automated) fun transfer( - stackSelection: StackSelection, - fromContainer: Container, - toContainer: Container -) = ContainerTransferTask(fromContainer, toContainer, stackSelection, automated) - -@Ta5kBuilder -@JvmName("transferByStackSelection") -context(automated: Automated) -fun transfer( - stackSelection: StackSelection, - toContainer: Container -) = transfer(stackSelection, stackSelection.findContainer() ?: HotbarAndInventoryContainer, toContainer) + selection: StackSelection, + fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, + toSelection: ContainerSelection +) = ContainerTransferTask(selection, fromSelection, toSelection, automated) @Ta5kBuilder @JvmName("transferExt") context(automated: Automated) fun StackSelection.transferTo( - toContainer: Container -) = transfer(this, findContainer() ?: HotbarAndInventoryContainer, toContainer) + fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, + toSelection: ContainerSelection +) = transfer(this, fromSelection, toSelection) class ContainerTransferTask @Ta5kBuilder internal constructor( - private var fromContainer: Container, - private val toContainer: Container, private val selection: StackSelection, + private val fromSelection: ContainerSelection, + private val toSelection: ContainerSelection, automated: Automated ) : Task(), Automated by automated { - override val name = "Transferring $selection from $fromContainer to $toContainer" + override val name = "Transferring $selection from $fromSelection to $toSelection" override fun SafeContext.onStart() { + val fromContainer = findContainer(containerSelection) + ?: run { + failure(IllegalStateException("Could not find container to pull $selection from")) + return + } when { fromContainer.isAccessed && toContainer.isAccessed -> TransferTask() .onSuccess { success(it) } fromContainer !is ExternalContainer -> - openTransferClose(toContainer, fromContainer, toContainer) + openTransferClose(toContainer, toContainer, containerSelection) toContainer !is ExternalContainer -> - openTransferClose(fromContainer, fromContainer, toContainer) + openTransferClose(fromContainer, toContainer, containerSelection) - else -> + else -> { taskOrNull { fromContainer.access() } .then { fromCtx -> - transfer(selection, fromContainer, HotbarAndInventoryContainer) + transfer(selection, toContainer, ContainerSelection.HOTBAR_AND_INVENTORY) .thenOrNull { fromCtx?.close() } } .thenOrNull { toContainer.access() } - .then { toCtx -> transferAndClose(toCtx, HotbarAndInventoryContainer, toContainer) } + .then { toCtx -> transferAndClose(toCtx, toContainer, ContainerSelection.HOTBAR_AND_INVENTORY) } + } }?.start() } @@ -95,49 +94,76 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( * Used when exactly one of the two containers is external and needs to be accessed. */ @Ta5kBuilder - private fun openTransferClose(containerToOpen: Container, from: Container, to: Container) = - containerToOpen - .access() - ?.then { ctx -> transferAndClose(ctx, from, to) } + private fun openTransferClose( + containerToOpen: Container, + to: Container, + containerSelection: ContainerSelection + ) = containerToOpen + .access() + ?.then { ctx -> transferAndClose(ctx, to, containerSelection) } /** * Transfers [selection] from [from] to [to], then closes the container via [ctx]. */ @Ta5kBuilder - private fun transferAndClose(ctx: OpenedContainerContext?, from: Container, to: Container) = - transfer(selection, from, to) - .thenOrNull { slot -> - ctx - ?.close() - ?.onSuccess { success(slot) } - } + private fun transferAndClose( + ctx: OpenedContainerContext?, + fromSelection: ContainerSelection, + toSelection: ContainerSelection + ) = transfer(selection, fromSelection, toSelection) + .thenOrNull { slot -> + ctx + ?.close() + ?.onSuccess { success(slot) } + } private inner class TransferTask @Ta5kBuilder constructor() : Task() { override val name = "Transferring" + private var transferred = 0 + private var lastSlot: Slot? = null + init { listen { runSafeAutomated { - val (fromSlot, toSlot) = fromContainer.getTransferSlots(selection, toContainer) - if (fromSlot == null) { - checkFail() - return@listen + while (selection.count == 0 || transferred < selection.count) { + val (fromSlot, toSlot) = fromContainer.getTransferSlots(selection, toContainer) + + if (fromSlot == null || toSlot == null) { + lastSlot?.let { slot -> + if (selection.count == 0 || transferred >= selection.count) { + success(slot) + return@listen + } + } + if (fromSlot == null) checkFail() + else failure("Unable to find a slot to transfer to.") + return@listen + } + + val moveCount = fromSlot.stack.count + if (!fromContainer.swap(fromSlot, toSlot, toContainer)) { + checkFail() + return@listen + } + + transferred += moveCount + lastSlot = toSlot + + // count == 0 means single stack transfer + if (selection.count == 0) { + success(toSlot) + return@listen + } } - if (toSlot == null) { - failure("Unable to find a slot to transfer to.") - return@listen - } - val transferSuccessful = fromContainer.swap(fromSlot, toSlot, toContainer) - if (transferSuccessful) success(toSlot) - else checkFail() + + lastSlot?.let { success(it) } ?: checkFail() } } } private fun checkFail() { - failure(NoMaterialAccessException(selection)) + failure(IllegalStateException("Unable to access $selection")) } - - private inner class NoMaterialAccessException(stackSelection: StackSelection) : IllegalStateException("Unable to access $stackSelection.") } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index 33fa0172e..088a8e79c 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -23,8 +23,8 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.inventory.container.containers.HotbarContainer -import com.lambda.interaction.inventory.container.containers.InventoryContainer +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder diff --git a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt index 9311f9a5b..58a1f0c88 100644 --- a/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/PlaceContainerTask.kt @@ -30,7 +30,7 @@ import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockPos -import com.lambda.util.item.ItemUtils.shulkerBoxes +import com.lambda.util.item.ItemUtils.SHULKER_BOXES import com.lambda.util.math.distSq import net.minecraft.block.ChestBlock import net.minecraft.entity.mob.ShulkerEntity @@ -99,7 +99,7 @@ class PlaceContainerTask @Ta5kBuilder internal constructor( Items.ENDER_CHEST -> { !ChestBlock.isChestBlocked(world, blockPos) } - in shulkerBoxes -> { + in SHULKER_BOXES -> { val box = ShulkerEntity .calculateBoundingBox(0.5f, direction, 0.0f, blockPos.toBottomCenterPos()) .offset(blockPos) diff --git a/src/main/kotlin/com/lambda/util/item/ItemUtils.kt b/src/main/kotlin/com/lambda/util/item/ItemUtils.kt index a3485c5ea..361a26c8e 100644 --- a/src/main/kotlin/com/lambda/util/item/ItemUtils.kt +++ b/src/main/kotlin/com/lambda/util/item/ItemUtils.kt @@ -17,8 +17,7 @@ package com.lambda.util.item -import com.lambda.context.SafeContext -import com.lambda.interaction.inventory.container.containers.ArmorContainer +import com.lambda.interaction.container.containers.ArmorContainer import net.minecraft.block.Block import net.minecraft.component.DataComponentTypes import net.minecraft.item.BlockItem @@ -27,128 +26,142 @@ import net.minecraft.item.ItemStack import net.minecraft.item.Items object ItemUtils { - val pickaxes = setOf( - Items.WOODEN_PICKAXE, - Items.STONE_PICKAXE, - Items.IRON_PICKAXE, - Items.GOLDEN_PICKAXE, - Items.DIAMOND_PICKAXE, - Items.NETHERITE_PICKAXE, - ) - - val shovels = setOf( - Items.WOODEN_SHOVEL, - Items.STONE_SHOVEL, - Items.IRON_SHOVEL, - Items.GOLDEN_SHOVEL, - Items.DIAMOND_SHOVEL, - Items.NETHERITE_SHOVEL, - ) - - val axes = setOf( - Items.WOODEN_AXE, - Items.STONE_AXE, - Items.IRON_AXE, - Items.GOLDEN_AXE, - Items.DIAMOND_AXE, - Items.NETHERITE_AXE, - ) - - val hoes = setOf( - Items.WOODEN_HOE, - Items.STONE_HOE, - Items.IRON_HOE, - Items.GOLDEN_HOE, - Items.DIAMOND_HOE, - Items.NETHERITE_HOE, - ) - - val swords = setOf( - Items.WOODEN_SWORD, - Items.STONE_SWORD, - Items.IRON_SWORD, - Items.GOLDEN_SWORD, - Items.DIAMOND_SWORD, - Items.NETHERITE_SWORD, - ) - - val misc = setOf( - Items.SHEARS, - Items.FLINT_AND_STEEL, - ) - - val tools = pickaxes + shovels + axes + hoes + swords + misc - - val shulkerBoxes = setOf( - Items.SHULKER_BOX, - Items.WHITE_SHULKER_BOX, - Items.ORANGE_SHULKER_BOX, - Items.MAGENTA_SHULKER_BOX, - Items.LIGHT_BLUE_SHULKER_BOX, - Items.YELLOW_SHULKER_BOX, - Items.LIME_SHULKER_BOX, - Items.PINK_SHULKER_BOX, - Items.GRAY_SHULKER_BOX, - Items.LIGHT_GRAY_SHULKER_BOX, - Items.CYAN_SHULKER_BOX, - Items.PURPLE_SHULKER_BOX, - Items.BLUE_SHULKER_BOX, - Items.BROWN_SHULKER_BOX, - Items.GREEN_SHULKER_BOX, - Items.RED_SHULKER_BOX, - Items.BLACK_SHULKER_BOX, - ) - - val bundles = setOf( - Items.BUNDLE, - Items.WHITE_BUNDLE, - Items.ORANGE_BUNDLE, - Items.MAGENTA_BUNDLE, - Items.LIGHT_BLUE_BUNDLE, - Items.YELLOW_BUNDLE, - Items.LIME_BUNDLE, - Items.PINK_BUNDLE, - Items.GRAY_BUNDLE, - Items.LIGHT_GRAY_BUNDLE, - Items.CYAN_BUNDLE, - Items.PURPLE_BUNDLE, - Items.BLUE_BUNDLE, - Items.BROWN_BUNDLE, - Items.GREEN_BUNDLE, - Items.RED_BUNDLE, - Items.BLACK_BUNDLE - ) - - val chests = setOf( - Items.CHEST, - Items.TRAPPED_CHEST, - Items.ENDER_CHEST, - Items.BARREL, - ) - - val defaultDisposables = setOf( - Items.DIRT, - Items.GRASS_BLOCK, - Items.COBBLESTONE, - Items.GRANITE, - Items.DIORITE, - Items.ANDESITE, - Items.SANDSTONE, - Items.RED_SANDSTONE, - Items.NETHERRACK, - Items.END_STONE, - Items.STONE, - Items.BASALT, - Items.BLACKSTONE, - Items.COBBLED_DEEPSLATE - ) + val PICKAXES = + setOf( + Items.WOODEN_PICKAXE, + Items.STONE_PICKAXE, + Items.COPPER_PICKAXE, + Items.IRON_PICKAXE, + Items.GOLDEN_PICKAXE, + Items.DIAMOND_PICKAXE, + Items.NETHERITE_PICKAXE, + ) + + val SHOVELS = + setOf( + Items.WOODEN_SHOVEL, + Items.STONE_SHOVEL, + Items.COPPER_SHOVEL, + Items.IRON_SHOVEL, + Items.GOLDEN_SHOVEL, + Items.DIAMOND_SHOVEL, + Items.NETHERITE_SHOVEL, + ) + + val AXES = + setOf( + Items.WOODEN_AXE, + Items.STONE_AXE, + Items.COPPER_AXE, + Items.IRON_AXE, + Items.GOLDEN_AXE, + Items.DIAMOND_AXE, + Items.NETHERITE_AXE, + ) + + val HOES = + setOf( + Items.WOODEN_HOE, + Items.STONE_HOE, + Items.COPPER_HOE, + Items.IRON_HOE, + Items.GOLDEN_HOE, + Items.DIAMOND_HOE, + Items.NETHERITE_HOE, + ) + + val SWORDS = + setOf( + Items.WOODEN_SWORD, + Items.STONE_SWORD, + Items.COPPER_SWORD, + Items.IRON_SWORD, + Items.GOLDEN_SWORD, + Items.DIAMOND_SWORD, + Items.NETHERITE_SWORD, + ) + + val MISC = + setOf( + Items.SHEARS, + Items.FLINT_AND_STEEL, + ) + + val TOOLS = PICKAXES + SHOVELS + AXES + HOES + SWORDS + MISC + + val SHULKER_BOXES = + setOf( + Items.SHULKER_BOX, + Items.WHITE_SHULKER_BOX, + Items.ORANGE_SHULKER_BOX, + Items.MAGENTA_SHULKER_BOX, + Items.LIGHT_BLUE_SHULKER_BOX, + Items.YELLOW_SHULKER_BOX, + Items.LIME_SHULKER_BOX, + Items.PINK_SHULKER_BOX, + Items.GRAY_SHULKER_BOX, + Items.LIGHT_GRAY_SHULKER_BOX, + Items.CYAN_SHULKER_BOX, + Items.PURPLE_SHULKER_BOX, + Items.BLUE_SHULKER_BOX, + Items.BROWN_SHULKER_BOX, + Items.GREEN_SHULKER_BOX, + Items.RED_SHULKER_BOX, + Items.BLACK_SHULKER_BOX, + ) + + val BUNDLES = + setOf( + Items.BUNDLE, + Items.WHITE_BUNDLE, + Items.ORANGE_BUNDLE, + Items.MAGENTA_BUNDLE, + Items.LIGHT_BLUE_BUNDLE, + Items.YELLOW_BUNDLE, + Items.LIME_BUNDLE, + Items.PINK_BUNDLE, + Items.GRAY_BUNDLE, + Items.LIGHT_GRAY_BUNDLE, + Items.CYAN_BUNDLE, + Items.PURPLE_BUNDLE, + Items.BLUE_BUNDLE, + Items.BROWN_BUNDLE, + Items.GREEN_BUNDLE, + Items.RED_BUNDLE, + Items.BLACK_BUNDLE + ) + + val CHESTS = + setOf( + Items.CHEST, + Items.COPPER_CHEST, + Items.TRAPPED_CHEST, + Items.ENDER_CHEST + ) + + val DEFAULT_DISPOSABLES = + setOf( + Items.DIRT, + Items.GRASS_BLOCK, + Items.COBBLESTONE, + Items.GRANITE, + Items.DIORITE, + Items.ANDESITE, + Items.SANDSTONE, + Items.RED_SANDSTONE, + Items.NETHERRACK, + Items.END_STONE, + Items.STONE, + Items.BASALT, + Items.BLACKSTONE, + Items.COBBLED_DEEPSLATE + ) val Item.block: Block get() = Block.getBlockFromItem(this) val ItemStack.blockItem get() = item as? BlockItem val Item.nutrition: Int get() = components.get(DataComponentTypes.FOOD)?.nutrition ?: 0 - context(safeContext: SafeContext) val ItemStack.armorSlot get() = ArmorContainer.slots.firstOrNull { it.canInsert(this) } From b7dfcded22ab61267ac88dc63559800557802c63 Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Tue, 8 Sep 2026 15:27:58 +0100 Subject: [PATCH 14/18] checkpoint --- .../mixin/entity/LivingEntityMixin.java | 1 - .../command/commands/TransferCommand.kt | 62 +-- .../kotlin/com/lambda/config/ConfigEditor.kt | 2 +- .../config/automation/AutomationConfig.kt | 30 +- .../lambda/config/blocks/InventoryConfig.kt | 8 +- .../com/lambda/config/entries/Setting.kt | 61 +-- .../serializers/PlacedContainerSerializer.kt | 115 ++++ .../graphics/mc/renderer/ChunkedRenderer.kt | 8 +- .../com/lambda/graphics/text/FontHandler.kt | 2 +- src/main/kotlin/com/lambda/gui/MenuBar.kt | 2 +- .../lambda/gui/components/ClickGuiLayout.kt | 9 +- .../simulation/result/results/BreakResult.kt | 5 +- .../result/results/GenericResult.kt | 5 +- .../construction/simulation/sims/BreakSim.kt | 3 +- .../simulation/sims/InteractSim.kt | 20 +- .../construction/verify/TargetState.kt | 19 +- .../lambda/interaction/container/Container.kt | 73 ++- .../container/ContainerSerializer.kt | 115 ++++ .../container/containers/ArmorContainer.kt | 2 +- .../container/containers/CreativeContainer.kt | 39 +- .../container/containers/CursorContainer.kt | 2 +- .../external/ShulkerBoxContainer.kt | 21 +- .../containers/external/StashContainer.kt | 13 +- .../container/selection/ContainerSelection.kt | 68 ++- .../container/selection/StackSelection.kt | 38 +- .../handler/handlers/BaritoneHandler.kt | 2 +- .../handler/handlers/ContainerHandler.kt | 513 ++++++++++-------- .../handler/handlers/GlideHandler.kt | 10 +- .../InteractedBlockHandler.kt | 6 +- .../{packet => }/PacketLimitHandler.kt | 2 +- .../handlers/breaking/RebreakHandler.kt | 4 +- .../manager/managers/breaking/BreakManager.kt | 4 +- .../managers/interacting/InteractManager.kt | 8 +- .../managers/inventory/InventoryManager.kt | 6 +- .../container/containers/ChestContainer.kt | 0 .../containers/EnderChestContainer.kt | 0 .../containers/ShulkerBoxContainer.kt | 0 .../kotlin/com/lambda/module/HudModule.kt | 2 +- src/main/kotlin/com/lambda/module/Module.kt | 5 +- .../com/lambda/module/{tag => }/ModuleTag.kt | 6 +- .../com/lambda/module/hud/AccountName.kt | 2 +- .../kotlin/com/lambda/module/hud/Baritone.kt | 2 +- .../com/lambda/module/hud/Coordinates.kt | 2 +- src/main/kotlin/com/lambda/module/hud/Fps.kt | 2 +- .../com/lambda/module/hud/ModuleList.kt | 2 +- .../kotlin/com/lambda/module/hud/Rotation.kt | 2 +- .../com/lambda/module/hud/Speedometer.kt | 2 +- .../com/lambda/module/hud/TaskFlowHud.kt | 2 +- src/main/kotlin/com/lambda/module/hud/Tps.kt | 2 +- .../kotlin/com/lambda/module/hud/Watermark.kt | 2 +- .../lambda/module/modules/chat/AntiSpam.kt | 2 +- .../module/modules/chat/ChatTimestamp.kt | 4 +- .../lambda/module/modules/chat/CustomChat.kt | 2 +- .../lambda/module/modules/chat/FancyChat.kt | 2 +- .../module/modules/chat/FriendHighlight.kt | 4 +- .../module/modules/client/AutoUpdater.kt | 2 +- .../com/lambda/module/modules/client/Capes.kt | 2 +- .../lambda/module/modules/client/Client.kt | 2 +- .../lambda/module/modules/client/Discord.kt | 2 +- .../module/modules/client/ModuleNotifier.kt | 2 +- .../lambda/module/modules/combat/AutoArmor.kt | 30 +- .../lambda/module/modules/combat/AutoTotem.kt | 3 +- .../lambda/module/modules/combat/Criticals.kt | 2 +- .../module/modules/combat/CrystalAura.kt | 45 +- .../module/modules/combat/FakePlayer.kt | 2 +- .../lambda/module/modules/combat/KillAura.kt | 4 +- .../module/modules/combat/PlayerTrap.kt | 41 +- .../lambda/module/modules/combat/Surround.kt | 22 +- .../combat/autodisconnect/AutoDisconnect.kt | 2 +- .../module/modules/debug/BaritoneTest.kt | 2 +- .../lambda/module/modules/debug/BlockTest.kt | 2 +- .../module/modules/debug/ContainerTest.kt | 2 +- .../modules/debug/DebugRendererModule.kt | 2 +- .../lambda/module/modules/debug/FallTest.kt | 2 +- .../module/modules/debug/InventoryDebug.kt | 2 +- .../module/modules/debug/PropertyPrinter.kt | 2 +- .../lambda/module/modules/debug/RenderTest.kt | 2 +- .../modules/debug/RendererTestModule.kt | 2 +- .../module/modules/debug/RotationTest.kt | 2 +- .../modules/debug/SettingsTestModule.kt | 2 +- .../lambda/module/modules/debug/SilentSwap.kt | 4 +- .../lambda/module/modules/debug/StateInfo.kt | 2 +- .../lambda/module/modules/debug/TimerTest.kt | 2 +- .../module/modules/movement/AutoSpiral.kt | 2 +- .../module/modules/movement/AutoWalk.kt | 2 +- .../module/modules/movement/BackTrack.kt | 2 +- .../module/modules/movement/BetterFirework.kt | 4 +- .../lambda/module/modules/movement/Blink.kt | 2 +- .../modules/movement/ElytraAltitudeControl.kt | 4 +- .../module/modules/movement/EntityControl.kt | 2 +- .../lambda/module/modules/movement/Jesus.kt | 2 +- .../lambda/module/modules/movement/NoFall.kt | 2 +- .../module/modules/movement/NoJumpCooldown.kt | 2 +- .../module/modules/movement/SafeWalk.kt | 2 +- .../lambda/module/modules/movement/Speed.kt | 6 +- .../lambda/module/modules/movement/Sprint.kt | 2 +- .../module/modules/movement/TargetStrafe.kt | 2 +- .../module/modules/movement/TickShift.kt | 2 +- .../lambda/module/modules/movement/Timer.kt | 2 +- .../module/modules/movement/Velocity.kt | 2 +- .../modules/movement/elytrafly/ElytraFly.kt | 6 +- .../movement/elytrafly/ElytraFlyMode.kt | 30 +- .../movement/elytrafly/ObstaclePassingMode.kt | 8 +- .../elytrafly/modes/BounceElytraFly.kt | 2 +- .../module/modules/network/PacketDelay.kt | 2 +- .../module/modules/network/PacketLimiter.kt | 4 +- .../module/modules/network/PacketLogger.kt | 2 +- .../module/modules/network/Rubberband.kt | 2 +- .../module/modules/network/ServerSpoof.kt | 2 +- .../lambda/module/modules/player/AntiAFK.kt | 2 +- .../lambda/module/modules/player/AntiAim.kt | 4 +- .../lambda/module/modules/player/AutoEat.kt | 2 +- .../module/modules/player/AutoElytraSwap.kt | 2 +- .../module/modules/player/ClickFriend.kt | 2 +- .../module/modules/player/EndermanLook.kt | 2 +- .../lambda/module/modules/player/FastBreak.kt | 2 +- .../lambda/module/modules/player/Interact.kt | 2 +- .../module/modules/player/InventoryMove.kt | 2 +- .../module/modules/player/InventoryResync.kt | 2 +- .../module/modules/player/InventoryTweaks.kt | 2 +- .../lambda/module/modules/player/LineLock.kt | 2 +- .../module/modules/player/NoForceRotate.kt | 2 +- .../module/modules/player/PacketMine.kt | 2 +- .../lambda/module/modules/player/PortalGui.kt | 2 +- .../com/lambda/module/modules/player/Reach.kt | 2 +- .../lambda/module/modules/player/Replay.kt | 2 +- .../module/modules/player/RotationLock.kt | 2 +- .../module/modules/player/StackReplenish.kt | 2 +- .../lambda/module/modules/player/ToolSaver.kt | 2 +- .../module/modules/render/BlockOutline.kt | 2 +- .../lambda/module/modules/render/Bobbing.kt | 2 +- .../module/modules/render/CameraTweaks.kt | 2 +- .../module/modules/render/ContainerPreview.kt | 2 +- .../com/lambda/module/modules/render/Esp.kt | 2 +- .../lambda/module/modules/render/ExtraTab.kt | 2 +- .../lambda/module/modules/render/FreeLook.kt | 2 +- .../lambda/module/modules/render/Freecam.kt | 2 +- .../module/modules/render/Fullbright.kt | 2 +- .../module/modules/render/LightLevels.kt | 7 +- .../module/modules/render/MapPreview.kt | 2 +- .../lambda/module/modules/render/Nametags.kt | 2 +- .../lambda/module/modules/render/NoRender.kt | 2 +- .../lambda/module/modules/render/RadiusESP.kt | 2 +- .../lambda/module/modules/render/Search.kt | 2 +- .../com/lambda/module/modules/render/Time.kt | 2 +- .../lambda/module/modules/render/Tracers.kt | 2 +- .../lambda/module/modules/render/ViewModel.kt | 2 +- .../lambda/module/modules/render/Weather.kt | 2 +- .../module/modules/render/WorldColors.kt | 2 +- .../com/lambda/module/modules/render/XRay.kt | 2 +- .../com/lambda/module/modules/render/Zoom.kt | 2 +- .../lambda/module/modules/world/AirPlace.kt | 2 +- .../lambda/module/modules/world/AutoPortal.kt | 2 +- .../lambda/module/modules/world/AutoSign.kt | 2 +- .../module/modules/world/AutoVillagerCycle.kt | 2 +- .../module/modules/world/HighwayTools.kt | 2 +- .../module/modules/world/MapDownloader.kt | 2 +- .../com/lambda/module/modules/world/Nuker.kt | 2 +- .../lambda/module/modules/world/Printer.kt | 2 +- .../lambda/module/modules/world/Scaffold.kt | 2 +- .../lambda/module/modules/world/StashMover.kt | 2 +- .../task/tasks/AcquirePlacedBlockTask.kt | 2 +- .../com/lambda/task/tasks/CollectDropsTask.kt | 2 +- .../task/tasks/ContainerTransferTask.kt | 98 +++- .../kotlin/com/lambda/util/FolderRegistry.kt | 3 +- .../com/lambda/util/combat/DamageUtils.kt | 4 +- .../com/lambda/util/item/ItemStackUtils.kt | 4 +- .../kotlin/com/lambda/util/math/Vectors.kt | 4 +- .../player/prediction/PredictionEntity.kt | 10 +- 169 files changed, 1173 insertions(+), 681 deletions(-) create mode 100644 src/main/kotlin/com/lambda/config/serializers/PlacedContainerSerializer.kt create mode 100644 src/main/kotlin/com/lambda/interaction/container/ContainerSerializer.kt rename src/main/kotlin/com/lambda/interaction/handler/handlers/{interacting => }/InteractedBlockHandler.kt (94%) rename src/main/kotlin/com/lambda/interaction/handler/handlers/{packet => }/PacketLimitHandler.kt (97%) delete mode 100644 src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt delete mode 100644 src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt delete mode 100644 src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt rename src/main/kotlin/com/lambda/module/{tag => }/ModuleTag.kt (96%) diff --git a/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java b/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java index 7b2ec4dc3..9af7e6302 100644 --- a/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java +++ b/src/main/java/com/lambda/mixin/entity/LivingEntityMixin.java @@ -49,7 +49,6 @@ @Mixin(LivingEntity.class) public abstract class LivingEntityMixin extends EntityMixin { - @Unique private final LivingEntity lambda$instance = (LivingEntity) (Object) this; @Definition(id = "getJumpVelocity", method = "Lnet/minecraft/entity/LivingEntity;getJumpVelocity()F") diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index 9077ebe4d..9bcfb93fa 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -29,7 +29,7 @@ import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.handler.handlers.ContainerHandler +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.handler.handlers.findContainers import com.lambda.interaction.handler.handlers.findContainersWithSpace import com.lambda.task.Task @@ -56,26 +56,23 @@ object TransferCommand : LambdaCommand( isItem(stack(ctx).value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val containers = selection.findContainers().toList() + val containers = findContainers(selection).toList() val indexedContainers = containers.withIndex() suggestMatching( indexedContainers, builder, - { (index, container) -> - "\"${index + 1}. ${container.name}\"" - }, - { (_, container) -> - container.descriptionAndStock(selection) - } + { (index, container) -> "\"${index + 1}. ${container.name}\"" }, + { (_, container) -> container.descriptionAndStock(selection) } ) } ?: builder.buildFuture() } required(string("to")) { to -> suggests { ctx, builder -> - val selection = selectStack(amount(ctx).value()) { - isItem(stack(ctx).value().item) - } + val selection = + selectStack(amount(ctx).value()) { + isItem(stack(ctx).value().item) + } AutomationConfig.DEFAULT.runSafeAutomated { val containers = selection.findContainersWithSpace().toList() val indexedContainers = containers.withIndex() @@ -83,30 +80,31 @@ object TransferCommand : LambdaCommand( suggestMatching( indexedContainers, builder, - { (index, container) -> - "\"${index + 1}. ${container.name}\"" - }, - { (_, container) -> - container.descriptionAndStock(selection) - } + { (index, container) -> "\"${index + 1}. ${container.name}\"" }, + { (_, container) -> container.descriptionAndStock(selection) } ) } ?: builder.buildFuture() } executeWithResult { - val selection = selectStack(amount().value()) { - isItem(stack().value().item) - } AutomationConfig.DEFAULT.runSafeAutomated { - val fromContainer = ContainerHandler.filteredContainers.find { - it.name == from().value().split(".").last().trim() - } ?: return@executeWithResult failure("From container not found") + val fromSelection = + selectContainer { + custom { it.name == from().value().split(".").first().trim() } + } - val toContainer = ContainerHandler.filteredContainers.find { - it.name == to().value().split(".").last().trim() - } ?: return@executeWithResult failure("To container not found") + val toSelection = + selectContainer { + custom { it.name == to().value().split(".").first().trim() } + } - transfer(selection, fromContainer, toContainer) - .start() + lastContainerTransfer = + transfer( + selectStack(amount().value()) { + isItem(stack().value().item) + }, + fromSelection, + toSelection + ).start() } return@executeWithResult success() } @@ -117,9 +115,11 @@ object TransferCommand : LambdaCommand( required(literal("cancel")) { executeWithResult { - lastContainerTransfer?.cancel() ?: run { - return@executeWithResult failure("No transfer to cancel") - } + lastContainerTransfer + ?.cancel() + ?: run { + return@executeWithResult failure("No transfer to cancel") + } this@TransferCommand.info("$lastContainerTransfer cancelled") lastContainerTransfer = null success() diff --git a/src/main/kotlin/com/lambda/config/ConfigEditor.kt b/src/main/kotlin/com/lambda/config/ConfigEditor.kt index 8700d9889..df332bd5d 100644 --- a/src/main/kotlin/com/lambda/config/ConfigEditor.kt +++ b/src/main/kotlin/com/lambda/config/ConfigEditor.kt @@ -21,7 +21,7 @@ package com.lambda.config import com.lambda.config.entries.Property import com.lambda.config.entries.Setting -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.context.SafeContext import kotlin.reflect.KProperty0 import kotlin.reflect.jvm.isAccessible diff --git a/src/main/kotlin/com/lambda/config/automation/AutomationConfig.kt b/src/main/kotlin/com/lambda/config/automation/AutomationConfig.kt index 4272fdf96..d90420e89 100644 --- a/src/main/kotlin/com/lambda/config/automation/AutomationConfig.kt +++ b/src/main/kotlin/com/lambda/config/automation/AutomationConfig.kt @@ -31,6 +31,9 @@ import com.lambda.config.categories.AutomationCategory import com.lambda.context.Automated import com.lambda.module.Module +@DslMarker +private annotation class AutomationConfigMarker + open class AutomationConfig( name: String, configCategory: ConfigCategory = AutomationCategory @@ -55,20 +58,17 @@ open class AutomationConfig( private const val HOTBAR_TAB = "Hotbar" private const val EAT_TAB = "Eat" - @DslMarker - private annotation class AutomationConfigMarker - - @AutomationConfigMarker - context(module: Module) - fun IMutableAutomationConfig.setDefaultAutomationConfig( - name: String = module.name - ) = AutomationConfig("$name Automation Config").also { this.defaultAutomationConfig = it } - - @AutomationConfigMarker - fun IMutableAutomationConfig.setDefaultAutomationConfig( - name: String - ) = AutomationConfig("$name Automation Config").also { this.defaultAutomationConfig = it } - val DEFAULT = AutomationConfig("Default") } -} \ No newline at end of file +} + +@AutomationConfigMarker +context(module: Module) +fun IMutableAutomationConfig.setDefaultAutomationConfig( + name: String = module.name +) = AutomationConfig("$name Automation Config").also { this.defaultAutomationConfig = it } + +@AutomationConfigMarker +fun IMutableAutomationConfig.setDefaultAutomationConfig( + name: String +) = AutomationConfig("$name Automation Config").also { this.defaultAutomationConfig = it } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 5ac44e036..4f0e9c893 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -48,22 +48,22 @@ interface InventoryConfig { fun materialComparator(selection: StackSelection) = when (this) { WithMaxItems -> compareBy { it.type } - .thenByDescending { it.stackCount(selection) } + .thenByDescending { it.count(selection) } .thenBy { it.name } WithMinItems -> compareBy { it.type } - .thenBy { it.stackCount(selection) } + .thenBy { it.count(selection) } .thenBy { it.name } } fun spaceComparator(selection: StackSelection) = when (this) { WithMaxItems -> compareBy { it.type } - .thenByDescending { it.spaceAvailable(selection) } + .thenByDescending { it.spaceLeft(selection) } .thenBy { it.name } WithMinItems -> compareBy { it.type } - .thenBy { it.spaceAvailable(selection) } + .thenBy { it.spaceLeft(selection) } .thenBy { it.name } } } diff --git a/src/main/kotlin/com/lambda/config/entries/Setting.kt b/src/main/kotlin/com/lambda/config/entries/Setting.kt index e68c0def7..17777d42a 100644 --- a/src/main/kotlin/com/lambda/config/entries/Setting.kt +++ b/src/main/kotlin/com/lambda/config/entries/Setting.kt @@ -31,6 +31,7 @@ import com.lambda.config.ConfigEntry import com.lambda.config.EntryCore import com.lambda.config.EntryLayer import com.lambda.config.MultipleLayerType +import com.lambda.config.entries.Setting.ValueListener import com.lambda.context.SafeContext import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.threading.runSafe @@ -229,42 +230,40 @@ abstract class Setting( override fun toString() = "Setting $name: $value" - companion object { - /** - * Will only register changes of the variable, not the content of the variable! - * E.g., if the variable is a list, it will only register if the list reference changes, not if the content of the list changes. - */ - @ConfigEntryDsl - fun , T> S.onValueChange(block: SafeContext.(from: T, to: T) -> Unit) = - apply { - listeners.add(ValueListener(true) { from, to -> - runSafe { block(from, to) } - }) - } - - @ConfigEntryDsl - fun , T> S.onValueChangeUnsafe(block: (from: T, to: T) -> Unit) = - apply { listeners.add(ValueListener(true, block)) } + class ValueListener(val requiresValueChange: Boolean, val execute: (from: T, to: T) -> Unit) +} - @ConfigEntryDsl - fun , T> S.onValueSet(block: SafeContext.(from: T, to: T) -> Unit) = - apply { - listeners.add(ValueListener(false) { from, to -> - runSafe { block(from, to) } - }) - } +/** + * Will only register changes of the variable, not the content of the variable! + * E.g., if the variable is a list, it will only register if the list reference changes, not if the content of the list changes. + */ +@ConfigEntryDsl +fun , T> S.onValueChange(block: SafeContext.(from: T, to: T) -> Unit) = + apply { + listeners.add(ValueListener(true) { from, to -> + runSafe { block(from, to) } + }) + } - @ConfigEntryDsl - fun , T> S.onValueSetUnsafe(block: (from: T, to: T) -> Unit) = - apply { listeners.add(ValueListener(false, block)) } +@ConfigEntryDsl +fun , T> S.onValueChangeUnsafe(block: (from: T, to: T) -> Unit) = + apply { listeners.add(ValueListener(true, block)) } - @ConfigEntryDsl - fun , T> S.disabled(predicate: () -> Boolean) = - apply { disabled = predicate } +@ConfigEntryDsl +fun , T> S.onValueSet(block: SafeContext.(from: T, to: T) -> Unit) = + apply { + listeners.add(ValueListener(false) { from, to -> + runSafe { block(from, to) } + }) } - class ValueListener(val requiresValueChange: Boolean, val execute: (from: T, to: T) -> Unit) -} +@ConfigEntryDsl +fun , T> S.onValueSetUnsafe(block: (from: T, to: T) -> Unit) = + apply { listeners.add(ValueListener(false, block)) } + +@ConfigEntryDsl +fun , T> S.disabled(predicate: () -> Boolean) = + apply { disabled = predicate } class SettingEntryLayer, U>( override val parent: EntryLayer.Multiple>, diff --git a/src/main/kotlin/com/lambda/config/serializers/PlacedContainerSerializer.kt b/src/main/kotlin/com/lambda/config/serializers/PlacedContainerSerializer.kt new file mode 100644 index 000000000..062915fab --- /dev/null +++ b/src/main/kotlin/com/lambda/config/serializers/PlacedContainerSerializer.kt @@ -0,0 +1,115 @@ +@file:Suppress("unused") + +package com.lambda.config.serializers + +import com.lambda.config.Deserializer +import com.lambda.config.JsonOps +import com.lambda.config.Serializer +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.PlacedContainer +import com.lambda.interaction.container.containers.external.ChestContainer +import com.lambda.interaction.container.containers.external.DoubleChestContainer +import com.lambda.interaction.container.containers.external.PlacedShulkerBoxContainer +import net.minecraft.block.Blocks +import net.minecraft.item.ItemStack +import net.minecraft.registry.Registries +import net.minecraft.util.Identifier +import net.minecraft.util.math.BlockPos +import tools.jackson.core.JsonGenerator +import tools.jackson.core.JsonParser +import tools.jackson.databind.DeserializationContext +import tools.jackson.databind.SerializationContext +import tools.jackson.databind.node.ArrayNode +import tools.jackson.databind.node.JsonNodeFactory +import tools.jackson.databind.node.ObjectNode + +object PlacedContainerSerializer : Serializer(PlacedContainer::class.java) { + override fun serialize(container: PlacedContainer, gen: JsonGenerator, ctxt: SerializationContext) { + val root = JsonNodeFactory.instance.objectNode() + + root.put("Type", container.type.name) + root.set("Pos", blockPosNode(container.pos)) + + when (container) { + is PlacedShulkerBoxContainer -> { + val blockId = Registries.BLOCK.getId(container.block).toString() + root.put("Block", blockId) + } + is DoubleChestContainer -> { + root.put("Double", true) + root.set("Left Pos", blockPosNode(container.leftPos)) + root.set("Right Pos", blockPosNode(container.rightPos)) + } + else -> {} + } + + val stackArray = JsonNodeFactory.instance.arrayNode() + for (stack in container.stacks) { + val encoded = ItemStack.CODEC + .encodeStart(JsonOps.UNCOMPRESSED, stack) + .result() + encoded.ifPresent { stackArray.add(it) } + } + root.set("Stacks", stackArray) + + gen.writeTree(root) + } + + private fun blockPosNode(pos: BlockPos): ObjectNode { + val node = JsonNodeFactory.instance.objectNode() + node.put("X", pos.x) + node.put("Y", pos.y) + node.put("Z", pos.z) + return node + } +} + +object PlacedContainerDeserializer : Deserializer(PlacedContainer::class.java) { + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): PlacedContainer? { + val root = p.readValueAsTree() ?: return null + + val typeName = root.get("Type")?.asString() ?: return null + val type = ContainerType.entries.find { it.name == typeName } ?: return null + + val posNode = root.get("Pos") as? ObjectNode ?: return null + val pos = parseBlockPos(posNode) ?: return null + + val stackArray = root.get("Stacks") as? ArrayNode + val stacks = + stackArray?.mapNotNull { element -> + ItemStack.CODEC + .parse(JsonOps.UNCOMPRESSED, element) + .result() + .orElse(null) + } ?: emptyList() + + val container = + when (type) { + ContainerType.PlacedShulkerBox -> { + val blockId = root.get("Block")?.asString() + val block = blockId?.let { Registries.BLOCK.get(Identifier.of(it)) } ?: Blocks.SHULKER_BOX + PlacedShulkerBoxContainer(pos, block, null, stacks) + } + ContainerType.Chest -> { + if (root.get("Double")?.asBoolean() == true) { + val leftPos = (root.get("Left Pos") as? ObjectNode)?.let { parseBlockPos(it) } ?: pos + val rightPos = (root.get("Right Pos") as? ObjectNode)?.let { parseBlockPos(it) } ?: pos + DoubleChestContainer(pos, leftPos, rightPos, stacks) + } else { + ChestContainer(pos, stacks) + } + } + else -> return null + } + + container.scanStacksForNestedContainers() + return container + } + + private fun parseBlockPos(node: ObjectNode): BlockPos? { + val x = node.get("X")?.asInt() ?: return null + val y = node.get("Y")?.asInt() ?: return null + val z = node.get("Z")?.asInt() ?: return null + return BlockPos(x, y, z) + } +} diff --git a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt index d7aebfca2..767c56ca6 100644 --- a/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt +++ b/src/main/kotlin/com/lambda/graphics/mc/renderer/ChunkedRenderer.kt @@ -63,7 +63,7 @@ class ChunkedRenderer( private val uploadQueue = ConcurrentLinkedDeque<() -> Unit>() init { - owner.listenUnsafe { event -> + owner.listenUnsafe(alwaysListen = true) { event -> val pos = event.pos val world = mc.world ?: return@listenUnsafe world.getWorldChunk(pos)?.chunkData?.markDirty() @@ -77,9 +77,9 @@ class ChunkedRenderer( if (zInChunk == 15) world.getWorldChunk(pos.south())?.chunkData?.markDirty() } - owner.listenUnsafe { event -> event.chunk.chunkData.markDirty() } - owner.listenUnsafe { chunkMap.remove(it.chunk.chunkKey)?.clearData() } - owner.listenUnsafe { clear() } + owner.listenUnsafe(alwaysListen = true) { event -> event.chunk.chunkData.markDirty() } + owner.listenUnsafe(alwaysListen = true) { chunkMap.remove(it.chunk.chunkKey)?.clearData() } + owner.listenUnsafe(alwaysListen = true) { clear() } owner.listenConcurrentlyUnsafe { if (pauseUpdates()) return@listenConcurrentlyUnsafe diff --git a/src/main/kotlin/com/lambda/graphics/text/FontHandler.kt b/src/main/kotlin/com/lambda/graphics/text/FontHandler.kt index edb196076..197e207fc 100644 --- a/src/main/kotlin/com/lambda/graphics/text/FontHandler.kt +++ b/src/main/kotlin/com/lambda/graphics/text/FontHandler.kt @@ -20,7 +20,7 @@ package com.lambda.graphics.text import com.lambda.Lambda.LOG import com.lambda.config.Config import com.lambda.config.categories.FontCategory -import com.lambda.config.entries.Setting.Companion.onValueChangeUnsafe +import com.lambda.config.entries.onValueChangeUnsafe import com.lambda.core.Loadable import com.lambda.event.events.ClientEvent import com.lambda.event.listener.SafeListener.Companion.listen diff --git a/src/main/kotlin/com/lambda/gui/MenuBar.kt b/src/main/kotlin/com/lambda/gui/MenuBar.kt index 2c5550ff2..df50b2a31 100644 --- a/src/main/kotlin/com/lambda/gui/MenuBar.kt +++ b/src/main/kotlin/com/lambda/gui/MenuBar.kt @@ -43,7 +43,7 @@ import com.lambda.imgui.type.ImBoolean import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.ModuleRegistry import com.lambda.module.ModuleRegistry.moduleNameMap -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.network.LambdaAPI import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.info diff --git a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt index f4e708bd8..f8965fbe4 100644 --- a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt +++ b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt @@ -21,7 +21,7 @@ import com.lambda.Lambda.mc import com.lambda.config.Config import com.lambda.config.Tab import com.lambda.config.categories.GuiCategory -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.settings.complex.KeybindSetting.Companion.onPressUnsafe import com.lambda.core.Loadable import com.lambda.event.events.GuiEvent @@ -49,8 +49,8 @@ import com.lambda.imgui.flag.ImGuiWindowFlags import com.lambda.module.ModuleRegistry import com.lambda.module.modules.client.Client import com.lambda.module.modules.combat.autodisconnect.AutoDisconnectScreen -import com.lambda.module.tag.ModuleTag -import com.lambda.module.tag.ModuleTag.Companion.shownTags +import com.lambda.module.ModuleTag +import com.lambda.module.ModuleTag.Companion.shownTags import com.lambda.sound.LambdaSound import com.lambda.sound.SoundHandler.play import com.lambda.util.Describable @@ -157,8 +157,7 @@ object ClickGuiLayout : Loadable, Config( mc.window.setIcon(mc.defaultResourcePack, icon) } } - @JvmStatic - @Tab(GENERAL_TAB) val setLambdaWindowTitle by setting("Set Lambda Window Title", true).onValueChange { _, _ -> mc.updateWindowTitle() } + @Tab(GENERAL_TAB) @JvmStatic val setLambdaWindowTitle by setting("Set Lambda Window Title", true).onValueChange { _, _ -> mc.updateWindowTitle() } @Tab(GENERAL_TAB) val lambdaTitleAppendixName by setting("Append Username", true) { setLambdaWindowTitle }.onValueChange { _, _ -> mc.updateWindowTitle() } @Tab(GENERAL_TAB) val backgroundBlur by setting("Background Blur", true) @Tab(GENERAL_TAB) val backgroundDarkening by setting("Background Darkening", true) diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index 361763443..e5bf44af2 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -33,8 +33,9 @@ import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.task.tasks.transferTo +import com.lambda.task.tasks.transfer import net.minecraft.block.BlockState import net.minecraft.item.Item import net.minecraft.util.math.BlockPos @@ -119,7 +120,7 @@ sealed class BreakResult : BuildResult() { context(_: Automated) override fun resolve() = selectStack { inverted { isItem(badItem) } } - .transferTo(HotbarContainer) + .transfer(toSelection = HotbarContainer.select()) override fun compareResult(other: ComparableResult) = when (other) { diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt index 0e06d44da..2c5e64a8d 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/GenericResult.kt @@ -28,8 +28,9 @@ import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.selection.StackSelection +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.BaritoneHandler -import com.lambda.task.tasks.transferTo +import com.lambda.task.tasks.transfer import net.minecraft.client.data.TextureMap.side import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos @@ -100,7 +101,7 @@ sealed class GenericResult : BuildResult() { context(_: Automated) override fun resolve() = neededSelection - .transferTo(HotbarContainer) + .transfer(toSelection = HotbarContainer.select()) override fun RenderBuilder.render() { val center = pos.toCenterPos() diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt index 06f5e8c1c..6f60974e2 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt @@ -158,8 +158,7 @@ class BreakSim internal constructor(simInfo: SimInfo) ofAnyType(ContainerType.Hotbar) } - val hotbarCandidates = stackSelection - .findContainers(containerSelection) + val hotbarCandidates = findContainers(stackSelection, containerSelection) .flatMap { stackSelection.filter(it.stacks) } .toList() if (hotbarCandidates.isEmpty()) { diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt index 341a15e8e..8f8ec8872 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt @@ -208,14 +208,18 @@ class InteractSim internal constructor(simInfo: InteractSimInfo) val stackSelection = item?.select(if (item == Items.AIR) 0 else 1) ?: selectStack { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } val containerSelection = selectContainer { ofAnyType(ContainerType.Hotbar) } - val container = stackSelection.findContainers(containerSelection).firstOrNull() ?: run { - result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) - return null - } - return stackSelection.filter(container.slots).run { - firstOrNull { it.index == player.inventory.selectedSlot } - ?: firstOrNull() - } + val container = findContainers(stackSelection, containerSelection) + .firstOrNull() + ?: run { + result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) + return null + } + return stackSelection + .filter(container.slots) + .run { + firstOrNull { it.index == player.inventory.selectedSlot } + ?: firstOrNull() + } } private suspend fun AutomatedSafeContext.simRotation( diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index 1ba987fc8..7eb8fd043 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.construction.verify import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.findContainerWithDisposable +import com.lambda.interaction.handler.handlers.findContainersWithDisposable import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.emptyState import com.lambda.util.BlockUtils.isEmpty @@ -86,9 +87,12 @@ sealed class TargetState : StateMatcher { context(automatedSafeContext: AutomatedSafeContext) override fun getStack(pos: BlockPos) = with(automatedSafeContext) { - findContainerWithDisposable()?.stacks?.firstOrNull { - it.item in inventoryConfig.disposables && it.item.block !in replace - } ?: ItemStack(Items.NETHERRACK) + findContainerWithDisposable() + ?.stacks + ?.firstOrNull { + it.item in inventoryConfig.disposables && it.item.block !in replace + } + ?: ItemStack(Items.NETHERRACK) } context(_: AutomatedSafeContext) @@ -113,9 +117,12 @@ sealed class TargetState : StateMatcher { context(automatedSafeContext: AutomatedSafeContext) override fun getStack(pos: BlockPos) = with(automatedSafeContext) { - findContainerWithDisposable()?.stacks?.firstOrNull { - it.item in inventoryConfig.disposables - } ?: ItemStack(Items.NETHERRACK) + findContainerWithDisposable() + ?.stacks + ?.firstOrNull { + it.item in inventoryConfig.disposables + } + ?: ItemStack(Items.NETHERRACK) } context(_: AutomatedSafeContext) diff --git a/src/main/kotlin/com/lambda/interaction/container/Container.kt b/src/main/kotlin/com/lambda/interaction/container/Container.kt index d8dd36dd5..18c348749 100644 --- a/src/main/kotlin/com/lambda/interaction/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/container/Container.kt @@ -22,14 +22,17 @@ import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.event.EventFlow.post import com.lambda.event.events.ContainerEvent +import com.lambda.interaction.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task.Ta5kBuilder import com.lambda.util.Nameable import com.lambda.util.item.ItemStackUtils.count -import com.lambda.util.item.ItemStackUtils.empty +import com.lambda.util.item.ItemStackUtils.emptySpace +import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemStackUtils.spaceLeft +import com.lambda.util.item.ItemUtils.SHULKER_BOXES import com.lambda.util.item.ItemUtils.toItemCount import com.lambda.util.text.TextBuilder import com.lambda.util.text.TextDsl @@ -71,6 +74,8 @@ abstract class Container( it.stack.isStackable } + open val isAccessed get() = true + context(_: SafeContext) fun descriptionAndStock(selection: StackSelection) = buildText { @@ -83,29 +88,72 @@ abstract class Container( fun TextBuilder.stock(selection: StackSelection) { literal("\n") literal("Contains ") - val available = stackCount(selection) + val available = count(selection) highlighted(if (available == Int.MAX_VALUE) "∞" else available.toItemCount()) literal(" of ") highlighted("${selection.optimalStack?.name?.string}") literal("\n") literal("Could store ") - val left = spaceAvailable(selection) + val left = spaceLeft(selection) highlighted(if (left == Int.MAX_VALUE) "∞" else left.toItemCount()) literal(" of ") highlighted("${selection.optimalStack?.name?.string}") } - open val isAccessed get() = true - fun update(slots: List) { this.stacks = slots } + fun scanStacksForNestedContainers() { + stacks.forEachIndexed { index, stack -> + if (stack.item in SHULKER_BOXES) { + storedContainers[index] = + ShulkerBoxContainer( + stack.name.string, + stack.item, + stack.shulkerBoxStacks, + this, + index + ).also { it.scanStacksForNestedContainers() } + } else storedContainers.remove(index) + } + } + @Ta5kBuilder context(automated: Automated) open fun access(): OpenContainerTask<*>? = PlayerOpenContainerTask(description, ::isAccessed) + open fun count(selection: StackSelection) = + slots.takeUnless { it.isEmpty() }?.let { selection.filter(it).count } + ?: selection.filter(stacks).count + + open fun spaceLeft(selection: StackSelection) = + slots.takeUnless { it.isEmpty() }?.let { selection.filter(it).spaceLeft + it.emptySpace } + ?: (selection.filter(stacks).spaceLeft + stacks.emptySpace) + + open fun findSlots(selection: StackSelection) = selection.filter(slots) + + fun findSlot(selection: StackSelection) = findSlots(selection).firstOrNull() + + open fun findStacks(selection: StackSelection) = selection.filter(stacks) + + fun findStack(selection: StackSelection) = findStacks(selection).firstOrNull() + + context(_: Automated) + fun findMoveSlots( + selection: StackSelection, + toContainer: Container, + toStackSelection: StackSelection = StackSelection.EVERYTHING + ) = Pair(findSlot(selection), toContainer.findReplaceSlot(toStackSelection)) + + context(_: Automated) + open fun findReplaceSlot( + selection: StackSelection = StackSelection.EVERYTHING + ) = findSlots(selection) + .sortedWith(replaceSorter) + .firstOrNull() + context(automatedSafeContext: AutomatedSafeContext) internal fun swap(fromSlot: Slot, toSlot: Slot, toContainer: Container): Boolean { val transferEvent = ContainerEvent.Transfer(fromSlot, toSlot, this@Container, toContainer) @@ -125,20 +173,5 @@ abstract class Container( } } - open fun stackCount(selection: StackSelection) = - selection.filter(stacks).count - - open fun spaceAvailable(selection: StackSelection) = - selection.filter(stacks).spaceLeft + stacks.empty - - context(_: Automated) - fun getTransferSlots(selection: StackSelection, destination: Container): Pair = - Pair(getSlot(selection), destination.getReplaceSlot()) - - context(_: Automated) - open fun getReplaceSlot() = slots.sortedWith(replaceSorter).firstOrNull() - - open fun getSlot(selection: StackSelection) = selection.bestMatch(slots) - override fun compareTo(other: Container) = compareBy { it.type }.compare(this, other) } diff --git a/src/main/kotlin/com/lambda/interaction/container/ContainerSerializer.kt b/src/main/kotlin/com/lambda/interaction/container/ContainerSerializer.kt new file mode 100644 index 000000000..d53ce206e --- /dev/null +++ b/src/main/kotlin/com/lambda/interaction/container/ContainerSerializer.kt @@ -0,0 +1,115 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.interaction.container + +import com.lambda.Lambda.LOG +import com.lambda.Lambda.mapper +import com.lambda.interaction.container.containers.external.EnderChestContainer +import com.lambda.util.FolderRegistry +import net.minecraft.util.math.BlockPos +import java.nio.file.Path +import kotlin.io.path.createDirectories +import kotlin.io.path.deleteIfExists +import kotlin.io.path.exists +import kotlin.io.path.notExists + +/** + * Handles saving and loading [PlacedContainer]s to/from disk as JSON files. + * + * Serialized containers are stored under [FolderRegistry.containers]. + */ +object ContainerSerializer { + private const val ENDER_CHEST_FILE = "ender_chest.json" + + /** + * A reusable sequence that lazily loads all serialized containers from disk. + * Every iteration reads the files anew, preventing RAM exhaustion. + */ + val serializedContainers: Sequence = + sequence { + val dir = FolderRegistry.containers + if (dir.notExists()) return@sequence + + dir.toFile().walkTopDown().forEach { file -> + if (file.isFile && file.name.endsWith(".json") && file.name != ENDER_CHEST_FILE) { + yield(readContainer(file.toPath()) ?: return@forEach) + } + } + } + + /** + * Saves a [PlacedContainer] to disk as JSON. + */ + @Synchronized + fun saveContainer(container: PlacedContainer) { + val dir = ensureDirectory() + val file = dir.resolve(containerFileName(container.pos)).toFile() + mapper.writeValue(file, container) + } + + /** + * Saves the [EnderChestContainer] to disk. This is always loaded into memory + * for the entire session. + */ + fun saveEnderChest() { + val dir = ensureDirectory() + val file = dir.resolve(ENDER_CHEST_FILE).toFile() + mapper.writeValue(file, EnderChestContainer) + } + + /** + * Loads the [EnderChestContainer] contents from disk, if available. + * Called on session start to restore the ender chest state. + */ + fun loadEnderChest() { + val file = FolderRegistry.containers.resolve(ENDER_CHEST_FILE) + if (!file.exists()) return + runCatching { + mapper.readValue(file.toFile(), EnderChestContainer::class.java) + }.onFailure { + LOG.warn("Failed to load ender chest from $file", it) + } + } + + /** + * Removes a serialized container from disk. + */ + @Synchronized + fun removeContainer(pos: BlockPos) { + val dir = FolderRegistry.containers + dir.resolve(containerFileName(pos)).deleteIfExists() + } + + + + private fun readContainer(file: Path): PlacedContainer? = + runCatching { + mapper.readValue(file.toFile(), PlacedContainer::class.java) + }.onFailure { + LOG.warn("Failed to read container from ${file.fileName}", it) + }.getOrNull() + + private fun ensureDirectory() = + FolderRegistry.containers.also { if (it.notExists()) it.createDirectories() } + + private fun containerFileName(pos: BlockPos): String { + val chunkX = pos.x shr 4 + val chunkZ = pos.z shr 4 + return "${chunkX}_${chunkZ}_${pos.x}_${pos.y}_${pos.z}.json" + } +} diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/ArmorContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/ArmorContainer.kt index bd54eebf8..2a76c37ab 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/ArmorContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/ArmorContainer.kt @@ -37,4 +37,4 @@ object ArmorContainer : Container(ContainerType.Armor) { override val description = buildText { literal("Armor") } override val isAccessed get() = mc.player?.currentScreenHandler?.syncId == 0 -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/CreativeContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/CreativeContainer.kt index 2c53447d1..f6538f81c 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/CreativeContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/CreativeContainer.kt @@ -40,30 +40,35 @@ data object CreativeContainer : Container(ContainerType.Creative) { override val description = buildText { literal("Creative") } + override fun count(selection: StackSelection): Int = + if (mc.player?.isCreative == true && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 + + override fun spaceLeft(selection: StackSelection): Int = + if (mc.player?.isCreative == true && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 + context(safeContext: SafeContext) override fun InvRequestBuilder.swap(fromHere: Slot, toSlot: Slot) { clickCreativeStack(fromHere.stack, toSlot.id) safeContext.player.currentScreenHandler.slots.getOrNull(toSlot.id)?.stack = fromHere.stack } - override fun getSlot(selection: StackSelection) = - selection.optimalStack?.let { stack -> - Slot( - object : SingleStackInventory { - override fun getStack() = stack - override fun setStack(stack: ItemStack?) {} - override fun markDirty() {} - override fun canPlayerUse(player: PlayerEntity?) = false - }, - 0, 0, 0 - ) - } + override fun findSlots(selection: StackSelection) = + listOfNotNull( + selection.optimalStack?.let { stack -> + Slot( + object : SingleStackInventory { + override fun getStack() = stack + override fun setStack(stack: ItemStack?) {} + override fun markDirty() {} + override fun canPlayerUse(player: PlayerEntity?) = false + }, + 0, 0, 0 + ) + } + ) - override fun stackCount(selection: StackSelection): Int = - if (mc.player?.isCreative == true && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 - - override fun spaceAvailable(selection: StackSelection): Int = - if (mc.player?.isCreative == true && correctScreenHandler && selection.optimalStack != null) Int.MAX_VALUE else -1 + override fun findStacks(selection: StackSelection) = + listOfNotNull(selection.optimalStack) private val correctScreenHandler get() = mc.player?.currentScreenHandler is PlayerScreenHandler || mc.player?.currentScreenHandler is CreativeInventoryScreen.CreativeScreenHandler diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/CursorContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/CursorContainer.kt index 5211c5d90..4455c6f4a 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/CursorContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/CursorContainer.kt @@ -32,4 +32,4 @@ object CursorContainer : Container(ContainerType.Cursor) { set(_) {} override val description = buildText { literal("Cursor") } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt index d2e67c234..8ba7a894f 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt @@ -27,13 +27,14 @@ import com.lambda.interaction.container.NestedContainer import com.lambda.interaction.container.OpenContainerTask import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.select import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.breakAndCollect import com.lambda.task.tasks.openContainer import com.lambda.task.tasks.placeContainer import com.lambda.task.tasks.transfer -import com.lambda.task.tasks.transferTo import com.lambda.task.tasks.wrappers.actionTask import com.lambda.task.tasks.wrappers.taskOrNull import com.lambda.task.tasks.wrappers.then @@ -79,8 +80,8 @@ data class ShulkerBoxContainer( override fun SafeContext.onStart() { transfer( selectStack { inIndex(index); isItem(shulkerItem) }, - containedIn, - HotbarContainer + containedIn.select(), + HotbarContainer.select() ).then { slot -> placeContainer(slot) } .then { pos -> openContainer(pos).onSuccess { @@ -104,17 +105,11 @@ data class ShulkerBoxContainer( .then { selectStack { isItem(shulkerItem) - hasCustomName(itemName) + hasName(itemName) sortedByBestContentMatch(stacks) - }.transferTo() - transfer( - selectStack { - isItem(shulkerItem) - hasCustomName(itemName) - sortedByBestContentMatch(stacks) - }, - HotbarAndInventoryContainer, - fromContainer + }.transfer( + ContainerSelection.HOTBAR_AND_INVENTORY, + fromContainer.select() ) } } diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/external/StashContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/StashContainer.kt index bd3420298..7d1276ac1 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/external/StashContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/StashContainer.kt @@ -38,11 +38,12 @@ data class StashContainer( get() = chests.flatMap { it.stacks } set(_) {} - override val description = buildText { - literal("Stash at ") - highlighted(pos.center.roundedBlockPos.toShortString()) - } + override val description = + buildText { + literal("Stash at ") + highlighted(pos.center.roundedBlockPos.toShortString()) + } - override fun stackCount(selection: StackSelection): Int = - chests.sumOf { it.stackCount(selection) } + override fun count(selection: StackSelection): Int = + chests.sumOf { it.count(selection) } } diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt index 39f72b7fa..5da064731 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt @@ -27,13 +27,26 @@ import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.container.containers.OffHandContainer import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.handler.handlers.ContainerSearchScope + +@ContainerMarker +fun Container.select( + scope: ContainerSearchScope = ContainerSearchScope.Accessed +) = selectContainer(scope) { ofAny(this@select) } + +@ContainerMarker +fun selectContainers( + vararg containers: Container, + scope: ContainerSearchScope = ContainerSearchScope.Accessed +) = selectContainer(scope) { ofAny(*containers) } /** - * ContainerSelection is a class that holds a predicate for matching MaterialContainers. + * ContainerSelection is a class that holds a predicate for matching containers. */ @Suppress("unused") -class ContainerSelection( +class ContainerSelection @ContainerMarker internal constructor( val selector: (Container) -> Boolean, + val scope: ContainerSearchScope = ContainerSearchScope.Accessed, val containersWhitelist: Collection = emptyList(), val accessedOnly: Boolean = false, val comparator: Comparator = compareBy { it.type } @@ -57,24 +70,35 @@ class ContainerSelection( companion object { val EVERYTHING = ContainerSelection({ true }) val NOTHING = ContainerSelection({ false }) - val HOTBAR_AND_INVENTORY = selectContainer { ofAny(HotbarContainer, InventoryContainer) } + val HOTBAR_AND_INVENTORY = selectContainers(HotbarContainer, InventoryContainer) val PLAYER = - selectContainer { - ofAny( - HotbarContainer, - InventoryContainer, - OffHandContainer, - CursorContainer, - ArmorContainer, - CreativeContainer - ) - } + selectContainers( + HotbarContainer, + InventoryContainer, + OffHandContainer, + CursorContainer, + ArmorContainer, + CreativeContainer + ) } } @Suppress("unused") @ContainerMarker -class ContainerSelectionBuilder private constructor() { +class ContainerSelectionBuilder @ContainerMarker private constructor( + private val scope: ContainerSearchScope +) { + @ContainerMarker + private constructor( + selection: ContainerSelection, + scope: ContainerSearchScope + ) : this(scope) { + this.selector = selection.selector + this.containersWhitelist.addAll(selection.containersWhitelist) + this.accessedOnly = selection.accessedOnly + this.comparator = selection.comparator + } + private var selector: (Container) -> Boolean = { true } private var containersWhitelist = mutableListOf() private var accessedOnly = false @@ -94,10 +118,14 @@ class ContainerSelectionBuilder private constructor() { appendSelector { container -> !types.contains(container.type) } } - fun matches(stackSelection: StackSelection) { + fun matchesSlots(stackSelection: StackSelection) { appendSelector { container -> stackSelection.filter(container.slots).isNotEmpty() } } + fun matchesStacks(stackSelection: StackSelection) { + appendSelector { container -> stackSelection.filter(container.stacks).isNotEmpty() } + } + fun matches(containerSelection: ContainerSelection) { appendSelector { container -> containerSelection.matches(container) } } @@ -131,11 +159,17 @@ class ContainerSelectionBuilder private constructor() { this.selector = { currentSelector(it) && selector(it) xor invert } } - private fun build() = ContainerSelection(selector, containersWhitelist, accessedOnly, comparator) + private fun build() = ContainerSelection(selector, scope, containersWhitelist, accessedOnly, comparator) companion object { fun selectContainer( + scope: ContainerSearchScope = ContainerSearchScope.Accessed, builder: ContainerSelectionBuilder.() -> Unit - ) = ContainerSelectionBuilder().apply(builder).build() + ) = ContainerSelectionBuilder(scope).apply(builder).build() + + fun ContainerSelection.mutate( + scope: ContainerSearchScope = this.scope, + builder: ContainerSelectionBuilder.() -> Unit = {} + ) = ContainerSelectionBuilder(this, scope).apply(builder).build() } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt index b1c403288..a58f95d22 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt @@ -17,6 +17,7 @@ package com.lambda.interaction.container.selection +import com.lambda.interaction.container.Container import com.lambda.interaction.container.ContainerMarker import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.util.EnchantmentUtils.getEnchantment @@ -43,7 +44,7 @@ fun Item.select(count: Int = 0) = selectStack(count) { isItem(this@select) } fun ItemStack.select(count: Int = 0) = selectStack(count) { isItemStack(this@select) } @Suppress("unused") -class StackSelection( +class StackSelection @ContainerMarker internal constructor( val whitelistedSlots: Collection = emptyList(), val count: Int = 0, val item: Item? = null, @@ -85,13 +86,21 @@ class StackSelection( fun filter(slots: Iterable) = slots .let { slots -> - if (whitelistedSlots.isNotEmpty()) whitelistedSlots.filter { it in slots } else slots + if (whitelistedSlots.isNotEmpty()) { + whitelistedSlots.filter { it in slots } + } else slots } .filter(::matches) .map { StackAndSlot(it.stack, it) } .sortedWith(comparator) .map { it.slot } + infix fun isIn(container: Container) = + container.count(this) >= count + + infix fun spaceIn(container: Container) = + container.spaceLeft(this) >= count + companion object { val EVERYTHING = StackSelection { _, _ -> true } val NOTHING = StackSelection { _, _ -> false } @@ -100,16 +109,30 @@ class StackSelection( @Suppress("unused") @ContainerMarker -class StackSelectionBuilder private constructor(private val count: Int = 0) { +class StackSelectionBuilder @ContainerMarker private constructor( + private var count: Int = 0 +) { private val whitelistedSlots = mutableListOf() private var selector: (ItemStack, Slot?) -> Boolean = { _, _ -> true } private var item: Item? = null - private var stackByRef = false private var itemStack: ItemStack? = null private var comparator: Comparator>? = null private var inShulkerBoxesOnly: Boolean = false private var invertNewSelectors = false + @ContainerMarker + private constructor( + selection: StackSelection, + count: Int = selection.count + ) : this(count) { + this.whitelistedSlots.addAll(selection.whitelistedSlots) + this.selector = selection.selector + this.item = selection.item + this.itemStack = selection.itemStack + this.comparator = selection.comparator + this.inShulkerBoxesOnly = selection.inShulkerBox + } + fun isItem(item: Item) { this.item = item appendSelector { stack, _ -> stack.item == item } @@ -146,7 +169,7 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { appendSelector { stack, _ -> stack.item in ItemUtils.SHULKER_BOXES } } - fun hasCustomName(name: String) { + fun hasName(name: String) { appendSelector { stack, _ -> stack.name.string == name } @@ -293,6 +316,11 @@ class StackSelectionBuilder private constructor(private val count: Int = 0) { count: Int = 0, builder: StackSelectionBuilder.() -> Unit ) = StackSelectionBuilder(count).apply(builder).build() + + fun StackSelection.mutate( + count: Int = this.count, + builder: StackSelectionBuilder.() -> Unit = {} + ) = StackSelectionBuilder(this, count).apply(builder).build() } } diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/BaritoneHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/BaritoneHandler.kt index b0959604f..85fe0978f 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/BaritoneHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/BaritoneHandler.kt @@ -28,7 +28,7 @@ import com.lambda.config.Tab import com.lambda.config.automation.AutomationConfig import com.lambda.config.blocks.RotationSettings import com.lambda.config.categories.LambdaCategory -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.context.Automated import com.lambda.util.BlockUtils.blockPos import net.minecraft.util.BlockMirror diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index 1740a2eea..be438a6ad 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -26,6 +26,7 @@ import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.Container import com.lambda.interaction.container.ContainerMarker +import com.lambda.interaction.container.ContainerSerializer import com.lambda.interaction.container.PlacedContainer import com.lambda.interaction.container.containers.external.ChestContainer import com.lambda.interaction.container.containers.external.DoubleChestContainer @@ -35,16 +36,17 @@ import com.lambda.interaction.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer import com.lambda.interaction.container.selection.StackSelection -import com.lambda.interaction.container.selection.select -import com.lambda.interaction.handler.handlers.ContainerHandler.filteredContainers +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.mutate +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.util.BlockUtils.blockEntity -import com.lambda.util.BlockUtils.blockState +import com.lambda.util.FolderRegistry import com.lambda.util.ReflectionUtils.getInstances import com.lambda.util.extension.containerStacks import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils.SHULKER_BOXES import com.lambda.util.player.SlotUtils.typeSafe import net.minecraft.block.ChestBlock +import net.minecraft.block.ShulkerBoxBlock import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.block.entity.EnderChestBlockEntity @@ -56,260 +58,307 @@ import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.state.property.Properties import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.ChunkPos +import com.lambda.Lambda +import com.lambda.context.AutomatedSafeContext +import java.nio.file.Files @Suppress("unused") object ContainerHandler : Loadable { - val containers: Sequence - get() { - fun Container.allNested(): Sequence = - sequence { - val nested = storedContainers.values - yieldAll(nested) - nested.forEach { yieldAll(it.allNested()) } - } - val baseContainers = compileContainers.asSequence() + - placedContainers.values.asSequence().flatMap { it.values } - return baseContainers + baseContainers.flatMap { it.allNested() } - } - - val compileContainers = getInstances() - val placedContainers = mutableMapOf>() - - context(automated: Automated) - val filteredContainers - get() = containers - .filter { automated.inventoryConfig.containerSelection.matches(it) } - .sorted() - - var lastInteractedBlockEntity: BlockEntity? = null - var pendingInteractedBlockEntity: BlockEntity? = null - - override fun load() = "Loaded ${compileContainers.size} containers" - - init { - listen { event -> - val packet = event.packet as? PlayerInteractBlockC2SPacket ?: return@listen - val entity = blockEntity(packet.blockHitResult.blockPos) - pendingInteractedBlockEntity = entity - lastInteractedBlockEntity = entity - } - - listen { event -> - val sh = event.screenHandler - onContainerUpdate(sh) - if (sh.syncId != 0 && pendingInteractedBlockEntity == null) { - lastInteractedBlockEntity = null - } - } - - listen { - if (it.screenHandler.syncId != 0) { - pendingInteractedBlockEntity = null - } - } - - listen { onContainerUpdate() } - listen { onContainerUpdate() } - - listen { event -> - val pos = event.pos - val containersInChunk = placedContainers[ChunkPos(pos)] ?: return@listen - val cachedContainer = containersInChunk[pos] ?: return@listen - val currentState = blockState(cachedContainer.pos) - if (currentState.block != event.newState.block) { - containersInChunk.remove(pos) - } - } - - listen { event -> - val chunk = event.chunk - val cachedContainers = placedContainers[chunk.pos] ?: return@listen - cachedContainers.values.retainAll { container -> - val matchingEntity = chunk.blockEntities[container.pos] ?: return@retainAll false - blockState(container.pos).block == matchingEntity.cachedState.block - } - } - } - - private fun SafeContext.onContainerUpdate(sh: ScreenHandler = player.currentScreenHandler) { - val blockEntity = lastInteractedBlockEntity - if (blockEntity != null) updatePlacedContainer(sh, blockEntity) - } - - private fun updatePlacedContainer( - sh: ScreenHandler, - blockEntity: BlockEntity - ) { - val pos = blockEntity.pos - when (blockEntity) { - is EnderChestBlockEntity -> { - if (sh.typeSafe != ScreenHandlerType.GENERIC_9X3) return - EnderChestContainer.apply { - update(sh.containerStacks) - scanContainerContents() - } - } - - is ChestBlockEntity -> { - val state = blockEntity.cachedState - if (state.block !is ChestBlock) return - - val stacks = blockEntity.stacks() - val chestType = state.get(Properties.CHEST_TYPE) ?: return - val chunkPos = ChunkPos(pos) - - if (chestType == ChestType.SINGLE) { - if (sh.typeSafe != ScreenHandlerType.GENERIC_9X3) return - (chunkPos.getPlacedContainer(pos) as? ChestContainer) - ?.update(stacks) - ?: run { chunkPos.setPlacedContainer(pos, ChestContainer(pos, stacks)) } - } else { - if (sh.typeSafe != ScreenHandlerType.GENERIC_9X6) return - val facing = state.get(Properties.HORIZONTAL_FACING) ?: return - val otherPos = - when (chestType) { - ChestType.LEFT -> pos.offset(facing.rotateYClockwise()) - ChestType.RIGHT -> pos.offset(facing.rotateYCounterclockwise()) - } - val leftPos = if (chestType == ChestType.LEFT) pos else otherPos - val leftChunkPos = ChunkPos(leftPos) - val rightPos = if (chestType == ChestType.RIGHT) pos else otherPos - val rightChunkPos = ChunkPos(rightPos) - - val existing = (leftChunkPos.getPlacedContainer(leftPos) as? DoubleChestContainer) - ?: (rightChunkPos.getPlacedContainer(rightPos) as? DoubleChestContainer) - - if (existing != null) { - existing.update(stacks) - leftChunkPos.setPlacedContainer(leftPos, existing) - rightChunkPos.setPlacedContainer(rightPos, existing) - } else { - val doubleChest = DoubleChestContainer(pos, leftPos, rightPos, stacks) - leftChunkPos.setPlacedContainer(leftPos, doubleChest) - rightChunkPos.setPlacedContainer(rightPos, doubleChest) - } - } - - chunkPos.getPlacedContainer(pos)?.scanContainerContents() - } - - is ShulkerBoxBlockEntity -> { - if (sh.typeSafe != ScreenHandlerType.SHULKER_BOX) return - val stacks = blockEntity.stacks() - val chunkPos = ChunkPos(pos) - (chunkPos.getPlacedContainer(pos) as? PlacedShulkerBoxContainer) - ?.update(stacks) - ?: run { - chunkPos.setPlacedContainer( - pos, - PlacedShulkerBoxContainer(pos, blockEntity.cachedState.block, null, stacks) - ) - } - - chunkPos.getPlacedContainer(pos)?.scanContainerContents() - } - } - } - - private fun Container.scanContainerContents() { - slots.forEach { slot -> - val stack = slot.stack - val index = slot.index - if (stack.item in SHULKER_BOXES) { - storedContainers[index] = - ShulkerBoxContainer( - stack.name.string, - stack.item, - stack.shulkerBoxStacks, - this, - index - ).also { it.scanContainerContents() } - } else storedContainers.remove(index) - } - } - - private fun getPlacedContainer(pos: BlockPos) = placedContainers[ChunkPos(pos)]?.get(pos) - - private fun ChunkPos.getPlacedContainer(pos: BlockPos) = placedContainers[this]?.get(pos) - - private fun setPlacedContainer(pos: BlockPos, container: PlacedContainer) = - placedContainers.getOrPut(ChunkPos(pos)) { mutableMapOf() }.put(pos, container) - - private fun ChunkPos.setPlacedContainer(pos: BlockPos, container: PlacedContainer) = - placedContainers.getOrPut(this) { mutableMapOf() }.put(pos, container) - - private fun Inventory.stacks() = iterator().asSequence().toList() + val compileContainers = getInstances() + var accessedPlacedContainer: PlacedContainer? = null + private set + + var lastInteractedBlockEntity: BlockEntity? = null + var pendingInteractedBlockEntity: BlockEntity? = null + + override fun load(): String { + ContainerSerializer.loadEnderChest() + return "Loaded ${compileContainers.size} containers" + } + + init { + listen { event -> + val packet = event.packet as? PlayerInteractBlockC2SPacket ?: return@listen + val entity = blockEntity(packet.blockHitResult.blockPos) + pendingInteractedBlockEntity = entity + lastInteractedBlockEntity = entity + } + + listen { event -> + val sh = event.screenHandler + onContainerUpdate(sh) + if (sh.syncId != 0 && pendingInteractedBlockEntity == null) { + lastInteractedBlockEntity = null + } + accessedPlacedContainer = null + } + + listen { + if (it.screenHandler.syncId != 0) { + pendingInteractedBlockEntity = null + } + } + + listen { onContainerUpdate() } + listen { onContainerUpdate() } + + listen { event -> + val oldBlock = event.oldState.block + if (oldBlock is ChestBlock || oldBlock is ShulkerBoxBlock) { + if (event.newState.block != oldBlock) { + ContainerSerializer.removeContainer(event.pos) + } + } + } + + listen { event -> + val chunk = event.chunk + val prefix = "${chunk.pos.x}_${chunk.pos.z}_" + + try { + val dir = FolderRegistry.containers + if (Files.exists(dir)) { + Files.newDirectoryStream(dir, "$prefix*.json").use { stream -> + stream.forEach { path -> + val parts = path.fileName.toString().removeSuffix(".json").split('_') + if (parts.size == 5) { + val x = parts[2].toIntOrNull() ?: return@forEach + val y = parts[3].toIntOrNull() ?: return@forEach + val z = parts[4].toIntOrNull() ?: return@forEach + val pos = BlockPos(x, y, z) + val entity = chunk.blockEntities[pos] + if (entity !is ChestBlockEntity && entity !is ShulkerBoxBlockEntity) { + Files.deleteIfExists(path) + } + } + } + } + } + } catch (e: Exception) { + Lambda.LOG.warn("Failed to clean up ghost containers for chunk ${chunk.pos}", e) + } + } + } + + private fun SafeContext.onContainerUpdate(sh: ScreenHandler = player.currentScreenHandler) { + val blockEntity = lastInteractedBlockEntity + if (blockEntity != null) updatePlacedContainer(sh, blockEntity) + } + + private fun updatePlacedContainer( + sh: ScreenHandler, + blockEntity: BlockEntity + ) { + val pos = blockEntity.pos + when (blockEntity) { + is EnderChestBlockEntity -> { + if (sh.typeSafe != ScreenHandlerType.GENERIC_9X3) return + EnderChestContainer.apply { + update(sh.containerStacks) + scanContainerContents() + } + ContainerSerializer.saveEnderChest() + } + + is ChestBlockEntity -> { + val state = blockEntity.cachedState + if (state.block !is ChestBlock) return + + val stacks = blockEntity.stacks() + val chestType = state.get(Properties.CHEST_TYPE) ?: return + + if (chestType == ChestType.SINGLE) { + if (sh.typeSafe != ScreenHandlerType.GENERIC_9X3) return + (accessedPlacedContainer as? ChestContainer) + ?.update(stacks) + ?: run { accessedPlacedContainer = ChestContainer(pos, stacks) } + } else { + if (sh.typeSafe != ScreenHandlerType.GENERIC_9X6) return + val facing = state.get(Properties.HORIZONTAL_FACING) ?: return + val otherPos = + when (chestType) { + ChestType.LEFT -> pos.offset(facing.rotateYClockwise()) + ChestType.RIGHT -> pos.offset(facing.rotateYCounterclockwise()) + } + val leftPos = if (chestType == ChestType.LEFT) pos else otherPos + val rightPos = if (chestType == ChestType.RIGHT) pos else otherPos + + val existing = accessedPlacedContainer as? DoubleChestContainer + if (existing != null && existing.pos == pos) { + existing.update(stacks) + } else { + accessedPlacedContainer = DoubleChestContainer(pos, leftPos, rightPos, stacks) + } + } + + accessedPlacedContainer?.let { + it.scanContainerContents() + ContainerSerializer.saveContainer(it) + } + } + + is ShulkerBoxBlockEntity -> { + if (sh.typeSafe != ScreenHandlerType.SHULKER_BOX) return + val stacks = blockEntity.stacks() + (accessedPlacedContainer as? PlacedShulkerBoxContainer) + ?.update(stacks) + ?: run { + accessedPlacedContainer = PlacedShulkerBoxContainer(pos, blockEntity.cachedState.block, null, stacks) + } + + accessedPlacedContainer?.let { + it.scanContainerContents() + ContainerSerializer.saveContainer(it) + } + } + } + } + + private fun Container.scanContainerContents() { + slots.forEach { slot -> + val stack = slot.stack + val index = slot.index + if (stack.item in SHULKER_BOXES) { + storedContainers[index] = + ShulkerBoxContainer( + stack.name.string, + stack.item, + stack.shulkerBoxStacks, + this, + index + ).also { it.scanContainerContents() } + } else storedContainers.remove(index) + } + } + + private fun Inventory.stacks() = iterator().asSequence().toList() } @ContainerMarker -context(_: Automated) -fun findContainer( - selection: ContainerSelection -) = filteredContainers.find(selection) +context(_: AutomatedSafeContext) +fun StackSelection.move( + fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, + toSelection: ContainerSelection = ContainerSelection.EVERYTHING, + toStackSelection: StackSelection = StackSelection.EVERYTHING +): Boolean { + val singleSelection = mutate(count.coerceAtMost(64)) + val fromContainer = + findContainer( + singleSelection, + selectContainer { + matches(fromSelection) + isAccessed() + } + ) + ?: return false + + val toContainer = + findContainer( + toStackSelection, + selectContainer { + matches(toSelection) + isAccessed() + } + ) + ?: return false + + val (fromSlot, toSlot) = fromContainer.findMoveSlots(this, toContainer, toStackSelection) + if (fromSlot == null || toSlot == null) return false + + return fromContainer.swap(fromSlot, toSlot, toContainer) +} @ContainerMarker -context(automated: Automated) -fun StackSelection.findContainer( - selection: ContainerSelection = ContainerSelection.EVERYTHING -) = findContainers(selection).firstOrNull() +context(_: Automated) +fun findContainer( + stackSelection: StackSelection = StackSelection.EVERYTHING, + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +) = findContainers(stackSelection, containerSelection) + .firstOrNull() @ContainerMarker context(automated: Automated) -fun StackSelection.findContainers( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING -) = filteredContainers - .filter { containerSelection.matches(it) } - .filter { it.stackCount(this) >= count } - .sortedWith(automated.inventoryConfig.accessPriority.materialComparator(this)) +fun findContainers( + stackSelection: StackSelection = StackSelection.EVERYTHING, + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +) = searchContainers(containerSelection.scope) + .filter { containerSelection.matches(it) } + .filter { stackSelection isIn it } + .sortedWith(automated.inventoryConfig.accessPriority.materialComparator(stackSelection)) @ContainerMarker -context(automated: Automated) +context(_: Automated) fun StackSelection.findContainerWithSpace( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING -) = findContainersWithSpace(containerSelection).firstOrNull() + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +) = findContainersWithSpace(containerSelection) + .firstOrNull() @ContainerMarker context(automated: Automated) fun StackSelection.findContainersWithSpace( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING -) = filteredContainers - .filter { containerSelection.matches(it) } - .filter { it.spaceAvailable(this) >= count } - .sortedWith(automated.inventoryConfig.accessPriority.spaceComparator(this)) + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +) = searchContainers(containerSelection.scope) + .filter { containerSelection.matches(it) } + .filter { this spaceIn it } + .sortedWith(automated.inventoryConfig.accessPriority.spaceComparator(this)) @ContainerMarker -context(automated: Automated) -fun StackSelection.findSlots( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING -) = - findContainers( - selectContainer { - matches(containerSelection) - isAccessed() - } - ).flatMap { filter(it.slots) } +context(_: Automated) +fun findContainerWithDisposable( + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +) = findContainersWithDisposable(containerSelection) + .firstOrNull() @ContainerMarker context(automated: Automated) -fun findContainerWithDisposable( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +fun findContainersWithDisposable( + containerSelection: ContainerSelection = ContainerSelection.EVERYTHING ) = - with(automated) { - findContainer( - selectContainer { - matches(containerSelection) - custom { container -> - inventoryConfig.disposables.any { container.stackCount(it.asItem().select(1)) > 0 } - } - } - ) - } - -private fun getSearchContainers(scope: ContainerSearchScope): Collection { + with(automated) { + findContainers( + containerSelection = selectContainer(containerSelection.scope) { + matches(containerSelection) + matchesStacks( + selectStack(1) { + isOneOfItems(inventoryConfig.disposables) + } + ) + } + ) + } +context(automated: Automated) +private fun searchContainers(scope: ContainerSearchScope): Sequence { + fun Container.allNested(): Sequence = + sequence { + yield(this@allNested) + storedContainers.values.forEach { nested -> + yieldAll(nested.allNested()) + } + } + + val compiled = ContainerHandler.compileContainers.asSequence() + val placedSeq = sequenceOf(ContainerHandler.accessedPlacedContainer).filterNotNull() + + val baseContainers = + when (scope) { + ContainerSearchScope.Player -> compiled - EnderChestContainer + ContainerSearchScope.Compiled -> compiled + ContainerSearchScope.Accessed -> placedSeq + compiled.filter { it.isAccessed } + ContainerSearchScope.All -> compiled + placedSeq + + ContainerSerializer.serializedContainers.filter { diskContainer -> + diskContainer.pos != ContainerHandler.accessedPlacedContainer?.pos + } + } + + return baseContainers + .flatMap { it.allNested() } + .filter { automated.inventoryConfig.containerSelection.matches(it) } } -private enum class ContainerSearchScope { - +enum class ContainerSearchScope { + Player, + Compiled, + Accessed, + All } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt index 87225c54f..d7de19c14 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt @@ -17,9 +17,11 @@ package com.lambda.interaction.handler.handlers +import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.container.selection.StackAndSlot import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.module.modules.combat.AutoArmor @@ -164,14 +166,18 @@ object GlideHandler { } @JvmStatic - context(safeContext: SafeContext) + context(safeContext: SafeContext, _: Automated) fun canGlide(): Boolean = with(safeContext) { val fakeFly = ElytraFly.isEnabled && ElytraFly.fakeFly val canGlideAlready = player.canGlideWithChestPiece() != fakeFly if (!autoSwapChecking || canGlideAlready) return canGlideAlready val selection = if (fakeFly) CHESTPLATE_SELECTION else ELYTRA_SELECTION - return selection.findContainers(HOTBAR_AND_INVENTORY_CONTAINERS) + return findContainers( + selection, + ContainerSelection.HOTBAR_AND_INVENTORY + ).toList() + .isNotEmpty() } private class PendingGlideAction( diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/InteractedBlockHandler.kt similarity index 94% rename from src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/InteractedBlockHandler.kt index b5dc73358..829ce02ed 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/interacting/InteractedBlockHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/InteractedBlockHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handler.handlers.interacting +package com.lambda.interaction.handler.handlers import com.lambda.config.automation.AutomationConfig import com.lambda.config.blocks.InteractConfig @@ -32,8 +32,8 @@ import com.lambda.util.collections.LimitedDecayQueue internal object InteractedBlockHandler : PostActionHandler() { override val pendingActions = LimitedDecayQueue( - AutomationConfig.DEFAULT.buildConfig.maxPendingActions, - AutomationConfig.DEFAULT.buildConfig.actionTimeout * 50L + AutomationConfig.Companion.DEFAULT.buildConfig.maxPendingActions, + AutomationConfig.Companion.DEFAULT.buildConfig.actionTimeout * 50L ) { if (Client.verboseDebug) warn("${it::class.simpleName} at ${it.context.blockPos.toShortString()} timed out") if (it.interactConfig.interactConfirmationMode != InteractConfig.InteractConfirmationMode.AwaitThenPlace) { diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/PacketLimitHandler.kt similarity index 97% rename from src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt rename to src/main/kotlin/com/lambda/interaction/handler/handlers/PacketLimitHandler.kt index 6229e1e29..8820cd659 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/packet/PacketLimitHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/PacketLimitHandler.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.lambda.interaction.handler.handlers.packet +package com.lambda.interaction.handler.handlers import com.lambda.config.blocks.BuildConfig import com.lambda.context.Automated diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt index 5817eb84c..f800db9ff 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt @@ -26,8 +26,8 @@ import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.BreakContext import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.reBreak -import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler -import com.lambda.interaction.handler.handlers.packet.PacketType +import com.lambda.interaction.handler.handlers.PacketLimitHandler +import com.lambda.interaction.handler.handlers.PacketType import com.lambda.interaction.manager.managers.breaking.BreakInfo import com.lambda.interaction.manager.managers.breaking.BreakManager import com.lambda.interaction.manager.managers.breaking.BreakManager.calcBreakDelta diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt index 64ab9cd82..00a14ab4e 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt @@ -42,8 +42,8 @@ import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.start import com.lambda.interaction.handler.handlers.breaking.RebreakHandler import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.getRebreakPotential import com.lambda.interaction.handler.handlers.breaking.RebreakResult -import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler -import com.lambda.interaction.handler.handlers.packet.PacketType +import com.lambda.interaction.handler.handlers.PacketLimitHandler +import com.lambda.interaction.handler.handlers.PacketType import com.lambda.interaction.manager.Manager import com.lambda.interaction.manager.ManagerUtils.isPosBlocked import com.lambda.interaction.manager.PositionBlocking diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt index 4c57ca26a..315281898 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/interacting/InteractManager.kt @@ -28,10 +28,10 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.InteractContext -import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler -import com.lambda.interaction.handler.handlers.interacting.InteractedBlockHandler.startPending -import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler -import com.lambda.interaction.handler.handlers.packet.PacketType +import com.lambda.interaction.handler.handlers.InteractedBlockHandler +import com.lambda.interaction.handler.handlers.InteractedBlockHandler.startPending +import com.lambda.interaction.handler.handlers.PacketLimitHandler +import com.lambda.interaction.handler.handlers.PacketType import com.lambda.interaction.manager.Manager import com.lambda.interaction.manager.ManagerUtils.isPosBlocked import com.lambda.interaction.manager.PositionBlocking diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryManager.kt index ee90518eb..62fda5e39 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/inventory/InventoryManager.kt @@ -22,9 +22,9 @@ import com.lambda.context.SafeContext import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler.canSendPackets -import com.lambda.interaction.handler.handlers.packet.PacketLimitHandler.sentPackets -import com.lambda.interaction.handler.handlers.packet.PacketType +import com.lambda.interaction.handler.handlers.PacketLimitHandler.canSendPackets +import com.lambda.interaction.handler.handlers.PacketLimitHandler.sentPackets +import com.lambda.interaction.handler.handlers.PacketType import com.lambda.interaction.manager.Manager import com.lambda.interaction.manager.managers.inventory.InventoryManager.actions import com.lambda.interaction.manager.managers.inventory.InventoryManager.activeRequest diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/kotlin/com/lambda/module/HudModule.kt b/src/main/kotlin/com/lambda/module/HudModule.kt index 9b3d571e4..23be5636b 100644 --- a/src/main/kotlin/com/lambda/module/HudModule.kt +++ b/src/main/kotlin/com/lambda/module/HudModule.kt @@ -19,7 +19,7 @@ package com.lambda.module import com.lambda.config.settings.complex.Bind import com.lambda.gui.Layout -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import java.awt.Color abstract class HudModule( diff --git a/src/main/kotlin/com/lambda/module/Module.kt b/src/main/kotlin/com/lambda/module/Module.kt index 0f106d0db..593fdce38 100644 --- a/src/main/kotlin/com/lambda/module/Module.kt +++ b/src/main/kotlin/com/lambda/module/Module.kt @@ -23,8 +23,8 @@ import com.lambda.config.ConfigCategory import com.lambda.config.automation.IMutableAutomationConfig import com.lambda.config.automation.MutableAutomationConfig import com.lambda.config.categories.ModuleCategory -import com.lambda.config.entries.Setting.Companion.onValueChange -import com.lambda.config.entries.Setting.Companion.onValueChangeUnsafe +import com.lambda.config.entries.onValueChange +import com.lambda.config.entries.onValueChangeUnsafe import com.lambda.config.settings.complex.Bind import com.lambda.config.settings.complex.KeybindSetting.Companion.onPress import com.lambda.config.settings.complex.KeybindSetting.Companion.onRelease @@ -41,7 +41,6 @@ import com.lambda.event.listener.SafeListener import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener import com.lambda.module.modules.client.Client -import com.lambda.module.tag.ModuleTag import com.lambda.sound.LambdaSound import com.lambda.sound.SoundHandler.play import com.lambda.util.KeyCode diff --git a/src/main/kotlin/com/lambda/module/tag/ModuleTag.kt b/src/main/kotlin/com/lambda/module/ModuleTag.kt similarity index 96% rename from src/main/kotlin/com/lambda/module/tag/ModuleTag.kt rename to src/main/kotlin/com/lambda/module/ModuleTag.kt index caab346cc..e01c0d70b 100644 --- a/src/main/kotlin/com/lambda/module/tag/ModuleTag.kt +++ b/src/main/kotlin/com/lambda/module/ModuleTag.kt @@ -15,12 +15,12 @@ * along with this program. If not, see . */ -package com.lambda.module.tag +package com.lambda.module import com.lambda.util.Nameable /** - * The [ModuleTag] class represents a tag, that can be associated in any cardinality with a [Module]. + * The [ModuleTag] class represents a tag, that can be associated in any cardinality with a [java.lang.Module]. * * Tags are used to categorize and organize modules, making them easier to find. * They can be custom created as per the user's needs. @@ -61,4 +61,4 @@ data class ModuleTag(override val name: String) : Nameable { fun isTagShown(tag: ModuleTag) = shownTags.contains(tag) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/module/hud/AccountName.kt b/src/main/kotlin/com/lambda/module/hud/AccountName.kt index 7b81bdaa3..24289c330 100644 --- a/src/main/kotlin/com/lambda/module/hud/AccountName.kt +++ b/src/main/kotlin/com/lambda/module/hud/AccountName.kt @@ -19,7 +19,7 @@ package com.lambda.module.hud import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/hud/Baritone.kt b/src/main/kotlin/com/lambda/module/hud/Baritone.kt index 438671ece..fa0e9c10b 100644 --- a/src/main/kotlin/com/lambda/module/hud/Baritone.kt +++ b/src/main/kotlin/com/lambda/module/hud/Baritone.kt @@ -21,7 +21,7 @@ import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.interaction.construction.simulation.BuildGoal import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag @Suppress("unused") object Baritone : HudModule( diff --git a/src/main/kotlin/com/lambda/module/hud/Coordinates.kt b/src/main/kotlin/com/lambda/module/hud/Coordinates.kt index a09dae66f..5498a2d2a 100644 --- a/src/main/kotlin/com/lambda/module/hud/Coordinates.kt +++ b/src/main/kotlin/com/lambda/module/hud/Coordinates.kt @@ -23,7 +23,7 @@ import com.lambda.config.editSetting import com.lambda.config.withEdits import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.FormattingUtils.format import com.lambda.util.extension.dimensionName diff --git a/src/main/kotlin/com/lambda/module/hud/Fps.kt b/src/main/kotlin/com/lambda/module/hud/Fps.kt index 917238a02..2dcf3a3a9 100644 --- a/src/main/kotlin/com/lambda/module/hud/Fps.kt +++ b/src/main/kotlin/com/lambda/module/hud/Fps.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.RenderEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.collections.LimitedDecayQueue import kotlin.time.Duration.Companion.seconds diff --git a/src/main/kotlin/com/lambda/module/hud/ModuleList.kt b/src/main/kotlin/com/lambda/module/hud/ModuleList.kt index cd438fbc2..6180de437 100644 --- a/src/main/kotlin/com/lambda/module/hud/ModuleList.kt +++ b/src/main/kotlin/com/lambda/module/hud/ModuleList.kt @@ -21,7 +21,7 @@ import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.imgui.flag.ImGuiCol import com.lambda.module.HudModule import com.lambda.module.ModuleRegistry -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import java.awt.Color @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/hud/Rotation.kt b/src/main/kotlin/com/lambda/module/hud/Rotation.kt index b9246cd0b..6530c1992 100644 --- a/src/main/kotlin/com/lambda/module/hud/Rotation.kt +++ b/src/main/kotlin/com/lambda/module/hud/Rotation.kt @@ -22,7 +22,7 @@ import com.lambda.config.editSetting import com.lambda.config.withEdits import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.FormattingUtils.format diff --git a/src/main/kotlin/com/lambda/module/hud/Speedometer.kt b/src/main/kotlin/com/lambda/module/hud/Speedometer.kt index 5ef49be74..354e8b719 100644 --- a/src/main/kotlin/com/lambda/module/hud/Speedometer.kt +++ b/src/main/kotlin/com/lambda/module/hud/Speedometer.kt @@ -22,7 +22,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.SpeedUnit import net.minecraft.util.math.Vec3d diff --git a/src/main/kotlin/com/lambda/module/hud/TaskFlowHud.kt b/src/main/kotlin/com/lambda/module/hud/TaskFlowHud.kt index eaa6aadf4..326b2b363 100644 --- a/src/main/kotlin/com/lambda/module/hud/TaskFlowHud.kt +++ b/src/main/kotlin/com/lambda/module/hud/TaskFlowHud.kt @@ -19,7 +19,7 @@ package com.lambda.module.hud import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.RootTask @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/hud/Tps.kt b/src/main/kotlin/com/lambda/module/hud/Tps.kt index 3c94e178e..2d8c4fb97 100644 --- a/src/main/kotlin/com/lambda/module/hud/Tps.kt +++ b/src/main/kotlin/com/lambda/module/hud/Tps.kt @@ -20,7 +20,7 @@ package com.lambda.module.hud import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.imgui.ImVec2 import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.FormattingUtils.format import com.lambda.util.ServerTPSUtils import com.lambda.util.ServerTPSUtils.recentData diff --git a/src/main/kotlin/com/lambda/module/hud/Watermark.kt b/src/main/kotlin/com/lambda/module/hud/Watermark.kt index fa46da254..4436e3f2d 100644 --- a/src/main/kotlin/com/lambda/module/hud/Watermark.kt +++ b/src/main/kotlin/com/lambda/module/hud/Watermark.kt @@ -21,7 +21,7 @@ import com.lambda.graphics.texture.TextureOwner.upload import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.imgui.ImGui import com.lambda.module.HudModule -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag @Suppress("unused") object Watermark : HudModule( diff --git a/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt b/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt index 25c6dab7f..cb55a5b9b 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt @@ -24,7 +24,7 @@ import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.ChatUtils.addresses import com.lambda.util.ChatUtils.colors import com.lambda.util.ChatUtils.discord diff --git a/src/main/kotlin/com/lambda/module/modules/chat/ChatTimestamp.kt b/src/main/kotlin/com/lambda/module/modules/chat/ChatTimestamp.kt index 9fafeecbb..f3a7fded9 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/ChatTimestamp.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/ChatTimestamp.kt @@ -20,13 +20,13 @@ package com.lambda.module.modules.chat import com.lambda.config.blocks.FormatterConfig import com.lambda.config.blocks.FormatterSettings import com.lambda.config.editTypedSettings -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.hide import com.lambda.config.withEdits import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.FormattingUtils.format import com.lambda.util.text.buildText import com.lambda.util.text.literal diff --git a/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt b/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt index 3357ecf63..4cff328bd 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/CustomChat.kt @@ -23,7 +23,7 @@ import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.NamedEnum @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt b/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt index c9220aeb6..074b96cd8 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/FancyChat.kt @@ -22,7 +22,7 @@ import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.ChatUtils.toBlue import com.lambda.util.ChatUtils.toGreen import com.lambda.util.ChatUtils.toLeet diff --git a/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt b/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt index 604d03a0f..239dcec05 100644 --- a/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt +++ b/src/main/kotlin/com/lambda/module/modules/chat/FriendHighlight.kt @@ -17,12 +17,12 @@ package com.lambda.module.modules.chat -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.event.events.ChatEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.sound.SoundHandler.playSound import com.lambda.util.CommunicationUtils.logError import com.lambda.util.text.MessageType diff --git a/src/main/kotlin/com/lambda/module/modules/client/AutoUpdater.kt b/src/main/kotlin/com/lambda/module/modules/client/AutoUpdater.kt index 9d62142d3..4d3dd975e 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/AutoUpdater.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/AutoUpdater.kt @@ -26,7 +26,7 @@ import com.lambda.gui.dsl.ImGuiBuilder.popupModal import com.lambda.imgui.ImGui import com.lambda.imgui.flag.ImGuiWindowFlags import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runIO import com.lambda.util.CommunicationUtils.debug import com.lambda.util.CommunicationUtils.logError diff --git a/src/main/kotlin/com/lambda/module/modules/client/Capes.kt b/src/main/kotlin/com/lambda/module/modules/client/Capes.kt index e1e42039f..bb42498e2 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/Capes.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/Capes.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.client import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object Capes : Module( name = "Capes", diff --git a/src/main/kotlin/com/lambda/module/modules/client/Client.kt b/src/main/kotlin/com/lambda/module/modules/client/Client.kt index 180314afd..a56bd2565 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/Client.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/Client.kt @@ -22,7 +22,7 @@ import com.lambda.config.Tab import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.interaction.construction.simulation.result.Drawable import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import java.awt.Color object Client : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/client/Discord.kt b/src/main/kotlin/com/lambda/module/modules/client/Discord.kt index 7858e254f..2679a1052 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/Discord.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/Discord.kt @@ -24,7 +24,7 @@ import com.lambda.event.EventFlow import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listenOnce import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.network.NetworkHandler.updateToken import com.lambda.network.api.v1.endpoints.linkDiscord import com.lambda.threading.runConcurrent diff --git a/src/main/kotlin/com/lambda/module/modules/client/ModuleNotifier.kt b/src/main/kotlin/com/lambda/module/modules/client/ModuleNotifier.kt index 95425ca6b..40a791379 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/ModuleNotifier.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/ModuleNotifier.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.client import com.lambda.event.events.ModuleEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.log import com.lambda.util.Describable import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt index bbb40e5ce..b5a5518d5 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.combat -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.settings.complex.Bind import com.lambda.config.settings.complex.KeybindSetting.Companion.onPress @@ -26,9 +26,13 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.containers.ArmorContainer +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.select +import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.handler.handlers.findContainers import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemUtils.armorSlot import net.minecraft.component.DataComponentTypes @@ -118,18 +122,23 @@ object AutoArmor : Module( fun SafeContext.tick() { tickedThisTick = true - val armorSlots = ArmorContainer.slots - - val swappable = HotbarAndInventoryContainer.slots - .filter { it.stack.isEquipable && (!ignoreBinding || it.stack.getEnchantment(Enchantments.BINDING_CURSE) <= 0) } + val armorSlots = findContainer(containerSelection = ArmorContainer.select())?.slots ?: return + + val swappable = findContainers(containerSelection = ContainerSelection.HOTBAR_AND_INVENTORY) + .flatMap { it.slots } + .filter { + it.stack.isEquipable(armorSlots) && + (!ignoreBinding || it.stack.getEnchantment(Enchantments.BINDING_CURSE) <= 0) + } .sortedWith(SORTER) .distinctBy { it.stack.armorSlot } val swaps = mutableListOf>() armorSlots.forEach { equipped -> - val new = swappable.find { new -> - equipped.canInsert(new.stack) && SORTER.compare(equipped, new) > 0 - } ?: return@forEach + val new = + swappable.find { new -> + equipped.canInsert(new.stack) && SORTER.compare(equipped, new) > 0 + } ?: return@forEach swaps.add(Pair(new, equipped)) } @@ -144,8 +153,7 @@ object AutoArmor : Module( } context(_: SafeContext) - private val ItemStack.isEquipable - get() = ArmorContainer.slots.any { it.canInsert(this) } + private fun ItemStack.isEquipable(armorSlots: List) = armorSlots.any { it.canInsert(this) } private enum class Protection(val enchant: RegistryKey) { Protection(Enchantments.PROTECTION), diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index 40ff8980a..32c21c1db 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -25,10 +25,9 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.FriendHandler -import com.lambda.interaction.inventory.container.select import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.combat.CombatUtils.hasDeadlyCrystal import com.lambda.util.combat.DamageUtils.isFallDeadly import com.lambda.util.extension.fullHealth diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt b/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt index bc7822c21..1755d1335 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt @@ -23,7 +23,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.PacketUtils.sendPacket import com.lambda.util.extension.rotation import com.lambda.util.math.component1 diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 09a6e4a44..39ccad79d 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.combat import com.lambda.config.Tab -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.blocks.TargetingSettings import com.lambda.config.hide import com.lambda.config.hideAllExcept @@ -28,14 +28,17 @@ import com.lambda.event.events.EntityEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.container.containers.OffHandContainer -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.select +import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.handler.handlers.move import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated import com.lambda.threading.runSafeGameScheduled @@ -49,7 +52,7 @@ import com.lambda.util.extension.fullHealth import com.lambda.util.math.MathUtils.ceilToInt import com.lambda.util.math.MathUtils.roundToStep import com.lambda.util.math.distSq -import com.lambda.util.math.flooredBlockPos +import com.lambda.util.math.blockPos import com.lambda.util.math.getHitVec import com.lambda.util.math.minus import com.lambda.util.math.plus @@ -480,21 +483,33 @@ object CrystalAura : Module( if (rotate && !rotationRequest { rotation(placeRotation) }.submit().done) return@runSafe - val selection = selectStack { isItem(Items.END_CRYSTAL) } + val selection = Items.END_CRYSTAL.select() + if ((swapHand == Hand.MAIN_HAND && player.mainHandStack.item != selection.item) || (swapHand == Hand.OFF_HAND && player.offHandStack.item != selection.item) ) runSafeAutomated { if (!swap) return@runSafe - var crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.matches(it) } - if (crystalSlot < 0) { - val swapTo = when (swapHand) { - Hand.MAIN_HAND -> HotbarContainer - Hand.OFF_HAND -> OffHandContainer - } - if (!selection.move(swapTo)) return@runSafe - crystalSlot = HotbarContainer.stacks.indexOfFirst { selection.matches(it) } + + val toContainer = + when (swapHand) { + Hand.MAIN_HAND -> HotbarContainer + Hand.OFF_HAND -> OffHandContainer + }.select() + + val crystalSlot = findContainer(selection, toContainer) + ?.findSlot(selection) + + if (crystalSlot == null) { + if (!selection.move(InventoryContainer.select(), toContainer)) return@runSafe + } + + if (swapHand == Hand.MAIN_HAND) { + val crystalSlot = selection + .bestMatch(HotbarContainer.slots) + ?.index + ?: return@runSafe + if (crystalSlot < 0 || !hotbarRequest(crystalSlot).submit().done) return@runSafe } - if (!hotbarRequest(crystalSlot).submit().done) return@runSafe } placeTimer.runSafeIfPassed(placeDelay.milliseconds) { @@ -531,7 +546,7 @@ object CrystalAura : Module( } private val EndCrystalEntity.baseBlockPos get() = - (pos - Vec3d(0.0, 0.5, 0.0)).flooredBlockPos + (pos - Vec3d(0.0, 0.5, 0.0)).blockPos private val BlockPos.crystalPosition get() = this.getHitVec(Direction.UP) diff --git a/src/main/kotlin/com/lambda/module/modules/combat/FakePlayer.kt b/src/main/kotlin/com/lambda/module/modules/combat/FakePlayer.kt index 266fad905..318fad2fb 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/FakePlayer.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/FakePlayer.kt @@ -24,7 +24,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.SafeListener.Companion.listenConcurrently import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.network.mojang.getProfile import com.lambda.threading.onShutdown import com.lambda.util.Timer diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index 8bee87050..2ae087f05 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.combat import com.lambda.config.Tab -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.blocks.TargetingSettings import com.lambda.config.editSetting import com.lambda.config.hide @@ -33,7 +33,7 @@ import com.lambda.interaction.container.selection.StackSelectionBuilder.Companio import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafeAutomated import com.lambda.util.NamedEnum import com.lambda.util.item.ItemStackUtils.attackDamage diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index 761c0bf67..3b68b1217 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -17,23 +17,26 @@ package com.lambda.module.modules.combat -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editTypedSettings import com.lambda.config.hideBlock import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.handler.handlers.FriendHandler.isFriend +import com.lambda.interaction.handler.handlers.findContainer import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build import com.lambda.util.BlockUtils.blockState import com.lambda.util.extension.shrinkByEpsilon import com.lambda.util.item.ItemUtils.block -import com.lambda.util.math.flooredBlockPos +import com.lambda.util.math.blockPos import com.lambda.util.world.entitySearch import net.minecraft.block.Blocks import net.minecraft.client.network.OtherClientPlayerEntity @@ -68,14 +71,26 @@ object PlayerTrap : Module( onEnable { task = tickingBlueprint { - val block = HotbarAndInventoryContainer.stacks.firstOrNull { - it.item is BlockItem && blocks.contains(it.item.block) - }?.item?.block ?: return@tickingBlueprint emptyMap() - val targetPlayer = if (self) player - else entitySearch( - buildConfig.blockReach, - player.eyePos.flooredBlockPos - ).firstOrNull { friends || !isFriend(it.gameProfile) } ?: return@tickingBlueprint emptyMap() + val selection = + selectStack { + custom { stack, _ -> + stack.item is BlockItem && blocks.contains(stack.item.block) + } + } + + val block = findContainer(selection, ContainerSelection.HOTBAR_AND_INVENTORY) + ?.findStack(selection) + ?.item?.block + ?: return@tickingBlueprint emptyMap() + + val targetPlayer = + if (self) player + else entitySearch( + buildConfig.blockReach, + player.eyePos.blockPos + ).firstOrNull { friends || !isFriend(it.gameProfile) } + ?: return@tickingBlueprint emptyMap() + getTrapPositions(targetPlayer).associateWith { TargetState.Block(block) } }.build(finishOnDone = false) .start() @@ -84,8 +99,8 @@ object PlayerTrap : Module( } fun SafeContext.getTrapPositions(player: PlayerEntity): Set { - val min = player.boundingBox.shrinkByEpsilon().minPos.flooredBlockPos.add(-1, -1, -1) - val max = player.boundingBox.shrinkByEpsilon().maxPos.flooredBlockPos.add(1, 1, 1) + val min = player.boundingBox.shrinkByEpsilon().minPos.blockPos.add(-1, -1, -1) + val max = player.boundingBox.shrinkByEpsilon().maxPos.blockPos.add(1, 1, 1) return buildSet { (min.x + 1.. diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt index fe24c73f8..552cad24c 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt @@ -17,15 +17,18 @@ package com.lambda.module.modules.combat -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editTypedSettings import com.lambda.config.hideBlock import com.lambda.config.withEdits import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.handler.handlers.findContainer import com.lambda.module.Module import com.lambda.module.modules.combat.PlayerTrap.getTrapPositions -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build @@ -58,9 +61,18 @@ object Surround : Module( onEnable { task = tickingBlueprint { - val block = HotbarAndInventoryContainer.stacks.firstOrNull { - it.item is BlockItem && blocks.contains(it.item.block) - }?.item?.block ?: return@tickingBlueprint emptyMap() + val selection = + selectStack { + custom { stack, _ -> + stack.item is BlockItem && blocks.contains(stack.item.block) + } + } + + val block = findContainer(selection, ContainerSelection.HOTBAR_AND_INVENTORY) + ?.findStack(selection) + ?.item?.block + ?: return@tickingBlueprint emptyMap() + getTrapPositions(player) .filter { it.y <= player.blockPos.y } .associateWith { TargetState.Block(block) } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt b/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt index a72292411..0d968759d 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/autodisconnect/AutoDisconnect.kt @@ -28,7 +28,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.gui.components.ClickGuiLayout import com.lambda.interaction.handler.handlers.FriendHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.sound.SoundHandler.playSound import com.lambda.util.CommunicationUtils import com.lambda.util.CommunicationUtils.info diff --git a/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt index 759fc8253..82e684486 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/BaritoneTest.kt @@ -22,7 +22,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag @Suppress("unused") object BaritoneTest : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt index 8dd42d214..71db39448 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.world.blockSearch import net.minecraft.block.Blocks diff --git a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt index 5bcea7fb9..364e2bc90 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/ContainerTest.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.selection.select import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.start import com.lambda.task.tasks.acquireStack import net.minecraft.item.Items diff --git a/src/main/kotlin/com/lambda/module/modules/debug/DebugRendererModule.kt b/src/main/kotlin/com/lambda/module/modules/debug/DebugRendererModule.kt index 3e417f071..e4abf5b44 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/DebugRendererModule.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/DebugRendererModule.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.debug import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag @Suppress("unused") object DebugRendererModule: Module( diff --git a/src/main/kotlin/com/lambda/module/modules/debug/FallTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/FallTest.kt index d397b76a5..9ec65d9e8 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/FallTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/FallTest.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.debug import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.info import com.lambda.util.combat.DamageUtils.fallDamage import com.lambda.util.combat.DamageUtils.isFallDeadly diff --git a/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt b/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt index 47ec92134..85af88c45 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/InventoryDebug.kt @@ -22,7 +22,7 @@ import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PacketEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.info import com.lambda.util.DynamicReflectionSerializer.dynamicString import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket diff --git a/src/main/kotlin/com/lambda/module/modules/debug/PropertyPrinter.kt b/src/main/kotlin/com/lambda/module/modules/debug/PropertyPrinter.kt index 6b5a18da1..77a3dabd2 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/PropertyPrinter.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/PropertyPrinter.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.debug import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.FolderRegistry import com.lambda.util.extension.resolveFile import net.minecraft.block.Block diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt index 1a0dc8dc7..5d5b177f5 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt @@ -21,7 +21,7 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.graphics.util.DynamicAABB.Companion.dynamicBox import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.extension.tickDelta import com.lambda.util.math.setAlpha diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RendererTestModule.kt b/src/main/kotlin/com/lambda/module/modules/debug/RendererTestModule.kt index 0e8692900..23b48c4a1 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/RendererTestModule.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/RendererTestModule.kt @@ -32,7 +32,7 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.graphics.outline.OutlineStyle import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.extension.prevPos import com.lambda.util.extension.tickDelta diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt index 1648c632e..b5d63290b 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/RotationTest.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.player.RotationUtils.lookAt import net.minecraft.util.hit.HitResult diff --git a/src/main/kotlin/com/lambda/module/modules/debug/SettingsTestModule.kt b/src/main/kotlin/com/lambda/module/modules/debug/SettingsTestModule.kt index 2facef200..f3430fc74 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/SettingsTestModule.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/SettingsTestModule.kt @@ -26,7 +26,7 @@ import com.lambda.config.blocks.ScreenTextSettings import com.lambda.config.blocks.WorldLineSettings import com.lambda.config.blocks.WorldTextSettings import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag @Suppress("unused") object SettingsTestModule : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt index faa464526..9c3e8df60 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/SilentSwap.kt @@ -17,14 +17,14 @@ package com.lambda.module.modules.debug -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.info object SilentSwap : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/debug/StateInfo.kt b/src/main/kotlin/com/lambda/module/modules/debug/StateInfo.kt index 1cf5a0a47..1789ca0ca 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/StateInfo.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/StateInfo.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.debug import com.lambda.config.settings.complex.KeybindSetting.Companion.onPress import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.BlockUtils.blockState import com.lambda.util.CommunicationUtils.info import com.lambda.util.KeyCode diff --git a/src/main/kotlin/com/lambda/module/modules/debug/TimerTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/TimerTest.kt index 25073151a..10b6abe2c 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/TimerTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/TimerTest.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.ClientEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.SafeListener.Companion.listenConcurrently import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.info @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt b/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt index a026b7fa7..15e4f463c 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/AutoSpiral.kt @@ -24,7 +24,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.BlockPosIterators import com.lambda.util.extension.isNether import com.lambda.util.player.RotationUtils.lookAt diff --git a/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt b/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt index d0dc18219..9218fe002 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/AutoWalk.kt @@ -25,7 +25,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.breaking.BreakManager import com.lambda.interaction.manager.managers.interacting.InteractManager import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.math.MathUtils.toDouble import com.lambda.util.player.MovementUtils.roundedForward import com.lambda.util.player.MovementUtils.roundedStrafing diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt index 281766a82..95abb3962 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt @@ -28,7 +28,7 @@ import com.lambda.graphics.util.DynamicAABB import com.lambda.gui.components.ClickGuiLayout import com.lambda.module.Module import com.lambda.module.modules.combat.KillAura -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.ClientPacket import com.lambda.util.PacketUtils.handlePacketSilently import com.lambda.util.PacketUtils.sendPacketSilently diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 2298bf1f2..2d20319c9 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.movement import com.lambda.Lambda import com.lambda.Lambda.mc -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editSetting import com.lambda.config.hideAllExcept import com.lambda.config.settings.complex.Bind @@ -36,7 +36,7 @@ import com.lambda.interaction.handler.handlers.GlideHandler import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.warn import com.lambda.util.KeyCode diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt index 444006b51..fe555adea 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt @@ -27,7 +27,7 @@ import com.lambda.graphics.util.DynamicAABB import com.lambda.gui.components.ClickGuiLayout import com.lambda.module.Module import com.lambda.module.modules.combat.KillAura -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.PacketUtils.handlePacketSilently import com.lambda.util.PacketUtils.sendPacketSilently diff --git a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt index 1dab22558..d083c4730 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.movement import com.lambda.config.Tab -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.event.events.TickEvent @@ -26,7 +26,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.modules.movement.BetterFirework.startFirework -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.info import com.lambda.util.SpeedUnit diff --git a/src/main/kotlin/com/lambda/module/modules/movement/EntityControl.kt b/src/main/kotlin/com/lambda/module/modules/movement/EntityControl.kt index 03bff2f1d..240b35840 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/EntityControl.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/EntityControl.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.world.fastEntitySearch import net.minecraft.entity.passive.AbstractHorseEntity import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Jesus.kt b/src/main/kotlin/com/lambda/module/modules/movement/Jesus.kt index 7f024e4bb..059ce26e3 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Jesus.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Jesus.kt @@ -24,7 +24,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.NamedEnum import com.lambda.util.extension.isElytraFlying import com.lambda.util.math.MathUtils.toInt diff --git a/src/main/kotlin/com/lambda/module/modules/movement/NoFall.kt b/src/main/kotlin/com/lambda/module/modules/movement/NoFall.kt index 5275eb08a..82b2f4bea 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/NoFall.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/NoFall.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.movement import com.lambda.event.events.MovementEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.PacketUtils.sendPacket import com.lambda.util.math.component1 import com.lambda.util.math.component2 diff --git a/src/main/kotlin/com/lambda/module/modules/movement/NoJumpCooldown.kt b/src/main/kotlin/com/lambda/module/modules/movement/NoJumpCooldown.kt index 1746e1e95..4e0ddef0d 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/NoJumpCooldown.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/NoJumpCooldown.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.movement import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object NoJumpCooldown : Module( name = "NoJumpCooldown", diff --git a/src/main/kotlin/com/lambda/module/modules/movement/SafeWalk.kt b/src/main/kotlin/com/lambda/module/modules/movement/SafeWalk.kt index e34f6db0f..87dad538c 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/SafeWalk.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/SafeWalk.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.movement import com.lambda.event.events.MovementEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.player.MovementUtils.motionX import com.lambda.util.player.MovementUtils.motionZ import com.lambda.util.player.MovementUtils.sneaking diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt index 821757d4e..cd173de2b 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Speed.kt @@ -17,8 +17,8 @@ package com.lambda.module.modules.movement -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.automation.setDefaultAutomationConfig +import com.lambda.config.entries.onValueChange import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.context.SafeContext @@ -28,7 +28,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.NamedEnum import com.lambda.util.extension.contains import com.lambda.util.extension.isElytraFlying diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Sprint.kt b/src/main/kotlin/com/lambda/module/modules/movement/Sprint.kt index d31ac27cc..7dfe55128 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Sprint.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Sprint.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.movement import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object Sprint : Module( name = "Sprint", diff --git a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt index 71b8159dd..5c92c6a66 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt @@ -29,7 +29,7 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.module.Module import com.lambda.module.modules.combat.KillAura -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import net.minecraft.entity.effect.StatusEffects import net.minecraft.util.math.Vec3d import java.awt.Color diff --git a/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt b/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt index 98cf8c9fa..8cf57f44b 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt @@ -24,7 +24,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module import com.lambda.module.modules.combat.KillAura -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runConcurrent import com.lambda.util.CommunicationUtils.info import com.lambda.util.PacketUtils.handlePacketSilently diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Timer.kt b/src/main/kotlin/com/lambda/module/modules/movement/Timer.kt index 359f78bde..2765c5fbe 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Timer.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Timer.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.movement import com.lambda.event.events.ClientEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag @Suppress("unused") object Timer : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Velocity.kt b/src/main/kotlin/com/lambda/module/modules/movement/Velocity.kt index cd2470c54..76e27baa0 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Velocity.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Velocity.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.movement import com.lambda.event.events.PacketEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import net.minecraft.network.packet.s2c.play.EntityVelocityUpdateS2CPacket object Velocity : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt index a55f96e3e..ea2740859 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt @@ -18,9 +18,9 @@ package com.lambda.module.modules.movement.elytrafly import com.lambda.config.Tab -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editSetting -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.forEachSetting import com.lambda.config.hideAllExcept import com.lambda.config.withEdits @@ -34,7 +34,7 @@ import com.lambda.module.Module import com.lambda.module.modules.movement.elytrafly.modes.BounceElytraFly import com.lambda.module.modules.movement.elytrafly.modes.GeneralElytraFly import com.lambda.module.modules.movement.elytrafly.modes.GrimControlElytraFly -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.NamedEnum import com.lambda.util.Timer diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt index c2f816622..f21fef99c 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt @@ -25,7 +25,9 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.containers.ArmorContainer +import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION +import com.lambda.interaction.handler.handlers.findContainer import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest @@ -85,11 +87,12 @@ abstract class ElytraFlyMode( } } - val elytraSlot = findElytra() ?: run { - logError("Fake Fly requires an elytra in your inventory, preferably in your hotbar.") - ElytraFly.disable() - return false - } + val elytraSlot = findElytra() + ?: run { + logError("Fake Fly requires an elytra in your inventory, preferably in your hotbar") + ElytraFly.disable() + return false + } val elytraInHotbar = elytraSlot.index in 0..8 val chestSlot = ArmorContainer.slots.getOrNull(1) ?: return false @@ -111,16 +114,21 @@ abstract class ElytraFlyMode( } } - val inventoryRequest = inventoryRequest { - swapChest() - action { startFly() } - swapChest() - }.submit(false) + val inventoryRequest = + inventoryRequest { + swapChest() + action { startFly() } + swapChest() + }.submit(false) return inventoryRequest.done } - fun findElytra(): Slot? = ELYTRA_SELECTION.filter(HotbarAndInventoryContainer.slots).minByOrNull { it.index } + fun findElytra(): Slot? = + findContainer( + ELYTRA_SELECTION, + ContainerSelection.HOTBAR_AND_INVENTORY + )?.findSlot(ELYTRA_SELECTION) protected fun SafeContext.startFly() { player.setFlag(Entity.GLIDING_FLAG_INDEX, true) diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt index ab6867227..152671136 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt @@ -30,7 +30,7 @@ import com.lambda.util.CommunicationUtils.logError import com.lambda.util.SpeedUnit import com.lambda.util.math.dist import com.lambda.util.math.distSq -import com.lambda.util.math.flooredBlockPos +import com.lambda.util.math.blockPos import com.lambda.util.math.isLoaded import com.lambda.util.world.raycast.InteractionMask import com.lambda.util.world.raycast.RayCastUtils.blockResult @@ -90,7 +90,7 @@ abstract class ObstaclePassingMode( passingToPos?.let { passingTo -> if (passingTo distSq startPos < playerPos distSq startPos) { - val atClosestPointBlockPos = closestLinePoint.flooredBlockPos == player.blockPos + val atClosestPointBlockPos = closestLinePoint.blockPos == player.blockPos if (!atClosestPointBlockPos) pathToValidPoint(closestLinePoint, snappedDir, false) else { BaritoneHandler.cancel() @@ -172,7 +172,7 @@ abstract class ObstaclePassingMode( private fun passTo(pos: Vec3d) { passingToPos = pos - BaritoneHandler.setGoalAndPath(GoalGetToBlock(pos.flooredBlockPos)) + BaritoneHandler.setGoalAndPath(GoalGetToBlock(pos.blockPos)) } protected fun Vec3d.findClosestPointOnLine(snappedDirection: Vec3d): Vec3d { @@ -185,7 +185,7 @@ abstract class ObstaclePassingMode( private fun Vec3d.isObstructed(direction: Vec3d) = if (!isLoaded) false else { - flooredBlockPos.down().let { downPos -> + blockPos.down().let { downPos -> !safeContext.blockState(downPos).isSolidBlock(safeContext.world, downPos) } || if (add(0.0, passerConfig.minObstacleHeight, 0.0).rayCastObstructed(direction)) true diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt index f47f1327f..942f1442c 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/modes/BounceElytraFly.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.movement.elytrafly.modes import com.lambda.config.Config import com.lambda.config.Group -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.context.SafeContext import com.lambda.event.events.MovementEvent import com.lambda.event.events.PacketEvent diff --git a/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt b/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt index c6774f7a2..c150e5484 100644 --- a/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt +++ b/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt @@ -22,7 +22,7 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runConcurrent import com.lambda.threading.runGameScheduled import com.lambda.threading.runSafe diff --git a/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt b/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt index f1b0aa7c2..a62fd1f71 100644 --- a/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt +++ b/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt @@ -17,11 +17,11 @@ package com.lambda.module.modules.network -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.event.events.PacketEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.info import com.lambda.util.ReflectionUtils.className import com.lambda.util.collections.LimitedDecayQueue diff --git a/src/main/kotlin/com/lambda/module/modules/network/PacketLogger.kt b/src/main/kotlin/com/lambda/module/modules/network/PacketLogger.kt index efcf05299..3660e73d5 100644 --- a/src/main/kotlin/com/lambda/module/modules/network/PacketLogger.kt +++ b/src/main/kotlin/com/lambda/module/modules/network/PacketLogger.kt @@ -24,7 +24,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.UnsafeListener.Companion.listenConcurrentlyUnsafe import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runIO import com.lambda.util.CommunicationUtils import com.lambda.util.CommunicationUtils.info diff --git a/src/main/kotlin/com/lambda/module/modules/network/Rubberband.kt b/src/main/kotlin/com/lambda/module/modules/network/Rubberband.kt index 45fb7f1b7..148fb311c 100644 --- a/src/main/kotlin/com/lambda/module/modules/network/Rubberband.kt +++ b/src/main/kotlin/com/lambda/module/modules/network/Rubberband.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.PlayerPacketEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.warn import com.lambda.util.collections.LimitedOrderedSet import com.lambda.util.math.dist diff --git a/src/main/kotlin/com/lambda/module/modules/network/ServerSpoof.kt b/src/main/kotlin/com/lambda/module/modules/network/ServerSpoof.kt index 39dbcfdd1..d034bca9c 100644 --- a/src/main/kotlin/com/lambda/module/modules/network/ServerSpoof.kt +++ b/src/main/kotlin/com/lambda/module/modules/network/ServerSpoof.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.network import com.lambda.event.events.PacketEvent import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.info import com.lambda.util.text.ClickEvents import com.lambda.util.text.buildText diff --git a/src/main/kotlin/com/lambda/module/modules/player/AntiAFK.kt b/src/main/kotlin/com/lambda/module/modules/player/AntiAFK.kt index 25f485e17..4091c92b2 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AntiAFK.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AntiAFK.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.player import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import net.minecraft.util.Hand @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt index 645239f00..5fd9b717e 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AntiAim.kt @@ -17,14 +17,14 @@ package com.lambda.module.modules.player -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.math.distSq import net.minecraft.entity.Entity import net.minecraft.entity.player.PlayerEntity diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt index 6d2997dca..1bb5e18e2 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt @@ -24,7 +24,7 @@ import com.lambda.config.withEdits import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.eat diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt index 2bde07f67..aeead9b02 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt @@ -26,7 +26,7 @@ import com.lambda.interaction.handler.handlers.GlideHandler.swapped import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module import com.lambda.module.modules.combat.AutoArmor -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.warn import com.lambda.util.player.PlayerUtils.canGlideWithChestPiece import net.minecraft.screen.slot.Slot diff --git a/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt b/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt index 402260cd5..a1adaea38 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ClickFriend.kt @@ -25,7 +25,7 @@ import com.lambda.interaction.handler.handlers.FriendHandler.befriend import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.interaction.handler.handlers.FriendHandler.unfriend import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.CommunicationUtils.info import com.lambda.util.InputUtils.isSatisfied import com.lambda.util.world.raycast.RayCastUtils.entityResult diff --git a/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt b/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt index 20024f5cb..73722103a 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt @@ -26,7 +26,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.math.distSq import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.mob.EndermanEntity diff --git a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index b0270222a..20742f245 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -29,7 +29,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.manager.managers.breaking.breakRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafeAutomated import java.util.concurrent.ConcurrentLinkedQueue diff --git a/src/main/kotlin/com/lambda/module/modules/player/Interact.kt b/src/main/kotlin/com/lambda/module/modules/player/Interact.kt index 48fec9a24..6ae205a89 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Interact.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Interact.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.player import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object Interact : Module( name = "Interact", diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt index b65300f3b..59f5d317c 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryMove.kt @@ -25,7 +25,7 @@ import com.lambda.gui.LambdaScreen import com.lambda.interaction.manager.managers.rotating.RotationMode import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.InputUtils import com.lambda.util.InputUtils.isKeyPressed import com.lambda.util.math.MathUtils.toFloatSign diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt index 59d0909c7..3ce04fa89 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryResync.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.TickTimer @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index cb82dbc01..ae88a5bfd 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -28,7 +28,7 @@ import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.interaction.handler.handlers.ContainerHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.wrappers.then diff --git a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt index 5f254bce7..db71f04c9 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt @@ -29,7 +29,7 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.interaction.manager.managers.rotating.RotationMode import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import net.minecraft.util.math.Vec3d import java.awt.Color diff --git a/src/main/kotlin/com/lambda/module/modules/player/NoForceRotate.kt b/src/main/kotlin/com/lambda/module/modules/player/NoForceRotate.kt index 7ca7798fb..9ef7a1953 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/NoForceRotate.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/NoForceRotate.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.player import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag @Suppress("unused") object NoForceRotate : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 779ecf750..c56cdcd2b 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -39,7 +39,7 @@ import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockState diff --git a/src/main/kotlin/com/lambda/module/modules/player/PortalGui.kt b/src/main/kotlin/com/lambda/module/modules/player/PortalGui.kt index dea4ec2e1..3b7022704 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PortalGui.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PortalGui.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.player import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object PortalGui : Module( name = "PortalGui", diff --git a/src/main/kotlin/com/lambda/module/modules/player/Reach.kt b/src/main/kotlin/com/lambda/module/modules/player/Reach.kt index 13855a2e6..5a6e38b84 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Reach.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Reach.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.player import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object Reach : Module( name = "Reach", diff --git a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt index 9ebf59a3b..50bc048f0 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt @@ -40,7 +40,7 @@ import com.lambda.interaction.manager.managers.rotating.RotationMode import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module import com.lambda.module.modules.player.Replay.InputAction.Companion.toAction -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.sound.SoundHandler.playSound import com.lambda.util.CommunicationUtils.info import com.lambda.util.CommunicationUtils.logError diff --git a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt index fb6148691..b7a5ca5af 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt @@ -26,7 +26,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.RotationMode import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import kotlin.math.roundToInt @Suppress("unused") diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index fb411189d..b1e435d49 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -28,7 +28,7 @@ import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.item.ItemStackUtils.slotId import net.minecraft.item.ItemStack import net.minecraft.item.Items diff --git a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt index 77de50df6..7f3c5ccc7 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt @@ -27,7 +27,7 @@ import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.EnchantmentUtils.forEachEnchantment import com.lambda.util.EnchantmentUtils.getEnchantment import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/module/modules/render/BlockOutline.kt b/src/main/kotlin/com/lambda/module/modules/render/BlockOutline.kt index 81eae6976..17d7a2dc3 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/BlockOutline.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/BlockOutline.kt @@ -27,7 +27,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.extension.tickDelta diff --git a/src/main/kotlin/com/lambda/module/modules/render/Bobbing.kt b/src/main/kotlin/com/lambda/module/modules/render/Bobbing.kt index d3d9303d5..f255e0c81 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Bobbing.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Bobbing.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.render import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object Bobbing : Module( name = "Bobbing", diff --git a/src/main/kotlin/com/lambda/module/modules/render/CameraTweaks.kt b/src/main/kotlin/com/lambda/module/modules/render/CameraTweaks.kt index 21c383419..0647ea3b1 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/CameraTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/CameraTweaks.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.render import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag object CameraTweaks : Module( name = "CameraTweaks", diff --git a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt index 66634e981..bd3e6360e 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt @@ -23,7 +23,7 @@ import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.config.settings.complex.Bind import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.InputUtils.isSatisfied import com.lambda.util.KeyCode diff --git a/src/main/kotlin/com/lambda/module/modules/render/Esp.kt b/src/main/kotlin/com/lambda/module/modules/render/Esp.kt index 1639b59ee..a2cc59eb9 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Esp.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Esp.kt @@ -31,7 +31,7 @@ import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.graphics.util.DynamicAABB.Companion.interpolatedBox import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.NamedEnum import com.lambda.util.math.setAlpha diff --git a/src/main/kotlin/com/lambda/module/modules/render/ExtraTab.kt b/src/main/kotlin/com/lambda/module/modules/render/ExtraTab.kt index d70c37a5a..fd561bcd2 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ExtraTab.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ExtraTab.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.render import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import java.awt.Color object ExtraTab : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt b/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt index 5541edce9..486efbd56 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/FreeLook.kt @@ -23,7 +23,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.extension.rotation import net.minecraft.client.option.Perspective diff --git a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt index e4881965c..3ec2aae6c 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt @@ -35,7 +35,7 @@ import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.RotationMode import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.Describable import com.lambda.util.NamedEnum diff --git a/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt b/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt index 09e15863c..9d59f795a 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt @@ -22,7 +22,7 @@ import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listenOnce import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import net.minecraft.entity.effect.StatusEffectInstance import net.minecraft.entity.effect.StatusEffects diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index eb590e40b..011ecaebf 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -19,7 +19,6 @@ package com.lambda.module.modules.render import com.lambda.config.Group import com.lambda.config.blocks.WorldLineSettings -import com.lambda.config.entries.Setting.Companion.onValueChange import com.lambda.config.forEachSetting import com.lambda.config.hide import com.lambda.config.withEdits @@ -29,10 +28,10 @@ import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.mc.renderer.ChunkedRenderer.Companion.chunkedRenderer import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState -import com.lambda.util.math.flooredBlockPos +import com.lambda.util.math.blockPos import com.lambda.util.math.setAlpha import com.lambda.util.math.vec3d import com.lambda.util.world.toBlockPos @@ -92,7 +91,7 @@ object LightLevels : Module( runSafe { if (areaMode.player) buildPositions(positions, player.blockPos) - if (areaMode.camera) buildPositions(positions, mc.gameRenderer.camera.pos.flooredBlockPos) + if (areaMode.camera) buildPositions(positions, mc.gameRenderer.camera.pos.blockPos) positions.forEach { pos -> buildRender(pos, dashStyle) } diff --git a/src/main/kotlin/com/lambda/module/modules/render/MapPreview.kt b/src/main/kotlin/com/lambda/module/modules/render/MapPreview.kt index fedeea4cd..270f73c83 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/MapPreview.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/MapPreview.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import net.minecraft.client.font.TextRenderer import net.minecraft.client.gl.RenderPipelines import net.minecraft.client.gui.DrawContext diff --git a/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt b/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt index 7cafda47f..176106c69 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Nametags.kt @@ -32,7 +32,7 @@ import com.lambda.graphics.text.FontHandler import com.lambda.graphics.util.DynamicAABB.Companion.interpolatedBox import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.extension.fullHealth import com.lambda.util.extension.maxFullHealth diff --git a/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt b/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt index 1287a2fcb..2ba504765 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt @@ -22,7 +22,7 @@ import com.lambda.config.blocks.EntitySelectionSettings import com.lambda.config.editTypedSettings import com.lambda.config.withEdits import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.EntityUtils.createNameMap import com.lambda.util.ReflectionUtils.scanResult import net.minecraft.block.entity.BlockEntity diff --git a/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt b/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt index 478cb318b..6e844c124 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt @@ -28,7 +28,7 @@ import com.lambda.graphics.mc.RenderBuilder import com.lambda.graphics.mc.renderer.ChunkedRenderer.Companion.chunkedRenderer import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.math.setAlpha diff --git a/src/main/kotlin/com/lambda/module/modules/render/Search.kt b/src/main/kotlin/com/lambda/module/modules/render/Search.kt index 15752cf49..7d941f1f6 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Search.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Search.kt @@ -36,7 +36,7 @@ import com.lambda.graphics.util.DirectionMask import com.lambda.graphics.util.DirectionMask.buildSideMesh import com.lambda.graphics.util.DynamicAABB.Companion.interpolatedBox import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.EntityUtils.decorationEntityMap diff --git a/src/main/kotlin/com/lambda/module/modules/render/Time.kt b/src/main/kotlin/com/lambda/module/modules/render/Time.kt index d5e384c68..986b7876d 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Time.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Time.kt @@ -21,7 +21,7 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket object Time : Module( diff --git a/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt b/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt index 792102e79..f2033ad5c 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Tracers.kt @@ -28,7 +28,7 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.graphics.mc.renderer.RendererUtils.worldToScreenNormalized import com.lambda.interaction.handler.handlers.FriendHandler.isFriend import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.extension.prevPos import com.lambda.util.extension.tickDelta diff --git a/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt b/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt index ff2acce3d..82239bbfa 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt @@ -24,7 +24,7 @@ import com.lambda.event.events.ButtonEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import net.minecraft.client.network.AbstractClientPlayerEntity import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack diff --git a/src/main/kotlin/com/lambda/module/modules/render/Weather.kt b/src/main/kotlin/com/lambda/module/modules/render/Weather.kt index 13a6b5239..5c218aaf1 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Weather.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Weather.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.render import com.lambda.config.Tab import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import net.minecraft.world.World diff --git a/src/main/kotlin/com/lambda/module/modules/render/WorldColors.kt b/src/main/kotlin/com/lambda/module/modules/render/WorldColors.kt index 227d0e209..b8307141e 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/WorldColors.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/WorldColors.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.render import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.math.vec3d import net.minecraft.util.math.Vec3d import java.awt.Color diff --git a/src/main/kotlin/com/lambda/module/modules/render/XRay.kt b/src/main/kotlin/com/lambda/module/modules/render/XRay.kt index 6e9d1e2a6..4b58bae51 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/XRay.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/XRay.kt @@ -23,7 +23,7 @@ import com.lambda.config.settings.collections.onDeselect import com.lambda.config.settings.collections.onSelect import com.lambda.context.SafeContext import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.BlockUtils import net.minecraft.block.Blocks import net.minecraft.fluid.Fluids diff --git a/src/main/kotlin/com/lambda/module/modules/render/Zoom.kt b/src/main/kotlin/com/lambda/module/modules/render/Zoom.kt index d991feb93..d654a69c5 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Zoom.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Zoom.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.render import com.lambda.event.events.ButtonEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.NamedEnum import java.lang.Math.clamp diff --git a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt index b29ce5000..952a1bda5 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt @@ -36,7 +36,7 @@ import com.lambda.interaction.manager.managers.interacting.InteractRequest import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafeAutomated import com.lambda.util.InputUtils.isSatisfied import com.lambda.util.KeyCode diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index e9154a9f8..a6665179c 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -45,7 +45,7 @@ import com.lambda.module.modules.world.AutoPortal.PosHandler.currAnchorPos import com.lambda.module.modules.world.AutoPortal.PosHandler.obiPositions import com.lambda.module.modules.world.AutoPortal.PosHandler.portalPositions import com.lambda.module.modules.world.AutoPortal.PosHandler.prevAnchorPos -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoSign.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoSign.kt index d2f1e502b..068c898ad 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoSign.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoSign.kt @@ -21,7 +21,7 @@ import com.ibm.icu.util.Calendar import com.lambda.event.events.GuiEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runConcurrent import com.lambda.threading.runSafeGameScheduled import com.lambda.util.PacketUtils.sendPacket diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt index 82751cce5..78352b15c 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt @@ -32,7 +32,7 @@ import com.lambda.interaction.construction.blueprint.toBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.sound.SoundHandler.playSound import com.lambda.task.Task import com.lambda.task.start diff --git a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt index b3c89f8f1..7ca52d72b 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt @@ -25,7 +25,7 @@ import com.lambda.interaction.construction.blueprint.PropagatingBlueprint.Compan import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build diff --git a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt index 7ced3f6a3..5f9b6e324 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt @@ -20,7 +20,7 @@ package com.lambda.module.modules.world import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.util.FileUtils.locationBoundDirectory import com.lambda.util.FolderRegistry import com.lambda.util.StringUtils.hashString diff --git a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt index 6f79fafb3..de229a0ff 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt @@ -25,7 +25,7 @@ import com.lambda.context.SafeContext import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build diff --git a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt index 6b8639976..016ed4a3a 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt @@ -33,7 +33,7 @@ import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.result.results.InteractResult import com.lambda.interaction.construction.verify.TargetState import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index b0e8f5c6d..85f99e94f 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -34,7 +34,7 @@ import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockPos import com.lambda.util.BlockUtils.blockState diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index 804f3648d..06f603307 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -50,7 +50,7 @@ import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.dist import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.tag.ModuleTag +import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt index 71c0fb03b..6602dc3f6 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -67,6 +67,6 @@ class AcquirePlacedBlockTask @Ta5kBuilder internal constructor( override fun SafeContext.onStart() { findBlock(block, searchRadius) .softFail() - .execute(this@AcquirePlacedBlockTask) + .start() } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt index c165f9000..5ae1d61ba 100644 --- a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt @@ -48,7 +48,7 @@ class CollectDropsTask @Ta5kBuilder internal constructor( ) : Task(), Automated by automated { override val name get() = "Collecting ${drops.size} item drop(s)" - override fun SafeContext.onStart() { + init { listen { runSafeAutomated { val target = diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index 275a02318..fc674267b 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -26,7 +26,8 @@ import com.lambda.interaction.container.ExternalContainer import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.container.selection.StackSelection -import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.mutate +import com.lambda.interaction.handler.handlers.findContainers import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.wrappers.taskOrNull @@ -40,51 +41,75 @@ context(automated: Automated) fun transfer( selection: StackSelection, fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, - toSelection: ContainerSelection -) = ContainerTransferTask(selection, fromSelection, toSelection, automated) + toSelection: ContainerSelection, + toStack: StackSelection = StackSelection.EVERYTHING +) = ContainerTransferTask(selection, fromSelection, toSelection, toStack, automated) @Ta5kBuilder @JvmName("transferExt") context(automated: Automated) -fun StackSelection.transferTo( +fun StackSelection.transfer( fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, - toSelection: ContainerSelection -) = transfer(this, fromSelection, toSelection) + toSelection: ContainerSelection, + toStack: StackSelection = StackSelection.EVERYTHING +) = transfer(this, fromSelection, toSelection, toStack) class ContainerTransferTask @Ta5kBuilder internal constructor( private val selection: StackSelection, private val fromSelection: ContainerSelection, private val toSelection: ContainerSelection, + private val toStack: StackSelection, automated: Automated ) : Task(), Automated by automated { override val name = "Transferring $selection from $fromSelection to $toSelection" override fun SafeContext.onStart() { - val fromContainer = findContainer(containerSelection) - ?: run { - failure(IllegalStateException("Could not find container to pull $selection from")) + val singleSelection = selection.mutate(count = if (selection.count == 0) 0 else 1) + + val fromContainers = findContainers(singleSelection, fromSelection).toList() + val toContainers = findContainers(toStack, toSelection) + .filter { toStack !== StackSelection.EVERYTHING || it.spaceLeft(singleSelection) > 0 } + .toList() + + if (fromContainers.isEmpty()) { + failure(IllegalStateException("Could not find any container to pull $selection from")) + return + } + if (toContainers.isEmpty()) { + failure(IllegalStateException("Could not find any container with space to push $selection to")) + return + } + + if (selection.count > 0) { + val totalAvailable = fromContainers.sumOf { it.count(singleSelection) } + if (totalAvailable < selection.count) { + failure(IllegalStateException("Not enough items across all containers to pull $selection")) return } + } + + val fromContainer = fromContainers.first() + val toContainer = toContainers.first() + when { - fromContainer.isAccessed && toContainer.isAccessed -> - TransferTask() + fromContainers.all { it.isAccessed } && toContainers.all { it.isAccessed } -> + TransferTask(fromContainers, toContainers) .onSuccess { success(it) } fromContainer !is ExternalContainer -> - openTransferClose(toContainer, toContainer, containerSelection) + openTransferClose(toContainer, fromSelection, toSelection) toContainer !is ExternalContainer -> - openTransferClose(fromContainer, toContainer, containerSelection) + openTransferClose(fromContainer, fromSelection, toSelection) - else -> { + else -> taskOrNull { fromContainer.access() } .then { fromCtx -> - transfer(selection, toContainer, ContainerSelection.HOTBAR_AND_INVENTORY) + transfer(selection, fromSelection, ContainerSelection.HOTBAR_AND_INVENTORY) .thenOrNull { fromCtx?.close() } } .thenOrNull { toContainer.access() } - .then { toCtx -> transferAndClose(toCtx, toContainer, ContainerSelection.HOTBAR_AND_INVENTORY) } - } + .then { toCtx -> transferAndClose(toCtx, ContainerSelection.HOTBAR_AND_INVENTORY, toSelection) } }?.start() } @@ -96,11 +121,11 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( @Ta5kBuilder private fun openTransferClose( containerToOpen: Container, - to: Container, - containerSelection: ContainerSelection + fromSelection: ContainerSelection, + toSelection: ContainerSelection ) = containerToOpen .access() - ?.then { ctx -> transferAndClose(ctx, to, containerSelection) } + ?.then { ctx -> transferAndClose(ctx, fromSelection, toSelection) } /** * Transfers [selection] from [from] to [to], then closes the container via [ctx]. @@ -117,7 +142,10 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( ?.onSuccess { success(slot) } } - private inner class TransferTask @Ta5kBuilder constructor() : Task() { + private inner class TransferTask @Ta5kBuilder constructor( + private val fromContainers: List, + private val toContainers: List + ) : Task() { override val name = "Transferring" private var transferred = 0 @@ -127,21 +155,39 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( listen { runSafeAutomated { while (selection.count == 0 || transferred < selection.count) { - val (fromSlot, toSlot) = fromContainer.getTransferSlots(selection, toContainer) + val currentSelection = selection.mutate(count = if (selection.count == 0) 0 else selection.count - transferred) + + var fromSlot: Slot? = null + var toSlot: Slot? = null + var fromContainer: Container? = null + var toContainer: Container? = null + + for (fc in fromContainers) { + for (tc in toContainers) { + val slots = fc.findMoveSlots(currentSelection, tc, toStack) + if (slots.first != null && slots.second != null) { + fromSlot = slots.first + toSlot = slots.second + fromContainer = fc + toContainer = tc + break + } + } + if (fromSlot != null) break + } - if (fromSlot == null || toSlot == null) { + if (fromSlot == null || toSlot == null || fromContainer == null || toContainer == null) { lastSlot?.let { slot -> if (selection.count == 0 || transferred >= selection.count) { success(slot) return@listen } } - if (fromSlot == null) checkFail() - else failure("Unable to find a slot to transfer to.") + checkFail() return@listen } - val moveCount = fromSlot.stack.count + val moveCount = minOf(fromSlot.stack.count, if (selection.count == 0) Int.MAX_VALUE else selection.count - transferred) if (!fromContainer.swap(fromSlot, toSlot, toContainer)) { checkFail() return@listen diff --git a/src/main/kotlin/com/lambda/util/FolderRegistry.kt b/src/main/kotlin/com/lambda/util/FolderRegistry.kt index d02d89b6f..7c284a79f 100644 --- a/src/main/kotlin/com/lambda/util/FolderRegistry.kt +++ b/src/main/kotlin/com/lambda/util/FolderRegistry.kt @@ -35,6 +35,7 @@ object FolderRegistry : Loadable { val replay: Path = lambda.resolve("replay") val cache: Path = lambda.resolve("cache") val capes: Path = cache.resolve("capes") + val containers: Path = cache.resolve("containers") val structure: Path = lambda.resolve("structure") val maps: Path = lambda.resolve("maps") val fonts: Path = lambda.resolve("fonts") @@ -42,7 +43,7 @@ object FolderRegistry : Loadable { val File.relativeMCPath: Path get() = minecraft.relativize(toPath()) override fun load(): String { - val folders = listOf(lambda, config, packetLogs, replay, cache, capes, structure, maps, fonts) + val folders = listOf(lambda, config, packetLogs, replay, cache, capes, containers, structure, maps, fonts) val createdFolders = folders.mapNotNull { if (it.notExists()) { it.createDirectories() diff --git a/src/main/kotlin/com/lambda/util/combat/DamageUtils.kt b/src/main/kotlin/com/lambda/util/combat/DamageUtils.kt index d6d890a09..f1b3abba8 100644 --- a/src/main/kotlin/com/lambda/util/combat/DamageUtils.kt +++ b/src/main/kotlin/com/lambda/util/combat/DamageUtils.kt @@ -20,7 +20,7 @@ package com.lambda.util.combat import com.lambda.context.SafeContext import com.lambda.util.BlockUtils.blockState import com.lambda.util.extension.fullHealth -import com.lambda.util.math.flooredBlockPos +import com.lambda.util.math.blockPos import com.lambda.util.math.minus import com.lambda.util.player.prediction.buildPlayerPrediction import net.minecraft.block.BedBlock @@ -76,7 +76,7 @@ object DamageUtils { val predictedPos = prediction.position val fallDistance = player.y - predictedPos.y + player.fallDistance - val state = blockState(predictedPos.flooredBlockPos) + val state = blockState(predictedPos.blockPos) val block = state.block val distance = fallDistance + diff --git a/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt b/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt index 867acc01d..3a06ff7a4 100644 --- a/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt +++ b/src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt @@ -76,8 +76,8 @@ object ItemStackUtils { val ItemStack.hasSpace get() = spaceLeft > 0 val List.spaceLeft get() = sumOf { it.spaceLeft } val List.spaceLeft @JvmName("slotSpaceLeft") get() = sumOf { it.stack.spaceLeft } - val List.empty: Int get() = count { it.isEmpty } - val List.empty: Int @JvmName("slotEmpty") get() = count { it.stack.isEmpty } + val List.emptySpace: Int get() = count { it.isEmpty } + val List.emptySpace: Int @JvmName("emptySlotSpace") get() = count { it.stack.isEmpty } val List.count: Int get() = if (isEmpty()) -1 else sumOf { it.count } val List.count: Int @JvmName("slotCount") get() = if (isEmpty()) -1 else sumOf { it.stack.count } val List.copy: List get() = map { it.copy() } diff --git a/src/main/kotlin/com/lambda/util/math/Vectors.kt b/src/main/kotlin/com/lambda/util/math/Vectors.kt index b43767cae..baaa02434 100644 --- a/src/main/kotlin/com/lambda/util/math/Vectors.kt +++ b/src/main/kotlin/com/lambda/util/math/Vectors.kt @@ -107,7 +107,7 @@ fun Vec3d.approximate(other: Vec3d, precision: Double = 2.0E-4): Boolean = val Vec3d.roundedBlockPos: BlockPos get() = BlockPos(x.roundToInt(), y.roundToInt(), z.roundToInt()) -val Vec3d.flooredBlockPos: BlockPos +val Vec3d.blockPos: BlockPos get() = BlockPos(x.floorToInt(), y.floorToInt(), z.floorToInt()) val Entity.netherCoord: Vec3d get() = pos.multiply(0.125, 1.0, 0.125) @@ -205,7 +205,7 @@ infix fun Entity.distSq(other: Vec3i): Int = blockPos distSq other infix fun Entity.distSq(other: Entity): Double = squaredDistanceTo(other) context(safeContext: SafeContext) -val Vec3d.isLoaded get() = flooredBlockPos.isLoaded +val Vec3d.isLoaded get() = blockPos.isLoaded val UP = Vec3d(0.0, 1.0, 0.0) val DOWN = Vec3d(0.0, -1.0, 0.0) diff --git a/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt b/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt index a4a6e3bc6..25a93a848 100644 --- a/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt +++ b/src/main/kotlin/com/lambda/util/player/prediction/PredictionEntity.kt @@ -26,7 +26,7 @@ import com.lambda.util.BlockUtils.blockState import com.lambda.util.math.DOWN import com.lambda.util.math.MathUtils.toIntSign import com.lambda.util.math.MathUtils.toRadian -import com.lambda.util.math.flooredBlockPos +import com.lambda.util.math.blockPos import com.lambda.util.math.plus import com.lambda.util.math.times import com.lambda.util.player.MovementUtils.forward @@ -85,7 +85,7 @@ class PredictionEntity(val player: ClientPlayerEntity) { // Other shit private var jumpingCooldown = player.jumpingCooldown - private var velocityAffectingPos = player.supportingBlockPos.orElse((position + DOWN * 0.001).flooredBlockPos) + private var velocityAffectingPos = player.supportingBlockPos.orElse((position + DOWN * 0.001).blockPos) private var horizontalCollision = player.horizontalCollision private var verticalCollision = player.verticalCollision @@ -208,7 +208,7 @@ class PredictionEntity(val player: ClientPlayerEntity) { } val velocityMultiplier = run { - val f = blockState(position.flooredBlockPos).block.velocityMultiplier.toDouble() + val f = blockState(position.blockPos).block.velocityMultiplier.toDouble() val g = blockState(velocityAffectingPos).block.velocityMultiplier.toDouble() if (f == 1.0) g else f } @@ -220,7 +220,7 @@ class PredictionEntity(val player: ClientPlayerEntity) { boundingBox = normalized.offset(position) } - velocityAffectingPos = (position + DOWN * 0.001).flooredBlockPos + velocityAffectingPos = (position + DOWN * 0.001).blockPos } /** @see net.minecraft.entity.LivingEntity.jump */ @@ -232,7 +232,7 @@ class PredictionEntity(val player: ClientPlayerEntity) { /** @see net.minecraft.entity.Entity.getJumpVelocityMultiplier */ val jumpHeight = run { - val f = blockState(position.flooredBlockPos).block.jumpVelocityMultiplier.toDouble() + val f = blockState(position.blockPos).block.jumpVelocityMultiplier.toDouble() val g = blockState(velocityAffectingPos).block.jumpVelocityMultiplier.toDouble() if (f == 1.0) g else f } * 0.42 + player.jumpBoostVelocityModifier From 8d0c65ff98c82f2993d8ea77c22e77111e26034c Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Thu, 10 Sep 2026 12:50:52 +0100 Subject: [PATCH 15/18] fix all syntax errors but most things are broken/could be written better --- .../command/commands/TransferCommand.kt | 33 ++- .../com/lambda/config/blocks/EatConfig.kt | 12 +- .../lambda/config/blocks/InventoryConfig.kt | 35 +-- .../lambda/config/blocks/InventorySettings.kt | 2 - .../EnderChestContainerSerializer.kt | 69 ++++++ .../lambda/gui/components/ClickGuiLayout.kt | 4 +- .../simulation/result/results/BreakResult.kt | 4 +- .../construction/simulation/sims/BreakSim.kt | 18 +- .../simulation/sims/InteractSim.kt | 17 +- .../construction/verify/TargetState.kt | 1 - .../lambda/interaction/container/Container.kt | 4 +- .../external/ShulkerBoxContainer.kt | 8 +- .../container/selection/ContainerSelection.kt | 94 +++++--- .../container/selection/StackSelection.kt | 206 +++++++++++++----- .../handler/handlers/ContainerHandler.kt | 121 ++++++---- .../handler/handlers/GlideHandler.kt | 30 +-- .../handlers/breaking/RebreakHandler.kt | 4 +- .../manager/managers/breaking/BreakManager.kt | 6 +- .../kotlin/com/lambda/module/HudModule.kt | 1 - .../lambda/module/modules/combat/AutoTotem.kt | 2 +- .../module/modules/combat/CrystalAura.kt | 11 +- .../lambda/module/modules/combat/KillAura.kt | 4 +- .../module/modules/combat/PlayerTrap.kt | 11 +- .../lambda/module/modules/combat/Surround.kt | 13 +- .../module/modules/movement/BackTrack.kt | 2 +- .../module/modules/movement/BetterFirework.kt | 14 +- .../lambda/module/modules/movement/Blink.kt | 2 +- .../modules/movement/ElytraAltitudeControl.kt | 2 +- .../module/modules/movement/TargetStrafe.kt | 2 +- .../module/modules/movement/TickShift.kt | 2 +- .../modules/movement/elytrafly/ElytraFly.kt | 2 +- .../movement/elytrafly/ElytraFlyMode.kt | 8 +- .../movement/elytrafly/ObstaclePassingMode.kt | 2 +- .../lambda/module/modules/player/AutoEat.kt | 2 +- .../module/modules/player/AutoElytraSwap.kt | 18 +- .../module/modules/player/EndermanLook.kt | 2 +- .../lambda/module/modules/player/FastBreak.kt | 2 +- .../module/modules/player/InventoryTweaks.kt | 20 +- .../lambda/module/modules/player/LineLock.kt | 2 +- .../module/modules/player/PacketMine.kt | 6 +- .../lambda/module/modules/player/Replay.kt | 2 +- .../module/modules/player/RotationLock.kt | 2 +- .../module/modules/player/StackReplenish.kt | 4 +- .../lambda/module/modules/player/ToolSaver.kt | 2 +- .../module/modules/render/ContainerPreview.kt | 2 +- .../com/lambda/module/modules/render/Esp.kt | 2 +- .../lambda/module/modules/render/Freecam.kt | 4 +- .../module/modules/render/Fullbright.kt | 2 +- .../module/modules/render/LightLevels.kt | 1 + .../lambda/module/modules/render/RadiusESP.kt | 2 +- .../lambda/module/modules/render/Search.kt | 2 +- .../lambda/module/modules/render/ViewModel.kt | 2 +- .../com/lambda/module/modules/render/XRay.kt | 2 +- .../lambda/module/modules/world/AirPlace.kt | 2 +- .../lambda/module/modules/world/AutoPortal.kt | 19 +- .../module/modules/world/AutoVillagerCycle.kt | 2 +- .../module/modules/world/HighwayTools.kt | 2 +- .../module/modules/world/MapDownloader.kt | 5 +- .../com/lambda/module/modules/world/Nuker.kt | 4 +- .../lambda/module/modules/world/Printer.kt | 4 +- .../lambda/module/modules/world/Scaffold.kt | 8 +- .../lambda/module/modules/world/StashMover.kt | 52 ++++- .../kotlin/com/lambda/network/CapeHandler.kt | 2 +- .../task/tasks/AcquirePlacedBlockTask.kt | 17 +- .../com/lambda/task/tasks/AcquireStackTask.kt | 10 +- .../com/lambda/task/tasks/CollectDropsTask.kt | 5 +- .../task/tasks/ContainerTransferTask.kt | 61 +++--- .../kotlin/com/lambda/task/tasks/EatTask.kt | 8 +- 68 files changed, 651 insertions(+), 377 deletions(-) create mode 100644 src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index 9bcfb93fa..def4906f1 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -28,10 +28,9 @@ import com.lambda.brigadier.executeWithResult import com.lambda.brigadier.required import com.lambda.command.LambdaCommand import com.lambda.config.automation.AutomationConfig -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.handler.handlers.findContainers -import com.lambda.interaction.handler.handlers.findContainersWithSpace import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.transfer @@ -52,11 +51,16 @@ object TransferCommand : LambdaCommand( required(integer("amount", 1)) { amount -> required(string("from")) { from -> suggests { ctx, builder -> - val selection = selectStack(amount(ctx).value()) { + val selection = stackSelection(amount(ctx).value()) { isItem(stack(ctx).value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val containers = findContainers(selection).toList() + val containers = + findContainers( + containerSelection { + hasStack(selection) + } + ).toList() val indexedContainers = containers.withIndex() suggestMatching( @@ -70,11 +74,16 @@ object TransferCommand : LambdaCommand( required(string("to")) { to -> suggests { ctx, builder -> val selection = - selectStack(amount(ctx).value()) { + stackSelection(amount(ctx).value()) { isItem(stack(ctx).value().item) } AutomationConfig.DEFAULT.runSafeAutomated { - val containers = selection.findContainersWithSpace().toList() + val containers = + findContainers( + containerSelection { + hasSpace(selection) + } + ).toList() val indexedContainers = containers.withIndex() suggestMatching( @@ -88,18 +97,18 @@ object TransferCommand : LambdaCommand( executeWithResult { AutomationConfig.DEFAULT.runSafeAutomated { val fromSelection = - selectContainer { - custom { it.name == from().value().split(".").first().trim() } + containerSelection { + predicate { it.name == from().value().split(".").first().trim() } } val toSelection = - selectContainer { - custom { it.name == to().value().split(".").first().trim() } + containerSelection { + predicate { it.name == to().value().split(".").first().trim() } } lastContainerTransfer = transfer( - selectStack(amount().value()) { + stackSelection(amount().value()) { isItem(stack().value().item) }, fromSelection, diff --git a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt index 721b5470e..d727e4831 100644 --- a/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/EatConfig.kt @@ -20,7 +20,7 @@ package com.lambda.config.blocks import com.lambda.context.Automated import com.lambda.context.AutomatedSafeContext import com.lambda.interaction.container.selection.StackAndSlot -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.threading.runSafe import com.lambda.util.Describable import com.lambda.util.NamedEnum @@ -96,14 +96,14 @@ interface EatConfig { context(c: Automated) fun selector() = - selectStack { + stackSelection { when(this@Reason) { - Hunger -> isOneOfItems(c.eatConfig.nutritiousFood) - Damage -> isOneOfItems(c.eatConfig.regenerationFood) - Fire -> isOneOfItems(c.eatConfig.resistanceFood) + Hunger -> ofAnyItems(c.eatConfig.nutritiousFood) + Damage -> ofAnyItems(c.eatConfig.regenerationFood) + Fire -> ofAnyItems(c.eatConfig.resistanceFood) else -> {} } - if (c.eatConfig.ignoreBadFood) isNoneOfItems(c.eatConfig.badFood) + if (c.eatConfig.ignoreBadFood) noneOfItems(c.eatConfig.badFood) sortedWith(c.eatConfig.selectionPriority.comparator) } } diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 4f0e9c893..6e65ca89d 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -20,8 +20,7 @@ package com.lambda.config.blocks import com.lambda.event.events.TickEvent import com.lambda.interaction.container.Container import com.lambda.interaction.container.selection.ContainerSelection -import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer -import com.lambda.interaction.container.selection.StackSelection +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection import com.lambda.util.Describable import com.lambda.util.NamedEnum import net.minecraft.item.Item @@ -29,42 +28,24 @@ import net.minecraft.item.Item interface InventoryConfig { val tickStageMask: Collection val disposables: Collection - val accessPriority: Priority - val storePriority: Priority val allowedContainers: Collection val containerSelection: ContainerSelection - get() = selectContainer { ofAnyType(*allowedContainers.toTypedArray()) } + get() = containerSelection { ofAnyType(*allowedContainers.toTypedArray()) } val enderChestSearchRadius: Int - enum class Priority( + @Suppress("unused") + enum class ContainerPriority( override val displayName: String, override val description: String ) : NamedEnum, Describable { WithMinItems("With Min Items", "Pick containers with the fewest matching items (or least space) first; useful for topping off or clearing leftovers."), WithMaxItems("With Max Items", "Pick containers with the most matching items (or most space) first; ideal for bulk moves with fewer transfers."); - fun materialComparator(selection: StackSelection) = - when (this) { - WithMaxItems -> compareBy { it.type } - .thenByDescending { it.count(selection) } - .thenBy { it.name } - - WithMinItems -> compareBy { it.type } - .thenBy { it.count(selection) } - .thenBy { it.name } - } - - fun spaceComparator(selection: StackSelection) = - when (this) { - WithMaxItems -> compareBy { it.type } - .thenByDescending { it.spaceLeft(selection) } - .thenBy { it.name } - - WithMinItems -> compareBy { it.type } - .thenBy { it.spaceLeft(selection) } - .thenBy { it.name } - } + fun comparator(countSelector: (Container, T) -> Int) = + compareBy> { it.first.type } + .thenByDescending { countSelector(it.first, it.second) } + .thenBy { it.first.name } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt index 2659c92f1..84f059189 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt @@ -31,8 +31,6 @@ class InventorySettings(override val c: Config) : InventoryConfig, ConfigBlock { override val tickStageMask by c.setting("Inventory Stage Mask", ALL_STAGES.toSet(), description = "The sub-tick timing at which inventory actions are performed", displayClassName = true) override val disposables by c.setting("Disposables", ItemUtils.DEFAULT_DISPOSABLES, description = "Items that will be ignored when checking for a free slot") - override val accessPriority by c.setting("Access Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when retrieving the item from") - override val storePriority by c.setting("Store Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when storing the item to") override val allowedContainers by c.setting("Allowed Containers", ContainerType.entries, description = "What containers are accessible") @Group(ENDER_CHEST_GROUP) override val enderChestSearchRadius by c.setting("Initial Search Radius", 10, 0..20, unit = " blocks", description = "Initial search radius to scan for an already placed ender chest. If one isn't found, one will be placed. If an ender chest isn't found in the inventory, it scans the rest of the loaded area to find an already placed one") diff --git a/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt b/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt new file mode 100644 index 000000000..a62b83044 --- /dev/null +++ b/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +@file:Suppress("unused") + +package com.lambda.config.serializers + +import com.lambda.config.Deserializer +import com.lambda.config.JsonOps +import com.lambda.config.Serializer +import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.containers.external.EnderChestContainer +import net.minecraft.item.ItemStack +import tools.jackson.core.JsonGenerator +import tools.jackson.core.JsonParser +import tools.jackson.databind.DeserializationContext +import tools.jackson.databind.SerializationContext +import tools.jackson.databind.node.ArrayNode +import tools.jackson.databind.node.JsonNodeFactory +import tools.jackson.databind.node.ObjectNode + +object EnderChestContainerSerializer : Serializer(EnderChestContainer::class.java) { + override fun serialize(container: EnderChestContainer, gen: JsonGenerator, ctxt: SerializationContext) { + val root = JsonNodeFactory.instance.objectNode() + root.put("Type", ContainerType.EnderChest.name) + + val stackArray = JsonNodeFactory.instance.arrayNode() + for (stack in container.stacks) { + val encoded = ItemStack.CODEC + .encodeStart(JsonOps.UNCOMPRESSED, stack) + .result() + encoded.ifPresent { stackArray.add(it) } + } + root.set("Stacks", stackArray) + + gen.writeTree(root) + } +} + +object EnderChestContainerDeserializer : Deserializer(EnderChestContainer::class.java) { + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): EnderChestContainer { + val root = p.readValueAsTree() + val stackArray = root.get("Stacks") as? ArrayNode + val stacks = stackArray?.mapNotNull { element -> + ItemStack.CODEC + .parse(JsonOps.UNCOMPRESSED, element) + .result() + .orElse(null) + } ?: emptyList() + + EnderChestContainer.update(stacks) + EnderChestContainer.scanStacksForNestedContainers() + return EnderChestContainer + } +} diff --git a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt index f8965fbe4..9bc94da3f 100644 --- a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt +++ b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt @@ -47,10 +47,10 @@ import com.lambda.imgui.flag.ImGuiCond import com.lambda.imgui.flag.ImGuiHoveredFlags import com.lambda.imgui.flag.ImGuiWindowFlags import com.lambda.module.ModuleRegistry -import com.lambda.module.modules.client.Client -import com.lambda.module.modules.combat.autodisconnect.AutoDisconnectScreen import com.lambda.module.ModuleTag import com.lambda.module.ModuleTag.Companion.shownTags +import com.lambda.module.modules.client.Client +import com.lambda.module.modules.combat.autodisconnect.AutoDisconnectScreen import com.lambda.sound.LambdaSound import com.lambda.sound.SoundHandler.play import com.lambda.util.Describable diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt index e5bf44af2..87bc4f532 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/result/results/BreakResult.kt @@ -32,7 +32,7 @@ import com.lambda.interaction.construction.simulation.result.Navigable import com.lambda.interaction.construction.simulation.result.Rank import com.lambda.interaction.construction.simulation.result.Resolvable import com.lambda.interaction.container.containers.HotbarContainer -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.BaritoneHandler import com.lambda.task.tasks.transfer @@ -119,7 +119,7 @@ sealed class BreakResult : BuildResult() { context(_: Automated) override fun resolve() = - selectStack { inverted { isItem(badItem) } } + stackSelection { notItem(badItem) } .transfer(toSelection = HotbarContainer.select()) override fun compareResult(other: ComparableResult) = diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt index 6f60974e2..f3876b581 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/BreakSim.kt @@ -29,11 +29,11 @@ import com.lambda.interaction.construction.simulation.result.results.GenericResu import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.ContainerType -import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection import com.lambda.interaction.container.selection.StackAndSlot import com.lambda.interaction.container.selection.StackSelection -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.handler.handlers.findContainers +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection +import com.lambda.interaction.handler.handlers.findStacks import com.lambda.interaction.manager.managers.hotbar.HotbarManager import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest @@ -138,11 +138,11 @@ class BreakSim internal constructor(simInfo: SimInfo) } private fun AutomatedSafeContext.getSwapStack(): Pair? { - val stackSelection = selectStack { + val stackSelection = stackSelection { if (breakConfig.efficientOnly) isEfficientForBreaking(state) if (breakConfig.suitableToolsOnly) isSuitableForBreaking(state) - if (breakConfig.forceSilkTouch) hasEnchantment(Enchantments.SILK_TOUCH) - if (breakConfig.forceFortunePickaxe) hasEnchantment(Enchantments.FORTUNE) + if (breakConfig.forceSilkTouch) withEnchantment(Enchantments.SILK_TOUCH) + if (breakConfig.forceFortunePickaxe) withEnchantment(Enchantments.FORTUNE) sortedWith { compareByDescending> { it.stack.canBreak(CachedBlockPosition(world, pos, false)) @@ -154,13 +154,11 @@ class BreakSim internal constructor(simInfo: SimInfo) } } - val containerSelection = selectContainer { + val containerSelection = containerSelection { ofAnyType(ContainerType.Hotbar) } - val hotbarCandidates = findContainers(stackSelection, containerSelection) - .flatMap { stackSelection.filter(it.stacks) } - .toList() + val hotbarCandidates = findStacks(stackSelection, containerSelection).toList() if (hotbarCandidates.isEmpty()) { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt index 8f8ec8872..e20ac4ecd 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/sims/InteractSim.kt @@ -28,10 +28,10 @@ import com.lambda.interaction.construction.simulation.result.results.InteractRes import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.ContainerType -import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.container.selection.select -import com.lambda.interaction.handler.handlers.findContainers +import com.lambda.interaction.handler.handlers.findContainer import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotation import com.lambda.interaction.manager.managers.rotating.RotationManager @@ -206,10 +206,13 @@ class InteractSim internal constructor(simInfo: InteractSimInfo) return null } val stackSelection = item?.select(if (item == Items.AIR) 0 else 1) - ?: selectStack { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } - val containerSelection = selectContainer { ofAnyType(ContainerType.Hotbar) } - val container = findContainers(stackSelection, containerSelection) - .firstOrNull() + ?: stackSelection { sortedWith { compareByDescending { it.stack.inventoryIndex == player.inventory.selectedSlot } } } + val containerSelection = + containerSelection { + hasStack(stackSelection) + ofAnyType(ContainerType.Hotbar) + } + val container = findContainer(containerSelection) ?: run { result(GenericResult.WrongItemSelection(pos, stackSelection, player.mainHandStack)) return null diff --git a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt index 7eb8fd043..d79b3748b 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/verify/TargetState.kt @@ -20,7 +20,6 @@ package com.lambda.interaction.construction.verify import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.interaction.handler.handlers.findContainerWithDisposable -import com.lambda.interaction.handler.handlers.findContainersWithDisposable import com.lambda.util.BlockUtils.blockState import com.lambda.util.BlockUtils.emptyState import com.lambda.util.BlockUtils.isEmpty diff --git a/src/main/kotlin/com/lambda/interaction/container/Container.kt b/src/main/kotlin/com/lambda/interaction/container/Container.kt index 18c348749..4195e1134 100644 --- a/src/main/kotlin/com/lambda/interaction/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/container/Container.kt @@ -144,12 +144,12 @@ abstract class Container( fun findMoveSlots( selection: StackSelection, toContainer: Container, - toStackSelection: StackSelection = StackSelection.EVERYTHING + toStackSelection: StackSelection = StackSelection.ANYTHING ) = Pair(findSlot(selection), toContainer.findReplaceSlot(toStackSelection)) context(_: Automated) open fun findReplaceSlot( - selection: StackSelection = StackSelection.EVERYTHING + selection: StackSelection = StackSelection.ANYTHING ) = findSlots(selection) .sortedWith(replaceSorter) .firstOrNull() diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt index 8ba7a894f..99ec23127 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt @@ -28,7 +28,7 @@ import com.lambda.interaction.container.OpenContainerTask import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.selection.ContainerSelection -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.container.selection.select import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.breakAndCollect @@ -79,7 +79,7 @@ data class ShulkerBoxContainer( ) : OpenContainerTask(description), Automated by automated { override fun SafeContext.onStart() { transfer( - selectStack { inIndex(index); isItem(shulkerItem) }, + stackSelection { inIndex(index); isItem(shulkerItem) }, containedIn.select(), HotbarContainer.select() ).then { slot -> placeContainer(slot) } @@ -103,9 +103,9 @@ data class ShulkerBoxContainer( else actionTask { player.closeScreen() } }.then { breakAndCollect(blockPos) } .then { - selectStack { + stackSelection { isItem(shulkerItem) - hasName(itemName) + withName(itemName) sortedByBestContentMatch(stacks) }.transfer( ContainerSelection.HOTBAR_AND_INVENTORY, diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt index 5da064731..9fbb794ea 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt @@ -20,25 +20,26 @@ package com.lambda.interaction.container.selection import com.lambda.interaction.container.Container import com.lambda.interaction.container.ContainerMarker import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.NestedContainer import com.lambda.interaction.container.containers.ArmorContainer import com.lambda.interaction.container.containers.CreativeContainer import com.lambda.interaction.container.containers.CursorContainer import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.container.containers.OffHandContainer -import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection import com.lambda.interaction.handler.handlers.ContainerSearchScope @ContainerMarker fun Container.select( scope: ContainerSearchScope = ContainerSearchScope.Accessed -) = selectContainer(scope) { ofAny(this@select) } +) = containerSelection(scope) { ofAny(this@select) } @ContainerMarker fun selectContainers( vararg containers: Container, scope: ContainerSearchScope = ContainerSearchScope.Accessed -) = selectContainer(scope) { ofAny(*containers) } +) = containerSelection(scope) { ofAny(*containers) } /** * ContainerSelection is a class that holds a predicate for matching containers. @@ -48,7 +49,8 @@ class ContainerSelection @ContainerMarker internal constructor( val selector: (Container) -> Boolean, val scope: ContainerSearchScope = ContainerSearchScope.Accessed, val containersWhitelist: Collection = emptyList(), - val accessedOnly: Boolean = false, + val containersBlacklist: Collection = emptyList(), + val accessScope: AccessScope = AccessScope.Both, val comparator: Comparator = compareBy { it.type } ) { @ContainerMarker @@ -62,13 +64,16 @@ class ContainerSelection @ContainerMarker internal constructor( run { containersWhitelist .takeIf { it.isNotEmpty() } - ?.filter { it in containers && (!accessedOnly || it.isAccessed) } - ?: containers - }.filter(selector) + ?.asSequence() + ?.filter { it in containers && (accessScope.accessed?.equals(it.isAccessed) != false) } + ?: containers.asSequence() + }.filter { it !in containersBlacklist } + .filter(selector) .sortedWith(comparator) + .toList() companion object { - val EVERYTHING = ContainerSelection({ true }) + val ACCESSED = ContainerSelection({ true }) val NOTHING = ContainerSelection({ false }) val HOTBAR_AND_INVENTORY = selectContainers(HotbarContainer, InventoryContainer) val PLAYER = @@ -95,21 +100,27 @@ class ContainerSelectionBuilder @ContainerMarker private constructor( ) : this(scope) { this.selector = selection.selector this.containersWhitelist.addAll(selection.containersWhitelist) - this.accessedOnly = selection.accessedOnly + this.containersBlacklist.addAll(selection.containersBlacklist) + this.accessScope = selection.accessScope this.comparator = selection.comparator } private var selector: (Container) -> Boolean = { true } - private var containersWhitelist = mutableListOf() - private var accessedOnly = false + private val containersWhitelist = mutableListOf() + private val containersBlacklist = mutableListOf() + private var accessScope: AccessScope = AccessScope.Both private var comparator: Comparator = compareBy { it.type } - private var invertNewSelectors = false - fun ofAny(vararg container: Container) { - containersWhitelist.addAll(container) + fun ofAny(vararg containers: Container) { + containersWhitelist.addAll(containers) appendSelector { container -> container in containersWhitelist } } + fun noneOf(vararg containers: Container) { + containersBlacklist.addAll(containers) + appendSelector { container -> container !in containersBlacklist } + } + fun ofAnyType(vararg types: ContainerType) { appendSelector { container -> types.contains(container.type) } } @@ -118,31 +129,50 @@ class ContainerSelectionBuilder @ContainerMarker private constructor( appendSelector { container -> !types.contains(container.type) } } - fun matchesSlots(stackSelection: StackSelection) { - appendSelector { container -> stackSelection.filter(container.slots).isNotEmpty() } + fun isNested() { + appendSelector { container -> container is NestedContainer } } - fun matchesStacks(stackSelection: StackSelection) { - appendSelector { container -> stackSelection.filter(container.stacks).isNotEmpty() } + fun notNested() { + appendSelector { container -> container !is NestedContainer } } fun matches(containerSelection: ContainerSelection) { appendSelector { container -> containerSelection.matches(container) } } + fun noMatch(containerSelection: ContainerSelection) { + appendSelector { container -> !containerSelection.matches(container) } + } + + fun hasStack(stackSelection: StackSelection) { + appendSelector { container -> stackSelection isIn container } + } + + fun noStack(stackSelection: StackSelection) { + appendSelector { container -> !stackSelection.isIn(container) } + } + + fun hasSpace(stackSelection: StackSelection) { + appendSelector { container -> stackSelection spaceIn container } + } + + fun noSpace(stackSelection: StackSelection) { + appendSelector { container -> !stackSelection.spaceIn(container) } + } + fun isAccessed() { - accessedOnly = true + accessScope = AccessScope.Accessed appendSelector { it.isAccessed } } - fun custom(predicate: (Container) -> Boolean) { - appendSelector { predicate(it) } + fun notAccessed() { + accessScope = AccessScope.NotAccessed + appendSelector { !it.isAccessed } } - fun inverted(block: () -> Boolean) { - invertNewSelectors = true - block() - invertNewSelectors = false + fun predicate(predicate: (Container) -> Boolean) { + appendSelector { predicate(it) } } fun sortedWith(comparator: Comparator) { @@ -154,15 +184,13 @@ class ContainerSelectionBuilder @ContainerMarker private constructor( } private fun appendSelector(selector: (Container) -> Boolean) { - val invert = invertNewSelectors - val currentSelector = this.selector - this.selector = { currentSelector(it) && selector(it) xor invert } + this.selector = { this.selector(it) && selector(it) } } - private fun build() = ContainerSelection(selector, scope, containersWhitelist, accessedOnly, comparator) + private fun build() = ContainerSelection(selector, scope, containersWhitelist, containersBlacklist, accessScope, comparator) companion object { - fun selectContainer( + fun containerSelection( scope: ContainerSearchScope = ContainerSearchScope.Accessed, builder: ContainerSelectionBuilder.() -> Unit ) = ContainerSelectionBuilder(scope).apply(builder).build() @@ -172,4 +200,10 @@ class ContainerSelectionBuilder @ContainerMarker private constructor( builder: ContainerSelectionBuilder.() -> Unit = {} ) = ContainerSelectionBuilder(this, scope).apply(builder).build() } +} + +enum class AccessScope(val accessed: Boolean?) { + Both(null), + Accessed(true), + NotAccessed(false) } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt index a58f95d22..262ff755b 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.container.selection import com.lambda.interaction.container.Container import com.lambda.interaction.container.ContainerMarker -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils @@ -38,18 +38,18 @@ import net.minecraft.screen.slot.Slot import java.util.* @ContainerMarker -fun Item.select(count: Int = 0) = selectStack(count) { isItem(this@select) } +fun Item.select(count: Int = 0) = stackSelection(count) { isItem(this@select) } @ContainerMarker -fun ItemStack.select(count: Int = 0) = selectStack(count) { isItemStack(this@select) } +fun ItemStack.select(count: Int = 0) = stackSelection(count) { isItemStack(this@select) } -@Suppress("unused") class StackSelection @ContainerMarker internal constructor( val whitelistedSlots: Collection = emptyList(), + val blacklistedSlots: Collection = emptyList(), val count: Int = 0, val item: Item? = null, val itemStack: ItemStack? = null, - val inShulkerBox: Boolean = false, + val shulkerBoxScope: ShulkerBoxScope = ShulkerBoxScope.Both, val comparator: Comparator> = compareBy { it.stack.count }, val selector: (ItemStack, Slot?) -> Boolean, ) { @@ -63,23 +63,25 @@ class StackSelection @ContainerMarker internal constructor( @ContainerMarker fun matches(stack: ItemStack) = - if (inShulkerBox) stack.shulkerBoxStacks.any { selector(it, null) } - else selector(stack, null) + shulkerBoxScope.inShulkerBox?.equals(stack.shulkerBoxStacks.any { selector(it, null) }) != false || + selector(stack, null) @ContainerMarker fun matches(slot: Slot): Boolean = - if (inShulkerBox) slot.stack.shulkerBoxStacks.any { selector(it, null) } - else selector(slot.stack, slot) + shulkerBoxScope.inShulkerBox?.equals(slot.stack.shulkerBoxStacks.any { selector(it, null) }) != false || + selector(slot.stack, slot) @ContainerMarker @JvmName("filter1") fun filter(stacks: Iterable) = stacks .let { if (whitelistedSlots.isNotEmpty()) emptyList() else it } + .asSequence() .filter(::matches) .map { StackAndSlot(it, null) } .sortedWith(comparator) .map { it.stack } + .toList() @ContainerMarker @JvmName("filter2") @@ -87,22 +89,29 @@ class StackSelection @ContainerMarker internal constructor( slots .let { slots -> if (whitelistedSlots.isNotEmpty()) { - whitelistedSlots.filter { it in slots } - } else slots + whitelistedSlots + .asSequence() + .filter { it in slots } + } else slots.asSequence() } + .filter { it !in blacklistedSlots } .filter(::matches) .map { StackAndSlot(it.stack, it) } .sortedWith(comparator) .map { it.slot } + .toList() + @ContainerMarker infix fun isIn(container: Container) = container.count(this) >= count + @ContainerMarker infix fun spaceIn(container: Container) = container.spaceLeft(this) >= count + @Suppress("unused") companion object { - val EVERYTHING = StackSelection { _, _ -> true } + val ANYTHING = StackSelection { _, _ -> true } val NOTHING = StackSelection { _, _ -> false } } } @@ -113,12 +122,12 @@ class StackSelectionBuilder @ContainerMarker private constructor( private var count: Int = 0 ) { private val whitelistedSlots = mutableListOf() + private val blacklistedSlots = mutableListOf() private var selector: (ItemStack, Slot?) -> Boolean = { _, _ -> true } private var item: Item? = null private var itemStack: ItemStack? = null private var comparator: Comparator>? = null - private var inShulkerBoxesOnly: Boolean = false - private var invertNewSelectors = false + private var shulkerBoxScope: ShulkerBoxScope = ShulkerBoxScope.NotInShulkerBox @ContainerMarker private constructor( @@ -126,11 +135,12 @@ class StackSelectionBuilder @ContainerMarker private constructor( count: Int = selection.count ) : this(count) { this.whitelistedSlots.addAll(selection.whitelistedSlots) + this.blacklistedSlots.addAll(selection.blacklistedSlots) this.selector = selection.selector this.item = selection.item this.itemStack = selection.itemStack this.comparator = selection.comparator - this.inShulkerBoxesOnly = selection.inShulkerBox + this.shulkerBoxScope = selection.shulkerBoxScope } fun isItem(item: Item) { @@ -138,30 +148,51 @@ class StackSelectionBuilder @ContainerMarker private constructor( appendSelector { stack, _ -> stack.item == item } } + fun notItem(item: Item) { + appendSelector { stack, _ -> stack.item != item } + } + inline fun isItem() { val kClass = T::class appendSelector { stack, _ -> stack::class == kClass } } + inline fun notItem() { + val kClass = T::class + appendSelector { stack, _ -> stack::class != kClass } + } + fun isItemStack(stack: ItemStack) { this.itemStack = stack appendSelector { s, _ -> ItemStack.areEqual(s, stack) } } + fun notItemStack(stack: ItemStack) { + appendSelector { s, _ -> !ItemStack.areEqual(s, stack) } + } + fun isItemStackByRef(stack: ItemStack) { this.itemStack = stack appendSelector { s, _ -> s === stack } } - fun inShulkerBoxesOnly() { - inShulkerBoxesOnly = true + fun notItemStackByRef(stack: ItemStack) { + appendSelector { s, _ -> s !== stack } + } + + fun alsoInShulkerBoxes() { + shulkerBoxScope = ShulkerBoxScope.Both } - fun isOneOfItems(items: Collection) { + fun onlyInShulkerBoxes() { + shulkerBoxScope = ShulkerBoxScope.InShulkerBox + } + + fun ofAnyItems(items: Collection) { appendSelector { stack, _ -> items.contains(stack.item) } } - fun isNoneOfItems(items: Collection) { + fun noneOfItems(items: Collection) { appendSelector { stack, _ -> !items.contains(stack.item) } } @@ -169,52 +200,87 @@ class StackSelectionBuilder @ContainerMarker private constructor( appendSelector { stack, _ -> stack.item in ItemUtils.SHULKER_BOXES } } - fun hasName(name: String) { - appendSelector { stack, _ -> - stack.name.string == name - } + fun notShulkerBox() { + appendSelector { stack, _ -> stack.item !in ItemUtils.SHULKER_BOXES } + } + + fun withName(name: String) { + appendSelector { stack, _ -> stack.name.string == name } + } + + fun withoutName(name: String) { + appendSelector { stack, _ -> stack.name.string != name } } - fun isOneOfStacks(stacks: Collection) { + fun ofAnyStacks(stacks: Collection) { appendSelector { stack, _ -> stacks.contains(stack) } } - fun isNoneOfStacks(stacks: Collection) { + fun noneOfStacks(stacks: Collection) { appendSelector { stack, _ -> !stacks.contains(stack) } } fun isEfficientForBreaking(blockState: BlockState) { appendSelector { itemStack, _ -> - val hasEfficientTool = efficientToolCache.getOrPut(blockState) { - ItemUtils.TOOLS.any { it.getMiningSpeed(it.defaultStack, blockState) > 1f } - } - if (hasEfficientTool) itemStack.item.getMiningSpeed(itemStack, blockState) > 1f + if (hasEfficientTool(blockState)) itemStack.item.getMiningSpeed(itemStack, blockState) > 1f else true } } + fun notEfficientForBreaking(blockState: BlockState) { + appendSelector { itemStack, _ -> + if (hasEfficientTool(blockState)) itemStack.item.getMiningSpeed(itemStack, blockState) <= 1f + else true + } + } + + private fun hasEfficientTool(blockState: BlockState) = + efficientToolCache.getOrPut(blockState) { + ItemUtils.TOOLS.any { it.getMiningSpeed(it.defaultStack, blockState) > 1f } + } + fun isSuitableForBreaking(blockState: BlockState) { appendSelector { itemStack, _ -> !blockState.isToolRequired || itemStack.isSuitableFor(blockState) } } - fun hasTag(tag: TagKey) { + fun notSuitableForBreaking(blockState: BlockState) { + appendSelector { itemStack, _ -> + blockState.isToolRequired && !itemStack.isSuitableFor(blockState) + } + } + + fun withTag(tag: TagKey) { appendSelector { stack, _ -> stack.isIn(tag) } } - fun hasUseAction(action: UseAction) { + fun withoutTag(tag: TagKey) { + appendSelector { stack, _ -> !stack.isIn(tag) } + } + + fun withUseAction(action: UseAction) { appendSelector { stack, _ -> stack.useAction == action } } - fun isTool() = hasComponent(DataComponentTypes.TOOL) + fun withoutUseAction(action: UseAction) { + appendSelector { stack, _ -> stack.useAction != action } + } - fun isFood() = hasComponent(DataComponentTypes.FOOD) + fun isTool() = withComponent(DataComponentTypes.TOOL) - fun hasComponent(type: ComponentType<*>) { - appendSelector { stack, _ -> - stack.components.contains(type) - } + fun notTool() = withoutComponent(DataComponentTypes.TOOL) + + fun isFood() = withComponent(DataComponentTypes.FOOD) + + fun notFood() = withoutComponent(DataComponentTypes.FOOD) + + fun withComponent(type: ComponentType<*>) { + appendSelector { stack, _ -> stack.components.contains(type) } + } + + fun withoutComponent(type: ComponentType<*>) { + appendSelector { stack, _ -> !stack.components.contains(type) } } fun isBlock(block: Block) { @@ -222,17 +288,29 @@ class StackSelectionBuilder @ContainerMarker private constructor( appendSelector { stack, _ -> stack.item == block.asItem() } } - fun hasDamage(damage: Int) { + fun notBlock(block: Block) { + appendSelector { stack, _ -> stack.item != block.asItem() } + } + + fun withDamage(damage: Int) { appendSelector { stack, _ -> stack.damage == damage } } - fun hasEnchantment(enchantment: RegistryKey, level: Int = -1) { + fun withoutDamage(damage: Int) { + appendSelector { stack, _ -> stack.damage != damage } + } + + fun withEnchantment(enchantment: RegistryKey, level: Int = -1) { appendSelector { stack, _ -> - if (level < 0) { - stack.getEnchantment(enchantment) > 0 - } else { - stack.getEnchantment(enchantment) == level - } + if (level < 0) stack.getEnchantment(enchantment) > 0 + else stack.getEnchantment(enchantment) == level + } + } + + fun withoutEnchantment(enchantment: RegistryKey, level: Int = -1) { + appendSelector { stack, _ -> + if (level < 0) stack.getEnchantment(enchantment) <= 0 + else stack.getEnchantment(enchantment) != level } } @@ -240,27 +318,38 @@ class StackSelectionBuilder @ContainerMarker private constructor( appendSelector { stack, _ -> stack.isEmpty} } + fun notEmpty() { + appendSelector { stack, _ -> !stack.isEmpty} + } + fun isSlot(slot: Slot) { appendSelector { _, s -> s != null && s matches slot } } + fun notSlot(slot: Slot) { + appendSelector { _, s -> s == null || !s.matches(slot) } + } + fun isSlotByReference(slot: Slot) { whitelistedSlots.add(slot) appendSelector { _, s -> s === slot } } + fun notSlotByReference(slot: Slot) { + blacklistedSlots.add(slot) + appendSelector { _, s -> s !== slot } + } + fun inIndex(index: Int) { appendSelector { _, s -> s?.index == index } } - fun custom(predicate: (ItemStack, Slot?) -> Boolean) { - appendSelector { stack, slot -> predicate(stack, slot) } + fun notInIndex(index: Int) { + appendSelector { _, s -> s?.index != index } } - fun inverted(block: () -> Unit) { - invertNewSelectors = true - block() - invertNewSelectors = false + fun predicate(predicate: (ItemStack, Slot?) -> Boolean) { + appendSelector { stack, slot -> predicate(stack, slot) } } fun sortedWith(newComparator: Comparator>) { @@ -291,20 +380,19 @@ class StackSelectionBuilder @ContainerMarker private constructor( @PublishedApi internal fun appendSelector(selector: (ItemStack, Slot?) -> Boolean) { - val invert = invertNewSelectors - val currentSelector = this.selector this.selector = { stack, slot -> - currentSelector(stack, slot) && selector(stack, slot) xor invert + this.selector(stack, slot) && selector(stack, slot) } } private fun build() = StackSelection( whitelistedSlots, + blacklistedSlots, count, item, itemStack, - inShulkerBoxesOnly, + shulkerBoxScope, comparator ?: compareBy { it.stack.count }, selector ) @@ -312,7 +400,7 @@ class StackSelectionBuilder @ContainerMarker private constructor( companion object { private val efficientToolCache = Collections.synchronizedMap(mutableMapOf()) - fun selectStack( + fun stackSelection( count: Int = 0, builder: StackSelectionBuilder.() -> Unit ) = StackSelectionBuilder(count).apply(builder).build() @@ -324,4 +412,10 @@ class StackSelectionBuilder @ContainerMarker private constructor( } } -data class StackAndSlot(val stack: ItemStack, val slot: T) \ No newline at end of file +data class StackAndSlot(val stack: ItemStack, val slot: T) + +enum class ShulkerBoxScope(val inShulkerBox: Boolean?) { + Both(null), + InShulkerBox(true), + NotInShulkerBox(false) +} \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index be438a6ad..ca19ef387 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -17,7 +17,9 @@ package com.lambda.interaction.handler.handlers +import com.lambda.Lambda import com.lambda.context.Automated +import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.core.Loadable import com.lambda.event.events.InventoryEvent @@ -34,14 +36,15 @@ import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.interaction.container.containers.external.PlacedShulkerBoxContainer import com.lambda.interaction.container.containers.external.ShulkerBoxContainer import com.lambda.interaction.container.selection.ContainerSelection -import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.selectContainer +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.mutate -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.util.BlockUtils.blockEntity import com.lambda.util.FolderRegistry import com.lambda.util.ReflectionUtils.getInstances import com.lambda.util.extension.containerStacks +import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils.SHULKER_BOXES import com.lambda.util.player.SlotUtils.typeSafe @@ -58,8 +61,6 @@ import net.minecraft.screen.ScreenHandler import net.minecraft.screen.ScreenHandlerType import net.minecraft.state.property.Properties import net.minecraft.util.math.BlockPos -import com.lambda.Lambda -import com.lambda.context.AutomatedSafeContext import java.nio.file.Files @Suppress("unused") @@ -237,16 +238,15 @@ object ContainerHandler : Loadable { @ContainerMarker context(_: AutomatedSafeContext) fun StackSelection.move( - fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, - toSelection: ContainerSelection = ContainerSelection.EVERYTHING, - toStackSelection: StackSelection = StackSelection.EVERYTHING + fromSelection: ContainerSelection = ContainerSelection.ACCESSED, + toSelection: ContainerSelection = ContainerSelection.ACCESSED, + replaceSelection: StackSelection = StackSelection.ANYTHING ): Boolean { - val singleSelection = mutate(count.coerceAtMost(64)) val fromContainer = findContainer( - singleSelection, - selectContainer { + containerSelection { matches(fromSelection) + hasStack(mutate(count.coerceAtMost(64))) isAccessed() } ) @@ -254,76 +254,119 @@ fun StackSelection.move( val toContainer = findContainer( - toStackSelection, - selectContainer { + containerSelection { matches(toSelection) + hasStack(replaceSelection) isAccessed() } ) ?: return false - val (fromSlot, toSlot) = fromContainer.findMoveSlots(this, toContainer, toStackSelection) + val (fromSlot, toSlot) = fromContainer.findMoveSlots(this, toContainer, replaceSelection) if (fromSlot == null || toSlot == null) return false return fromContainer.swap(fromSlot, toSlot, toContainer) } @ContainerMarker -context(_: Automated) -fun findContainer( - stackSelection: StackSelection = StackSelection.EVERYTHING, - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING -) = findContainers(stackSelection, containerSelection) +context(automated: Automated) +fun findSlot( + stackSelection: StackSelection = StackSelection.ANYTHING, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +) = findSlots(stackSelection, containerSelection, sorted) .firstOrNull() @ContainerMarker context(automated: Automated) -fun findContainers( - stackSelection: StackSelection = StackSelection.EVERYTHING, - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +fun findSlots( + stackSelection: StackSelection = StackSelection.ANYTHING, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +) = searchContainers(containerSelection.scope) + .filter { containerSelection.matches(it) } + .let { + if (sorted) it.sorted() + else it + } + .mapNotNull { container -> + val slots = stackSelection.filter(container.slots) + if (slots.count >= stackSelection.count) slots + else null + } + .flatten() + +@ContainerMarker +context(automated: Automated) +fun findStack( + stackSelection: StackSelection = StackSelection.ANYTHING, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +) = findStacks(stackSelection, containerSelection, sorted) + .firstOrNull() + +@ContainerMarker +context(automated: Automated) +fun findStacks( + stackSelection: StackSelection = StackSelection.ANYTHING, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true ) = searchContainers(containerSelection.scope) .filter { containerSelection.matches(it) } - .filter { stackSelection isIn it } - .sortedWith(automated.inventoryConfig.accessPriority.materialComparator(stackSelection)) + .let { + if (sorted) it.sorted() + else it + } + .mapNotNull { container -> + val stacks = stackSelection.filter(container.stacks) + if (stacks.count >= stackSelection.count) stacks + else null + } + .flatten() @ContainerMarker context(_: Automated) -fun StackSelection.findContainerWithSpace( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING -) = findContainersWithSpace(containerSelection) +fun findContainer( + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +) = findContainers(containerSelection, sorted) .firstOrNull() @ContainerMarker context(automated: Automated) -fun StackSelection.findContainersWithSpace( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING +fun findContainers( + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true ) = searchContainers(containerSelection.scope) .filter { containerSelection.matches(it) } - .filter { this spaceIn it } - .sortedWith(automated.inventoryConfig.accessPriority.spaceComparator(this)) + .let { + if (sorted) it.sorted() + else it + } @ContainerMarker context(_: Automated) fun findContainerWithDisposable( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING -) = findContainersWithDisposable(containerSelection) + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +) = findContainersWithDisposable(containerSelection, sorted) .firstOrNull() @ContainerMarker context(automated: Automated) fun findContainersWithDisposable( - containerSelection: ContainerSelection = ContainerSelection.EVERYTHING + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true ) = with(automated) { findContainers( - containerSelection = selectContainer(containerSelection.scope) { + containerSelection(containerSelection.scope) { matches(containerSelection) - matchesStacks( - selectStack(1) { - isOneOfItems(inventoryConfig.disposables) - } + hasStack( + stackSelection(1) { ofAnyItems(inventoryConfig.disposables) } ) - } + }, + sorted ) } diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt index d7de19c14..2a8d1b498 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt @@ -17,13 +17,12 @@ package com.lambda.interaction.handler.handlers -import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection import com.lambda.interaction.container.selection.StackAndSlot -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.modules.movement.elytrafly.ElytraFly import com.lambda.module.modules.movement.elytrafly.ElytraFly.mode @@ -42,9 +41,9 @@ import net.minecraft.registry.tag.ItemTags object GlideHandler { val ELYTRA_SELECTION = - selectStack { + stackSelection { isItem(Items.ELYTRA) - custom { stack, _ -> stack.damage < stack.maxDamage } + predicate { stack, _ -> stack.damage < stack.maxDamage } sortedWith { compareByDescending> { it.stack.getEnchantment(Enchantments.UNBREAKING) @@ -54,10 +53,10 @@ object GlideHandler { } } val CHESTPLATE_SELECTION = - selectStack { - hasTag(ItemTags.CHEST_ARMOR) - inverted { isItem(Items.ELYTRA) } - custom { stack, _ -> stack.damage < stack.maxDamage } + stackSelection { + withTag(ItemTags.CHEST_ARMOR) + notItem(Items.ELYTRA) + predicate { stack, _ -> stack.damage < stack.maxDamage } sortedWith { compareByDescending> { it.stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) @@ -166,18 +165,19 @@ object GlideHandler { } @JvmStatic - context(safeContext: SafeContext, _: Automated) + context(safeContext: SafeContext) fun canGlide(): Boolean = with(safeContext) { val fakeFly = ElytraFly.isEnabled && ElytraFly.fakeFly val canGlideAlready = player.canGlideWithChestPiece() != fakeFly if (!autoSwapChecking || canGlideAlready) return canGlideAlready val selection = if (fakeFly) CHESTPLATE_SELECTION else ELYTRA_SELECTION - return findContainers( - selection, - ContainerSelection.HOTBAR_AND_INVENTORY - ).toList() - .isNotEmpty() + return with(ElytraFly) { + findContainer( + containerSelection { hasStack(selection) }, + false + ) != null + } } private class PendingGlideAction( diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt index f800db9ff..40f04a2bf 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/breaking/RebreakHandler.kt @@ -24,10 +24,10 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.interaction.construction.simulation.context.BreakContext -import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock -import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.reBreak import com.lambda.interaction.handler.handlers.PacketLimitHandler import com.lambda.interaction.handler.handlers.PacketType +import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock +import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.reBreak import com.lambda.interaction.manager.managers.breaking.BreakInfo import com.lambda.interaction.manager.managers.breaking.BreakManager import com.lambda.interaction.manager.managers.breaking.BreakManager.calcBreakDelta diff --git a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt index 00a14ab4e..eabc193ee 100644 --- a/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/manager/managers/breaking/BreakManager.kt @@ -35,6 +35,8 @@ import com.lambda.interaction.construction.simulation.result.results.BreakResult import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.selection.StackSelection +import com.lambda.interaction.handler.handlers.PacketLimitHandler +import com.lambda.interaction.handler.handlers.PacketType import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.destroyBlock import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.pendingActions @@ -42,8 +44,6 @@ import com.lambda.interaction.handler.handlers.breaking.BrokenBlockHandler.start import com.lambda.interaction.handler.handlers.breaking.RebreakHandler import com.lambda.interaction.handler.handlers.breaking.RebreakHandler.getRebreakPotential import com.lambda.interaction.handler.handlers.breaking.RebreakResult -import com.lambda.interaction.handler.handlers.PacketLimitHandler -import com.lambda.interaction.handler.handlers.PacketType import com.lambda.interaction.manager.Manager import com.lambda.interaction.manager.ManagerUtils.isPosBlocked import com.lambda.interaction.manager.PositionBlocking @@ -139,7 +139,7 @@ object BreakManager : Manager( .lastOrNull { it.breakConfig.doubleBreak || it.type == Secondary }?.context?.itemSelection - ?: StackSelection.EVERYTHING + ?: StackSelection.ANYTHING override val blockedPositions get() = activeInfos.map { it.context.blockPos } + pendingActions.map { it.context.blockPos } diff --git a/src/main/kotlin/com/lambda/module/HudModule.kt b/src/main/kotlin/com/lambda/module/HudModule.kt index 23be5636b..5a4372b02 100644 --- a/src/main/kotlin/com/lambda/module/HudModule.kt +++ b/src/main/kotlin/com/lambda/module/HudModule.kt @@ -19,7 +19,6 @@ package com.lambda.module import com.lambda.config.settings.complex.Bind import com.lambda.gui.Layout -import com.lambda.module.ModuleTag import java.awt.Color abstract class HudModule( diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index 32c21c1db..517625872 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.combat -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.context.SafeContext diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 39ccad79d..75902dad3 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -31,7 +31,7 @@ import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.container.containers.OffHandContainer import com.lambda.interaction.container.selection.select -import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.handler.handlers.findSlot import com.lambda.interaction.handler.handlers.move import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo @@ -51,8 +51,8 @@ import com.lambda.util.combat.CombatUtils.crystalDamage import com.lambda.util.extension.fullHealth import com.lambda.util.math.MathUtils.ceilToInt import com.lambda.util.math.MathUtils.roundToStep -import com.lambda.util.math.distSq import com.lambda.util.math.blockPos +import com.lambda.util.math.distSq import com.lambda.util.math.getHitVec import com.lambda.util.math.minus import com.lambda.util.math.plus @@ -490,17 +490,16 @@ object CrystalAura : Module( ) runSafeAutomated { if (!swap) return@runSafe - val toContainer = + val toContainerSelection = when (swapHand) { Hand.MAIN_HAND -> HotbarContainer Hand.OFF_HAND -> OffHandContainer }.select() - val crystalSlot = findContainer(selection, toContainer) - ?.findSlot(selection) + val crystalSlot = findSlot(selection, toContainerSelection) if (crystalSlot == null) { - if (!selection.move(InventoryContainer.select(), toContainer)) return@runSafe + if (!selection.move(InventoryContainer.select(), toContainerSelection)) return@runSafe } if (swapHand == Hand.MAIN_HAND) { diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index 2ae087f05..d9962e06e 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -29,7 +29,7 @@ import com.lambda.event.events.InventoryEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.containers.HotbarContainer -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module @@ -120,7 +120,7 @@ object KillAura : Module( if (swap) { val selection = - selectStack { + stackSelection { sortedWith { compareByDescending { damageMode.block(this@listen, it.stack) diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index 3b68b1217..0e140935c 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -25,9 +25,9 @@ import com.lambda.context.SafeContext import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.selection.ContainerSelection -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.handler.handlers.FriendHandler.isFriend -import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.handler.handlers.findStack import com.lambda.module.Module import com.lambda.module.ModuleTag import com.lambda.task.Task @@ -72,14 +72,13 @@ object PlayerTrap : Module( onEnable { task = tickingBlueprint { val selection = - selectStack { - custom { stack, _ -> + stackSelection { + predicate { stack, _ -> stack.item is BlockItem && blocks.contains(stack.item.block) } } - val block = findContainer(selection, ContainerSelection.HOTBAR_AND_INVENTORY) - ?.findStack(selection) + val block = findStack(selection, ContainerSelection.HOTBAR_AND_INVENTORY) ?.item?.block ?: return@tickingBlueprint emptyMap() diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt index 552cad24c..48d5eb31f 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt @@ -24,11 +24,11 @@ import com.lambda.config.withEdits import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.selection.ContainerSelection -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack -import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection +import com.lambda.interaction.handler.handlers.findStack import com.lambda.module.Module -import com.lambda.module.modules.combat.PlayerTrap.getTrapPositions import com.lambda.module.ModuleTag +import com.lambda.module.modules.combat.PlayerTrap.getTrapPositions import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build @@ -62,14 +62,13 @@ object Surround : Module( onEnable { task = tickingBlueprint { val selection = - selectStack { - custom { stack, _ -> + stackSelection { + predicate { stack, _ -> stack.item is BlockItem && blocks.contains(stack.item.block) } } - val block = findContainer(selection, ContainerSelection.HOTBAR_AND_INVENTORY) - ?.findStack(selection) + val block = findStack(selection, ContainerSelection.HOTBAR_AND_INVENTORY) ?.item?.block ?: return@tickingBlueprint emptyMap() diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt index 95abb3962..abcfe1088 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt @@ -27,8 +27,8 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.graphics.util.DynamicAABB import com.lambda.gui.components.ClickGuiLayout import com.lambda.module.Module -import com.lambda.module.modules.combat.KillAura import com.lambda.module.ModuleTag +import com.lambda.module.modules.combat.KillAura import com.lambda.util.ClientPacket import com.lambda.util.PacketUtils.handlePacketSilently import com.lambda.util.PacketUtils.sendPacketSilently diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index 2d20319c9..b2ae33205 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -30,9 +30,11 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.GlideHandler +import com.lambda.interaction.handler.handlers.findStack import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module @@ -84,9 +86,11 @@ object BetterFirework : Module( private var takeoffState = TakeoffState.Idle val ClientPlayerEntity.hasFireworks: Boolean - get() = Items.FIREWORK_ROCKET.select() - .filter(HotbarAndInventoryContainer.stacks) - .isNotEmpty() || offHandStack.item == Items.FIREWORK_ROCKET + get() = + findStack( + Items.FIREWORK_ROCKET.select(), + ContainerSelection.HOTBAR_AND_INVENTORY + ) != null || offHandStack.item == Items.FIREWORK_ROCKET context(_: SafeContext) private val ClientPlayerEntity.canTakeoff: Boolean @@ -167,7 +171,7 @@ object BetterFirework : Module( if (!inventory) return val inventoryMatch = selection.bestMatch(InventoryContainer.slots) ?: return - val hotbarSlot = selectStack { isEmpty() }.bestMatch(HotbarContainer.slots)?.index ?: 8 + val hotbarSlot = stackSelection { isEmpty() }.bestMatch(HotbarContainer.slots)?.index ?: 8 inventoryRequest { swapWithHotbar(inventoryMatch.id, hotbarSlot) diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt index fe555adea..eca5c391e 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt @@ -26,8 +26,8 @@ import com.lambda.graphics.mc.renderer.TickedRenderer.Companion.tickedRenderer import com.lambda.graphics.util.DynamicAABB import com.lambda.gui.components.ClickGuiLayout import com.lambda.module.Module -import com.lambda.module.modules.combat.KillAura import com.lambda.module.ModuleTag +import com.lambda.module.modules.combat.KillAura import com.lambda.threading.runSafe import com.lambda.util.PacketUtils.handlePacketSilently import com.lambda.util.PacketUtils.sendPacketSilently diff --git a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt index d083c4730..9f076b769 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/ElytraAltitudeControl.kt @@ -25,8 +25,8 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.modules.movement.BetterFirework.startFirework import com.lambda.module.ModuleTag +import com.lambda.module.modules.movement.BetterFirework.startFirework import com.lambda.threading.runSafe import com.lambda.util.CommunicationUtils.info import com.lambda.util.SpeedUnit diff --git a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt index 5c92c6a66..78865afd7 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/TargetStrafe.kt @@ -28,8 +28,8 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRenderer import com.lambda.interaction.manager.managers.rotating.Rotation.Companion.rotationTo import com.lambda.module.Module -import com.lambda.module.modules.combat.KillAura import com.lambda.module.ModuleTag +import com.lambda.module.modules.combat.KillAura import net.minecraft.entity.effect.StatusEffects import net.minecraft.util.math.Vec3d import java.awt.Color diff --git a/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt b/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt index 8cf57f44b..c89e52c07 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/TickShift.kt @@ -23,8 +23,8 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.module.Module -import com.lambda.module.modules.combat.KillAura import com.lambda.module.ModuleTag +import com.lambda.module.modules.combat.KillAura import com.lambda.threading.runConcurrent import com.lambda.util.CommunicationUtils.info import com.lambda.util.PacketUtils.handlePacketSilently diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt index ea2740859..4f1389c3e 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFly.kt @@ -31,10 +31,10 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.manager.managers.rotating.RotationManager import com.lambda.module.Module +import com.lambda.module.ModuleTag import com.lambda.module.modules.movement.elytrafly.modes.BounceElytraFly import com.lambda.module.modules.movement.elytrafly.modes.GeneralElytraFly import com.lambda.module.modules.movement.elytrafly.modes.GrimControlElytraFly -import com.lambda.module.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.NamedEnum import com.lambda.util.Timer diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt index f21fef99c..cd1eb6e30 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ElytraFlyMode.kt @@ -27,7 +27,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.containers.ArmorContainer import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION -import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.handler.handlers.findSlot import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest @@ -124,11 +124,7 @@ abstract class ElytraFlyMode( return inventoryRequest.done } - fun findElytra(): Slot? = - findContainer( - ELYTRA_SELECTION, - ContainerSelection.HOTBAR_AND_INVENTORY - )?.findSlot(ELYTRA_SELECTION) + fun findElytra(): Slot? = findSlot(ELYTRA_SELECTION, ContainerSelection.HOTBAR_AND_INVENTORY) protected fun SafeContext.startFly() { player.setFlag(Entity.GLIDING_FLAG_INDEX, true) diff --git a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt index 152671136..f92853026 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/elytrafly/ObstaclePassingMode.kt @@ -28,9 +28,9 @@ import com.lambda.threading.runGameScheduled import com.lambda.util.BlockUtils.blockState import com.lambda.util.CommunicationUtils.logError import com.lambda.util.SpeedUnit +import com.lambda.util.math.blockPos import com.lambda.util.math.dist import com.lambda.util.math.distSq -import com.lambda.util.math.blockPos import com.lambda.util.math.isLoaded import com.lambda.util.world.raycast.InteractionMask import com.lambda.util.world.raycast.RayCastUtils.blockResult diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt index 1bb5e18e2..a6da8b71d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoEat.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.blocks.EatConfig.Companion.reasonEating import com.lambda.config.hideAllExcept import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt index aeead9b02..a2fc3f1ed 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt @@ -23,10 +23,11 @@ import com.lambda.interaction.handler.handlers.GlideHandler.CHESTPLATE_SELECTION import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION import com.lambda.interaction.handler.handlers.GlideHandler.manuallySwapped import com.lambda.interaction.handler.handlers.GlideHandler.swapped +import com.lambda.interaction.handler.handlers.findSlots import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module -import com.lambda.module.modules.combat.AutoArmor import com.lambda.module.ModuleTag +import com.lambda.module.modules.combat.AutoArmor import com.lambda.util.CommunicationUtils.warn import com.lambda.util.player.PlayerUtils.canGlideWithChestPiece import net.minecraft.screen.slot.Slot @@ -45,13 +46,14 @@ object AutoElytraSwap : Module( fun manualSwap(elytra: Boolean): Boolean { val swapSlot = - HotbarAndInventoryContainer.slots.let { slots -> - if (elytra) ELYTRA_SELECTION.filter(slots) - else CHESTPLATE_SELECTION.filter(slots) - }.minByOrNull { it.index } ?: run { - AutoElytraSwap.warn("The required armor piece was not found for AutoElytraSwap to work.") - return false - } + findSlots( + if (elytra) ELYTRA_SELECTION + else CHESTPLATE_SELECTION + ).minByOrNull { it.index } + ?: run { + AutoElytraSwap.warn("The required armor piece was not found for AutoElytraSwap to work.") + return false + } return swapWithChestplate(swapSlot) } diff --git a/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt b/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt index 73722103a..7aa51038d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/EndermanLook.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.context.SafeContext diff --git a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt index 20742f245..76a5204fc 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/FastBreak.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editSetting import com.lambda.config.editTypedSettings import com.lambda.config.hide diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index ae88a5bfd..5c4cbd212 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -17,16 +17,17 @@ package com.lambda.module.modules.player -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.interaction.container.NestedContainer +import com.lambda.interaction.container.ContainerType import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.containers.external.EnderChestContainer -import com.lambda.interaction.handler.handlers.ContainerHandler +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection +import com.lambda.interaction.handler.handlers.findContainer import com.lambda.module.Module import com.lambda.module.ModuleTag import com.lambda.task.Task @@ -37,7 +38,6 @@ import net.minecraft.item.Items import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.SlotActionType import java.util.* -import kotlin.collections.fold @Suppress("unused") object InventoryTweaks : Module( @@ -70,12 +70,12 @@ object InventoryTweaks : Module( val targetContainer = if (stack.item == Items.ENDER_CHEST) EnderChestContainer - else { - ContainerHandler.allContainers - .filterIsInstance() - .firstOrNull { container -> container.index == slot.index } - ?: return@listen - } + else findContainer( + containerSelection { + ofAnyType(ContainerType.ShulkerBox) + isNested() + } + ) ?: return@listen event.cancel() diff --git a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt index db71f04c9..40d78570d 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/LineLock.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.player import com.lambda.config.Group -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editSetting import com.lambda.config.hideAllExcept import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index c56cdcd2b..c5b7b9a13 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -18,12 +18,12 @@ package com.lambda.module.modules.player import com.lambda.config.Group -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.blocks.BreakConfig.SwingMode import com.lambda.config.editSetting import com.lambda.config.editTypedSettings -import com.lambda.config.entries.Setting.Companion.disabled -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.disabled +import com.lambda.config.entries.onValueChange import com.lambda.config.hide import com.lambda.config.hideAllExcept import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt index 50bc048f0..c5135903e 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Replay.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Replay.kt @@ -39,8 +39,8 @@ import com.lambda.interaction.manager.managers.rotating.Rotation import com.lambda.interaction.manager.managers.rotating.RotationMode import com.lambda.interaction.manager.managers.rotating.RotationRequestBuilder.Companion.rotationRequest import com.lambda.module.Module -import com.lambda.module.modules.player.Replay.InputAction.Companion.toAction import com.lambda.module.ModuleTag +import com.lambda.module.modules.player.Replay.InputAction.Companion.toAction import com.lambda.sound.SoundHandler.playSound import com.lambda.util.CommunicationUtils.info import com.lambda.util.CommunicationUtils.logError diff --git a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt index b7a5ca5af..3fa739d4b 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/RotationLock.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editSetting import com.lambda.config.hideAllExcept import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index b1e435d49..4e4d97de9 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hide import com.lambda.config.hideAllExcept import com.lambda.config.withEdits @@ -47,7 +47,7 @@ object StackReplenish : Module( .withEdits { hideAllExcept(::inventoryConfig) inventoryConfig.apply { - hide(::disposables, ::accessPriority, ::storePriority) + hide(::disposables) } } diff --git a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt index 7f3c5ccc7..ffaecdeb2 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/ToolSaver.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.event.events.ContainerEvent diff --git a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt index bd3e6360e..0ee377384 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ContainerPreview.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc import com.lambda.config.Tab -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.settings.complex.Bind import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.module.Module diff --git a/src/main/kotlin/com/lambda/module/modules/render/Esp.kt b/src/main/kotlin/com/lambda/module/modules/render/Esp.kt index a2cc59eb9..be0d21c83 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Esp.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Esp.kt @@ -23,7 +23,7 @@ import com.lambda.config.blocks.EntityColorSettings import com.lambda.config.blocks.EntitySelectionSettings import com.lambda.config.blocks.OutlineSettings import com.lambda.config.blocks.WorldLineSettings -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.forEachSetting import com.lambda.config.hide import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt index 3ec2aae6c..94f24cc09 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Freecam.kt @@ -18,9 +18,9 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editSetting -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.hideAllExcept import com.lambda.config.withEdits import com.lambda.context.SafeContext diff --git a/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt b/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt index 9d59f795a..18dfd1a33 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Fullbright.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.render -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listenOnce diff --git a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt index 011ecaebf..7d3de14c9 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/LightLevels.kt @@ -19,6 +19,7 @@ package com.lambda.module.modules.render import com.lambda.config.Group import com.lambda.config.blocks.WorldLineSettings +import com.lambda.config.entries.onValueChange import com.lambda.config.forEachSetting import com.lambda.config.hide import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt b/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt index 6e844c124..455ea2ebb 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/RadiusESP.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.render import com.lambda.config.Group import com.lambda.config.blocks.WorldLineSettings -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.forEachSetting import com.lambda.config.hide import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/render/Search.kt b/src/main/kotlin/com/lambda/module/modules/render/Search.kt index 7d941f1f6..a0b0f134d 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Search.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Search.kt @@ -21,7 +21,7 @@ import com.lambda.config.Group import com.lambda.config.blocks.ScreenLineSettings import com.lambda.config.blocks.WorldLineSettings import com.lambda.config.editTypedSettings -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.forEachSetting import com.lambda.config.hide import com.lambda.config.settings.collections.onDeselect diff --git a/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt b/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt index 82239bbfa..b109d3b5a 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/ViewModel.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc import com.lambda.config.Tab -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.event.events.ButtonEvent import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen diff --git a/src/main/kotlin/com/lambda/module/modules/render/XRay.kt b/src/main/kotlin/com/lambda/module/modules/render/XRay.kt index 4b58bae51..426526ee8 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/XRay.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/XRay.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.settings.collections.onDeselect import com.lambda.config.settings.collections.onSelect import com.lambda.context.SafeContext diff --git a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt index 952a1bda5..7ac8b39a9 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AirPlace.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.world import com.lambda.Lambda.mc import com.lambda.config.Group -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.settings.complex.Bind import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt index a6665179c..59eb6e0ca 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoPortal.kt @@ -19,7 +19,7 @@ package com.lambda.module.modules.world import baritone.api.pathing.goals.GoalBlock import com.lambda.config.Group -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.blocks.WorldLineSettings import com.lambda.config.editSetting import com.lambda.config.forEachSetting @@ -36,16 +36,19 @@ import com.lambda.graphics.mc.renderer.ImmediateRenderer.Companion.immediateRend import com.lambda.graphics.util.DirectionMask import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.containers.HotbarContainer -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection +import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.findSlot import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.module.Module +import com.lambda.module.ModuleTag import com.lambda.module.modules.world.AutoPortal.PosHandler.currAnchorPos import com.lambda.module.modules.world.AutoPortal.PosHandler.obiPositions import com.lambda.module.modules.world.AutoPortal.PosHandler.portalPositions import com.lambda.module.modules.world.AutoPortal.PosHandler.prevAnchorPos -import com.lambda.module.ModuleTag import com.lambda.task.Task import com.lambda.task.start import com.lambda.task.tasks.build @@ -322,12 +325,12 @@ object AutoPortal : Module( return } - val sel = selectStack(1) { isItem() } + val selection = stackSelection(1) { isItem() } - val hotbarStack = sel.filter(HotbarContainer.slots).firstOrNull() - if (hotbarStack != null) { + val hotbarSlot = findSlot(selection, HotbarContainer.select()) + if (hotbarSlot != null) { val request = - hotbarRequest(hotbarStack.index) { + hotbarRequest(hotbarSlot.index) { keepTicks(0) }.submit(false) if (request.done) block() @@ -335,7 +338,7 @@ object AutoPortal : Module( } val invSlot = - if (inventory) sel.filter(HotbarAndInventoryContainer.slots).firstOrNull() + if (inventory) findSlot(selection, ContainerSelection.HOTBAR_AND_INVENTORY) else null if (invSlot == null) { failure("No Flint and Steel!") diff --git a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt index 78352b15c..6ee1bc20c 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/AutoVillagerCycle.kt @@ -18,7 +18,7 @@ package com.lambda.module.modules.world import com.lambda.config.Group -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.hideAllExcept import com.lambda.config.settings.complex.Bind import com.lambda.config.settings.complex.KeybindSetting.Companion.onPress diff --git a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt index 7ca52d72b..82f0aee02 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/HighwayTools.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.world -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editTypedSettings import com.lambda.config.withEdits import com.lambda.interaction.construction.blueprint.Blueprint.Companion.emptyStructure diff --git a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt index 5f9b6e324..608deef16 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/MapDownloader.kt @@ -19,6 +19,8 @@ package com.lambda.module.modules.world import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.handler.handlers.findStacks import com.lambda.module.Module import com.lambda.module.ModuleTag import com.lambda.util.FileUtils.locationBoundDirectory @@ -42,7 +44,8 @@ object MapDownloader : Module( listen { val mapStates = entitySearch(128.0) .mapNotNull { FilledMapItem.getMapState(it.heldItemStack, world) } + - PlayerContainer.stacks.mapNotNull { FilledMapItem.getMapState(it, world) } + findStacks(containerSelection = ContainerSelection.PLAYER) + .mapNotNull { FilledMapItem.getMapState(it, world) } mapStates.forEach { map -> val name = map.hash diff --git a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt index de229a0ff..d19eec4f0 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Nuker.kt @@ -17,9 +17,9 @@ package com.lambda.module.modules.world -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editTypedSettings -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.withEdits import com.lambda.context.SafeContext import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint diff --git a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt index 016ed4a3a..a8284547c 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Printer.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Printer.kt @@ -19,9 +19,9 @@ package com.lambda.module.modules.world import com.lambda.Lambda.mc import com.lambda.config.Group -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.blocks.WorldLineSettings -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.forEachSetting import com.lambda.config.hideAllExcept import com.lambda.config.withEdits diff --git a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt index 85f99e94f..7354bf66e 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/Scaffold.kt @@ -17,7 +17,7 @@ package com.lambda.module.modules.world -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editSetting import com.lambda.config.editTypedSettings import com.lambda.config.hide @@ -31,7 +31,7 @@ import com.lambda.interaction.construction.simulation.context.BuildContext import com.lambda.interaction.construction.simulation.sim import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.containers.HotbarContainer -import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.selectStack +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.manager.managers.interacting.interactRequest import com.lambda.module.Module import com.lambda.module.ModuleTag @@ -74,8 +74,8 @@ object Scaffold : Module( } listen { - val selection = selectStack { - custom { stack, _ -> + val selection = stackSelection { + predicate { stack, _ -> stack.blockItem.let { blockItem -> blockItem != null && blockItem.block !in blacklistedBlocks } } } diff --git a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt index 06f603307..4c29df3f8 100644 --- a/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt +++ b/src/main/kotlin/com/lambda/module/modules/world/StashMover.kt @@ -20,9 +20,9 @@ package com.lambda.module.modules.world import baritone.api.pathing.goals.GoalBlock import com.lambda.Lambda.mc import com.lambda.config.Tab -import com.lambda.config.automation.AutomationConfig.Companion.setDefaultAutomationConfig +import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editTypedSettings -import com.lambda.config.entries.Setting.Companion.onValueChange +import com.lambda.config.entries.onValueChange import com.lambda.config.hide import com.lambda.config.hideBlock import com.lambda.config.settings.complex.Bind @@ -42,7 +42,13 @@ import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer import com.lambda.interaction.container.containers.OffHandContainer import com.lambda.interaction.container.containers.external.EnderChestContainer +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.findContainers +import com.lambda.interaction.handler.handlers.findSlots +import com.lambda.interaction.handler.handlers.findStack +import com.lambda.interaction.handler.handlers.findStacks import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.interaction.manager.managers.rotating.Rotation @@ -454,7 +460,9 @@ object StashMover : Module( MoverState.DispensingPearl -> handleDispensingPearl() MoverState.AwaitingPearl -> checkTimerProgress(MoverState.DispensingPearl, pearlButtonTimeout) { - if (HotbarAndInventoryContainer.stacks.any { it.item === Items.ENDER_PEARL }) { + val hasPearl = findContainers(containerSelection = ContainerSelection.HOTBAR_AND_INVENTORY) + .any { it.stacks.any { it.item == Items.ENDER_PEARL } } + if (hasPearl) { pearlThrown = false moverState = MoverState.ThrowingPearl true @@ -501,7 +509,7 @@ object StashMover : Module( if (moverState != MoverState.AwaitingTeleport) return@listen val packet = event.packet if (packet !is PlayerPositionLookS2CPacket) return@listen - if (finished && HotbarAndInventoryContainer.stacks.all { it.isEmpty }) { + if (finished && findStacks(containerSelection = ContainerSelection.HOTBAR_AND_INVENTORY).all { it.isEmpty }) { success(finishedMessage) return@listen } @@ -520,12 +528,17 @@ object StashMover : Module( moverState = MoverState.OpeningPullContainer return } - if (!moveFromContainerToContainer(screenHandler.containerSlots, HotbarAndInventoryContainer.stacks)) return + val move = + moveFromContainerToContainer( + screenHandler.containerSlots, + findStacks(containerSelection = ContainerSelection.HOTBAR_AND_INVENTORY).toList() + ) + if (!move) return pullContainer?.let { container -> if (screenHandler.containerStacks.all { it.isEmpty }) { pullContainers.remove(container) pulledContainers.add(container) - if (HotbarAndInventoryContainer.stacks.any { it.isEmpty }) { + if (findStack(stackSelection { isEmpty() }, ContainerSelection.HOTBAR_AND_INVENTORY) != null) { moverState = MoverState.OpeningPullContainer return } @@ -543,7 +556,12 @@ object StashMover : Module( moverState = MoverState.OpeningPutEnderChest return } - if (moveFromContainerToContainer(HotbarAndInventoryContainer.slots, screenHandler.containerStacks)) { + val move = + moveFromContainerToContainer( + findSlots(containerSelection = ContainerSelection.HOTBAR_AND_INVENTORY).toList(), + screenHandler.containerStacks + ) + if (move) { moverState = MoverState.OpeningPullContainer } } @@ -580,7 +598,7 @@ object StashMover : Module( rotation(rotation) }.submit() if (!rotationRequest.done || rotation dist RotationManager.serverRotation > 0.001) return - val throwSlots = HotbarAndInventoryContainer.slots.filter { !it.stack.isEmpty } + val throwSlots = findSlots(stackSelection { notEmpty() }, ContainerSelection.HOTBAR_AND_INVENTORY).toList() if (throwSlots.isNotEmpty()) { val inventoryRequest = inventoryRequest(settleForLess = true) { throwSlots.forEach { slot -> @@ -597,12 +615,17 @@ object StashMover : Module( moverState = MoverState.OpeningPutContainer return } - if (!moveFromContainerToContainer(HotbarAndInventoryContainer.slots, screenHandler.containerStacks)) return + val move = + moveFromContainerToContainer( + findSlots(containerSelection = ContainerSelection.HOTBAR_AND_INVENTORY).toList(), + screenHandler.containerStacks + ) + if (!move) return putContainer?.let { container -> if (screenHandler.containerStacks.all { !it.isEmpty }) { putContainers.remove(container) filledContainers.add(container) - if (HotbarAndInventoryContainer.stacks.any { !it.isEmpty }) { + if (findStack(stackSelection { notEmpty() }, ContainerSelection.HOTBAR_AND_INVENTORY) != null) { moverState = MoverState.OpeningPutContainer return } @@ -616,7 +639,12 @@ object StashMover : Module( moverState = MoverState.OpeningPullEnderChest return } - if (moveFromContainerToContainer(screenHandler.containerSlots, HotbarAndInventoryContainer.stacks)) { + val move = + moveFromContainerToContainer( + screenHandler.containerSlots, + findStacks(containerSelection = ContainerSelection.HOTBAR_AND_INVENTORY).toList() + ) + if (move) { putOrThrowItems() } } @@ -659,7 +687,7 @@ object StashMover : Module( if (pearlThrown) { if (!player.offHandStack.isEmpty) { - if (HotbarAndInventoryContainer.stacks.none { it.isEmpty }) { + if (findStack(stackSelection { isEmpty() }, ContainerSelection.HOTBAR_AND_INVENTORY) == null) { failWithLog("No free slots to return the offhand stack to!", ::failure) return } diff --git a/src/main/kotlin/com/lambda/network/CapeHandler.kt b/src/main/kotlin/com/lambda/network/CapeHandler.kt index e92ba1540..241c1f653 100644 --- a/src/main/kotlin/com/lambda/network/CapeHandler.kt +++ b/src/main/kotlin/com/lambda/network/CapeHandler.kt @@ -21,7 +21,7 @@ import com.lambda.Lambda.LOG import com.lambda.Lambda.mc import com.lambda.config.Config import com.lambda.config.categories.SecretsCategory -import com.lambda.config.entries.Setting.Companion.onValueChangeUnsafe +import com.lambda.config.entries.onValueChangeUnsafe import com.lambda.core.Loadable import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt index 6602dc3f6..3547c047d 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquirePlacedBlockTask.kt @@ -21,8 +21,8 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.containers.ArmorContainer.findSlot import com.lambda.interaction.container.selection.select -import com.lambda.interaction.handler.handlers.findSlots import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.wrappers.softFail @@ -48,15 +48,12 @@ class AcquirePlacedBlockTask @Ta5kBuilder internal constructor( init { listen { runSafeAutomated { - block.item - .select(1) - .findSlots() - .firstOrNull()?.let { slot -> - PlaceContainerTask(slot, this) - .onSuccess { success(it) } - .execute(this@AcquirePlacedBlockTask) - return@listen - } + findSlot(block.item.select()).let { slot -> + PlaceContainerTask(slot, this) + .onSuccess { success(it) } + .execute(this@AcquirePlacedBlockTask) + return@listen + } } failure("No $block found in range or hotbar/inventory!") diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index e8db24cd2..0f95dc667 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -21,7 +21,7 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.selection.StackSelection -import com.lambda.interaction.handler.handlers.findContainer +import com.lambda.interaction.container.selection.select import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.threading.runSafeAutomated @@ -46,11 +46,9 @@ class AcquireStackTask @Ta5kBuilder internal constructor( override fun SafeContext.onStart() { runSafeAutomated { - selection.findContainer() - ?.let { transfer(selection, it, HotbarContainer) } - ?.onSuccess { slot -> success(slot) } - ?.start() - ?: failure(NoContainerFound(selection)) // ToDo: Create crafting path + selection.transfer(toSelection = HotbarContainer.select()) + .onSuccess { slot -> success(slot) } + .start() } } } diff --git a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt index 5ae1d61ba..cae228e6a 100644 --- a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt @@ -22,7 +22,10 @@ import com.lambda.context.Automated import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.handler.handlers.BaritoneHandler +import com.lambda.interaction.handler.handlers.findStack import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder @@ -64,7 +67,7 @@ class CollectDropsTask @Ta5kBuilder internal constructor( return@listen } - if (HotbarAndInventoryContainer.stacks.none { it.isEmpty }) { + if (findStack(stackSelection { isEmpty() }, ContainerSelection.HOTBAR_AND_INVENTORY) == null) { val stackToThrow = player.currentScreenHandler.playerSlots.firstOrNull { it.stack.item in inventoryConfig.disposables diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index fc674267b..a8036ebe4 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -25,6 +25,7 @@ import com.lambda.interaction.container.Container import com.lambda.interaction.container.ExternalContainer import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.selection.ContainerSelection +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.mutate import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.mutate import com.lambda.interaction.handler.handlers.findContainers @@ -40,50 +41,58 @@ import net.minecraft.screen.slot.Slot context(automated: Automated) fun transfer( selection: StackSelection, - fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, + fromSelection: ContainerSelection = ContainerSelection.ACCESSED, toSelection: ContainerSelection, - toStack: StackSelection = StackSelection.EVERYTHING + toStack: StackSelection = StackSelection.ANYTHING ) = ContainerTransferTask(selection, fromSelection, toSelection, toStack, automated) @Ta5kBuilder @JvmName("transferExt") context(automated: Automated) fun StackSelection.transfer( - fromSelection: ContainerSelection = ContainerSelection.EVERYTHING, + fromSelection: ContainerSelection = ContainerSelection.ACCESSED, toSelection: ContainerSelection, - toStack: StackSelection = StackSelection.EVERYTHING + toStack: StackSelection = StackSelection.ANYTHING ) = transfer(this, fromSelection, toSelection, toStack) class ContainerTransferTask @Ta5kBuilder internal constructor( - private val selection: StackSelection, + private val fromStack: StackSelection, private val fromSelection: ContainerSelection, private val toSelection: ContainerSelection, private val toStack: StackSelection, automated: Automated ) : Task(), Automated by automated { - override val name = "Transferring $selection from $fromSelection to $toSelection" + override val name = "Transferring $fromStack from $fromSelection to $toSelection" override fun SafeContext.onStart() { - val singleSelection = selection.mutate(count = if (selection.count == 0) 0 else 1) + val singleSelection = fromStack.mutate(count = if (fromStack.count == 0) 0 else 1) - val fromContainers = findContainers(singleSelection, fromSelection).toList() - val toContainers = findContainers(toStack, toSelection) - .filter { toStack !== StackSelection.EVERYTHING || it.spaceLeft(singleSelection) > 0 } - .toList() + val fromContainers = + findContainers( + fromSelection.mutate { + hasStack(fromStack) + } + ).toList() + val toContainers = + findContainers( + toSelection.mutate { + hasStack(toStack) + } + ).toList() if (fromContainers.isEmpty()) { - failure(IllegalStateException("Could not find any container to pull $selection from")) + failure(IllegalStateException("Could not find any container to pull $fromStack from")) return } if (toContainers.isEmpty()) { - failure(IllegalStateException("Could not find any container with space to push $selection to")) + failure(IllegalStateException("Could not find any container with space to push $fromStack to")) return } - if (selection.count > 0) { + if (fromStack.count > 0) { val totalAvailable = fromContainers.sumOf { it.count(singleSelection) } - if (totalAvailable < selection.count) { - failure(IllegalStateException("Not enough items across all containers to pull $selection")) + if (totalAvailable < fromStack.count) { + failure(IllegalStateException("Not enough items across all containers to pull $fromStack")) return } } @@ -105,7 +114,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( else -> taskOrNull { fromContainer.access() } .then { fromCtx -> - transfer(selection, fromSelection, ContainerSelection.HOTBAR_AND_INVENTORY) + transfer(fromStack, fromSelection, ContainerSelection.HOTBAR_AND_INVENTORY) .thenOrNull { fromCtx?.close() } } .thenOrNull { toContainer.access() } @@ -114,7 +123,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( } /** - * Opens [containerToOpen], transfers [selection] from [from] to [to], then closes the opened container. + * Opens [containerToOpen], transfers [fromStack] from [from] to [to], then closes the opened container. * * Used when exactly one of the two containers is external and needs to be accessed. */ @@ -128,14 +137,14 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( ?.then { ctx -> transferAndClose(ctx, fromSelection, toSelection) } /** - * Transfers [selection] from [from] to [to], then closes the container via [ctx]. + * Transfers [fromStack] from [from] to [to], then closes the container via [ctx]. */ @Ta5kBuilder private fun transferAndClose( ctx: OpenedContainerContext?, fromSelection: ContainerSelection, toSelection: ContainerSelection - ) = transfer(selection, fromSelection, toSelection) + ) = transfer(fromStack, fromSelection, toSelection) .thenOrNull { slot -> ctx ?.close() @@ -154,8 +163,8 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( init { listen { runSafeAutomated { - while (selection.count == 0 || transferred < selection.count) { - val currentSelection = selection.mutate(count = if (selection.count == 0) 0 else selection.count - transferred) + while (fromStack.count == 0 || transferred < fromStack.count) { + val currentSelection = fromStack.mutate(count = if (fromStack.count == 0) 0 else fromStack.count - transferred) var fromSlot: Slot? = null var toSlot: Slot? = null @@ -178,7 +187,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( if (fromSlot == null || toSlot == null || fromContainer == null || toContainer == null) { lastSlot?.let { slot -> - if (selection.count == 0 || transferred >= selection.count) { + if (fromStack.count == 0 || transferred >= fromStack.count) { success(slot) return@listen } @@ -187,7 +196,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( return@listen } - val moveCount = minOf(fromSlot.stack.count, if (selection.count == 0) Int.MAX_VALUE else selection.count - transferred) + val moveCount = minOf(fromSlot.stack.count, if (fromStack.count == 0) Int.MAX_VALUE else fromStack.count - transferred) if (!fromContainer.swap(fromSlot, toSlot, toContainer)) { checkFail() return@listen @@ -197,7 +206,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( lastSlot = toSlot // count == 0 means single stack transfer - if (selection.count == 0) { + if (fromStack.count == 0) { success(toSlot) return@listen } @@ -209,7 +218,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( } private fun checkFail() { - failure(IllegalStateException("Unable to access $selection")) + failure(IllegalStateException("Unable to access $fromStack")) } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index 088a8e79c..1e987d79e 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -25,6 +25,7 @@ import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.containers.InventoryContainer +import com.lambda.interaction.container.selection.select import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder @@ -72,7 +73,12 @@ class EatTask @Ta5kBuilder internal constructor( } else { if (InventoryContainer.slots.any { selection.matches(it) }) { runSafeAutomated { - transfer(selection, InventoryContainer, HotbarContainer) + transfer( + selection, + InventoryContainer.select(), + HotbarContainer.select() + ).start() + return@listen } } if (holdingUse) { From d9efa6d6d11e6ac3be8f014d06aaeb02d4c9cbcc Mon Sep 17 00:00:00 2001 From: beanbag44 <107891830+beanbag44@users.noreply.github.com> Date: Sat, 12 Sep 2026 20:20:27 +0100 Subject: [PATCH 16/18] improvements --- .../EnderChestContainerSerializer.kt | 21 +- .../lambda/interaction/container/Container.kt | 7 +- ...ntainerMarker.kt => ContainerDslMarker.kt} | 2 +- .../container/OpenContainerTask.kt | 10 - .../external/EnderChestContainer.kt | 4 +- .../external/ShulkerBoxContainer.kt | 8 +- .../container/selection/ContainerSelection.kt | 73 +++- .../container/selection/StackSelection.kt | 128 +++---- .../handler/handlers/ContainerHandler.kt | 38 +- .../module/modules/player/InventoryTweaks.kt | 5 +- src/main/kotlin/com/lambda/task/Task.kt | 84 ++--- .../com/lambda/task/tasks/AcquireStackTask.kt | 7 +- .../kotlin/com/lambda/task/tasks/BuildTask.kt | 4 +- .../com/lambda/task/tasks/CollectDropsTask.kt | 58 +-- .../task/tasks/ContainerTransferTask.kt | 332 +++++++++++------- .../lambda/task/tasks/wrappers/ActionTasks.kt | 2 +- 16 files changed, 463 insertions(+), 320 deletions(-) rename src/main/kotlin/com/lambda/interaction/container/{ContainerMarker.kt => ContainerDslMarker.kt} (95%) diff --git a/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt b/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt index a62b83044..8601077c5 100644 --- a/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt +++ b/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt @@ -52,16 +52,21 @@ object EnderChestContainerSerializer : Serializer(EnderChes } object EnderChestContainerDeserializer : Deserializer(EnderChestContainer::class.java) { - override fun deserialize(p: JsonParser, ctxt: DeserializationContext): EnderChestContainer { + override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): EnderChestContainer? { + throw initFromJsonException("EnderChestContainer") + } + + override fun deserialize(p: JsonParser, ctxt: DeserializationContext, intoValue: EnderChestContainer): EnderChestContainer { val root = p.readValueAsTree() val stackArray = root.get("Stacks") as? ArrayNode - val stacks = stackArray?.mapNotNull { element -> - ItemStack.CODEC - .parse(JsonOps.UNCOMPRESSED, element) - .result() - .orElse(null) - } ?: emptyList() - + val stacks = + stackArray?.mapNotNull { element -> + ItemStack.CODEC + .parse(JsonOps.UNCOMPRESSED, element) + .result() + .orElse(null) + } ?: emptyList() + EnderChestContainer.update(stacks) EnderChestContainer.scanStacksForNestedContainers() return EnderChestContainer diff --git a/src/main/kotlin/com/lambda/interaction/container/Container.kt b/src/main/kotlin/com/lambda/interaction/container/Container.kt index 4195e1134..6ffecb4a6 100644 --- a/src/main/kotlin/com/lambda/interaction/container/Container.kt +++ b/src/main/kotlin/com/lambda/interaction/container/Container.kt @@ -121,8 +121,7 @@ abstract class Container( @Ta5kBuilder context(automated: Automated) - open fun access(): OpenContainerTask<*>? = - PlayerOpenContainerTask(description, ::isAccessed) + open fun access(): OpenContainerTask<*>? = null open fun count(selection: StackSelection) = slots.takeUnless { it.isEmpty() }?.let { selection.filter(it).count } @@ -145,12 +144,12 @@ abstract class Container( selection: StackSelection, toContainer: Container, toStackSelection: StackSelection = StackSelection.ANYTHING - ) = Pair(findSlot(selection), toContainer.findReplaceSlot(toStackSelection)) + ) = Pair(selection.filter(slots).firstOrNull(), toContainer.findReplaceSlot(toStackSelection)) context(_: Automated) open fun findReplaceSlot( selection: StackSelection = StackSelection.ANYTHING - ) = findSlots(selection) + ) = selection.filter(slots) .sortedWith(replaceSorter) .firstOrNull() diff --git a/src/main/kotlin/com/lambda/interaction/container/ContainerMarker.kt b/src/main/kotlin/com/lambda/interaction/container/ContainerDslMarker.kt similarity index 95% rename from src/main/kotlin/com/lambda/interaction/container/ContainerMarker.kt rename to src/main/kotlin/com/lambda/interaction/container/ContainerDslMarker.kt index 9b56dc2c7..9269e464e 100644 --- a/src/main/kotlin/com/lambda/interaction/container/ContainerMarker.kt +++ b/src/main/kotlin/com/lambda/interaction/container/ContainerDslMarker.kt @@ -18,4 +18,4 @@ package com.lambda.interaction.container @DslMarker -annotation class ContainerMarker \ No newline at end of file +annotation class ContainerDslMarker \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/container/OpenContainerTask.kt b/src/main/kotlin/com/lambda/interaction/container/OpenContainerTask.kt index 61a07e5d7..27cc94c61 100644 --- a/src/main/kotlin/com/lambda/interaction/container/OpenContainerTask.kt +++ b/src/main/kotlin/com/lambda/interaction/container/OpenContainerTask.kt @@ -17,7 +17,6 @@ package com.lambda.interaction.container -import com.lambda.context.SafeContext import com.lambda.task.Task import net.minecraft.text.Text @@ -25,13 +24,4 @@ abstract class OpenContainerTask @Ta5kBuilder intern description: Text ) : Task() { override val name = "accessing container: ${description.string}" -} - -class PlayerOpenContainerTask @Ta5kBuilder internal constructor( - description: Text, - private val isAccessed: () -> Boolean -) : OpenContainerTask(description) { - override fun SafeContext.onStart() { - success(BasicOpenedContainerContext(isAccessed)) - } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/external/EnderChestContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/EnderChestContainer.kt index 925cf1aaa..da40583bb 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/external/EnderChestContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/EnderChestContainer.kt @@ -25,8 +25,10 @@ import com.lambda.interaction.container.ContainerType import com.lambda.interaction.container.ExternalContainer import com.lambda.interaction.container.OpenContainerTask import com.lambda.interaction.container.OpenedContainerContext +import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.selection.select import com.lambda.interaction.handler.handlers.ContainerHandler.lastInteractedBlockEntity +import com.lambda.interaction.handler.handlers.findSlot import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.acquireStack import com.lambda.task.tasks.breakAndCollect @@ -83,7 +85,7 @@ object EnderChestContainer : Container(ContainerType.EnderChest), ExternalContai }, onFailure = { acquireStack(Items.ENDER_CHEST.select(1)) - .then { placeContainer(it) } + .then { placeContainer(findSlot(it, HotbarContainer.select())) } .then { pos -> openContainer(pos).onSuccess { success(OpenedEnderChestContext(pos)) diff --git a/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt index 99ec23127..9a61e1a27 100644 --- a/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt +++ b/src/main/kotlin/com/lambda/interaction/container/containers/external/ShulkerBoxContainer.kt @@ -30,6 +30,8 @@ import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.interaction.container.selection.select +import com.lambda.interaction.handler.handlers.ContainerSearchScope +import com.lambda.interaction.handler.handlers.findSlot import com.lambda.task.Task.Ta5kBuilder import com.lambda.task.tasks.breakAndCollect import com.lambda.task.tasks.openContainer @@ -79,10 +81,10 @@ data class ShulkerBoxContainer( ) : OpenContainerTask(description), Automated by automated { override fun SafeContext.onStart() { transfer( - stackSelection { inIndex(index); isItem(shulkerItem) }, + stackSelection { predicate { _, slot -> slot?.index == index }; isItem(shulkerItem) }, containedIn.select(), HotbarContainer.select() - ).then { slot -> placeContainer(slot) } + ).then { result -> placeContainer(findSlot(result.stackSelection, result.containerSelection)) } .then { pos -> openContainer(pos).onSuccess { success(OpenedShulkerBoxContext(pos, containedIn)) @@ -109,7 +111,7 @@ data class ShulkerBoxContainer( sortedByBestContentMatch(stacks) }.transfer( ContainerSelection.HOTBAR_AND_INVENTORY, - fromContainer.select() + fromContainer.select(ContainerSearchScope.Loaded) ) } } diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt index 9fbb794ea..3316a6afb 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt @@ -18,7 +18,7 @@ package com.lambda.interaction.container.selection import com.lambda.interaction.container.Container -import com.lambda.interaction.container.ContainerMarker +import com.lambda.interaction.container.ContainerDslMarker import com.lambda.interaction.container.ContainerType import com.lambda.interaction.container.NestedContainer import com.lambda.interaction.container.containers.ArmorContainer @@ -30,12 +30,17 @@ import com.lambda.interaction.container.containers.OffHandContainer import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection import com.lambda.interaction.handler.handlers.ContainerSearchScope -@ContainerMarker +@ContainerDslMarker fun Container.select( scope: ContainerSearchScope = ContainerSearchScope.Accessed ) = containerSelection(scope) { ofAny(this@select) } -@ContainerMarker +@ContainerDslMarker +fun Iterable.select( + scope: ContainerSearchScope = ContainerSearchScope.Accessed +) = containerSelection(scope) { ofAny(this@select) } + +@ContainerDslMarker fun selectContainers( vararg containers: Container, scope: ContainerSearchScope = ContainerSearchScope.Accessed @@ -45,21 +50,22 @@ fun selectContainers( * ContainerSelection is a class that holds a predicate for matching containers. */ @Suppress("unused") -class ContainerSelection @ContainerMarker internal constructor( +class ContainerSelection @ContainerDslMarker internal constructor( val selector: (Container) -> Boolean, val scope: ContainerSearchScope = ContainerSearchScope.Accessed, val containersWhitelist: Collection = emptyList(), + val loadedContainers: Collection = emptyList(), val containersBlacklist: Collection = emptyList(), val accessScope: AccessScope = AccessScope.Both, val comparator: Comparator = compareBy { it.type } ) { - @ContainerMarker + @ContainerDslMarker fun bestMatch(containers: Iterable) = filter(containers).firstOrNull() - @ContainerMarker + @ContainerDslMarker fun matches(container: Container): Boolean = selector(container) - @ContainerMarker + @ContainerDslMarker fun filter(containers: Iterable) = run { containersWhitelist @@ -89,11 +95,11 @@ class ContainerSelection @ContainerMarker internal constructor( } @Suppress("unused") -@ContainerMarker -class ContainerSelectionBuilder @ContainerMarker private constructor( +@ContainerDslMarker +class ContainerSelectionBuilder @ContainerDslMarker private constructor( private val scope: ContainerSearchScope ) { - @ContainerMarker + @ContainerDslMarker private constructor( selection: ContainerSelection, scope: ContainerSearchScope @@ -107,12 +113,28 @@ class ContainerSelectionBuilder @ContainerMarker private constructor( private var selector: (Container) -> Boolean = { true } private val containersWhitelist = mutableListOf() + private val loadedContainers = mutableListOf() private val containersBlacklist = mutableListOf() private var accessScope: AccessScope = AccessScope.Both private var comparator: Comparator = compareBy { it.type } + fun withContainers(vararg containers: Container) { + loadedContainers.addAll(containers) + } + + fun withContainers(containers: Iterable) { + loadedContainers.addAll(containers) + } + fun ofAny(vararg containers: Container) { containersWhitelist.addAll(containers) + withContainers(*containers) + appendSelector { container -> container in containersWhitelist } + } + + fun ofAny(containers: Iterable) { + containersWhitelist.addAll(containers) + withContainers(containers) appendSelector { container -> container in containersWhitelist } } @@ -121,14 +143,27 @@ class ContainerSelectionBuilder @ContainerMarker private constructor( appendSelector { container -> container !in containersBlacklist } } + fun noneOf(containers: Iterable) { + containersBlacklist.addAll(containers) + appendSelector { container -> container !in containersBlacklist } + } + fun ofAnyType(vararg types: ContainerType) { appendSelector { container -> types.contains(container.type) } } + fun ofAnyType(types: Iterable) { + appendSelector { container -> types.contains(container.type) } + } + fun noneOfType(vararg types: ContainerType) { appendSelector { container -> !types.contains(container.type) } } + fun noneOfType(types: Iterable) { + appendSelector { container -> !types.contains(container.type) } + } + fun isNested() { appendSelector { container -> container is NestedContainer } } @@ -184,10 +219,20 @@ class ContainerSelectionBuilder @ContainerMarker private constructor( } private fun appendSelector(selector: (Container) -> Boolean) { - this.selector = { this.selector(it) && selector(it) } - } - - private fun build() = ContainerSelection(selector, scope, containersWhitelist, containersBlacklist, accessScope, comparator) + val currentSelector = this.selector + this.selector = { currentSelector(it) && selector(it) } + } + + private fun build() = + ContainerSelection( + selector, + scope, + containersWhitelist, + loadedContainers, + containersBlacklist, + accessScope, + comparator + ) companion object { fun containerSelection( diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt index 262ff755b..19716278e 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt @@ -15,15 +15,16 @@ * along with this program. If not, see . */ +@file:Suppress("unused") + package com.lambda.interaction.container.selection import com.lambda.interaction.container.Container -import com.lambda.interaction.container.ContainerMarker +import com.lambda.interaction.container.ContainerDslMarker import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection import com.lambda.util.EnchantmentUtils.getEnchantment import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils -import com.lambda.util.player.SlotUtils.matches import net.minecraft.block.Block import net.minecraft.block.BlockState import net.minecraft.component.ComponentType @@ -37,16 +38,16 @@ import net.minecraft.registry.tag.TagKey import net.minecraft.screen.slot.Slot import java.util.* -@ContainerMarker -fun Item.select(count: Int = 0) = stackSelection(count) { isItem(this@select) } +@ContainerDslMarker +fun Item.select(count: Int = 1) = stackSelection(count) { isItem(this@select) } -@ContainerMarker -fun ItemStack.select(count: Int = 0) = stackSelection(count) { isItemStack(this@select) } +@ContainerDslMarker +fun ItemStack.select(count: Int = 1) = stackSelection(count) { isItemStack(this@select) } -class StackSelection @ContainerMarker internal constructor( +class StackSelection @ContainerDslMarker internal constructor( + val count: Int = 1, val whitelistedSlots: Collection = emptyList(), val blacklistedSlots: Collection = emptyList(), - val count: Int = 0, val item: Item? = null, val itemStack: ItemStack? = null, val shulkerBoxScope: ShulkerBoxScope = ShulkerBoxScope.Both, @@ -55,23 +56,33 @@ class StackSelection @ContainerMarker internal constructor( ) { val optimalStack = itemStack ?: item?.let { ItemStack(it, count) } - @ContainerMarker + @ContainerDslMarker fun bestMatch(stacks: Iterable) = filter(stacks).firstOrNull() - @ContainerMarker + @ContainerDslMarker fun bestMatch(slots: Iterable) = filter(slots).firstOrNull() - @ContainerMarker - fun matches(stack: ItemStack) = - shulkerBoxScope.inShulkerBox?.equals(stack.shulkerBoxStacks.any { selector(it, null) }) != false || - selector(stack, null) + @ContainerDslMarker + fun matches(stack: ItemStack): Boolean { + val matchesSelf = selector(stack, null) + return when (shulkerBoxScope.inShulkerBox) { + true -> stack.shulkerBoxStacks.any { selector(it, null) } + false -> matchesSelf + null -> matchesSelf || stack.shulkerBoxStacks.any { selector(it, null) } + } + } - @ContainerMarker - fun matches(slot: Slot): Boolean = - shulkerBoxScope.inShulkerBox?.equals(slot.stack.shulkerBoxStacks.any { selector(it, null) }) != false || - selector(slot.stack, slot) + @ContainerDslMarker + fun matches(slot: Slot): Boolean { + val matchesSelf = selector(slot.stack, slot) + return when (shulkerBoxScope.inShulkerBox) { + true -> slot.stack.shulkerBoxStacks.any { selector(it, null) } + false -> matchesSelf + null -> matchesSelf || slot.stack.shulkerBoxStacks.any { selector(it, null) } + } + } - @ContainerMarker + @ContainerDslMarker @JvmName("filter1") fun filter(stacks: Iterable) = stacks @@ -83,7 +94,7 @@ class StackSelection @ContainerMarker internal constructor( .map { it.stack } .toList() - @ContainerMarker + @ContainerDslMarker @JvmName("filter2") fun filter(slots: Iterable) = slots @@ -101,25 +112,39 @@ class StackSelection @ContainerMarker internal constructor( .map { it.slot } .toList() - @ContainerMarker + @ContainerDslMarker infix fun isIn(container: Container) = container.count(this) >= count - @ContainerMarker + @ContainerDslMarker + fun isIn(vararg containers: Container) = + containers.sumOf { it.count(this) } >= count + + @ContainerDslMarker + infix fun isIn(containers: Iterable) = + containers.sumOf { it.count(this) } >= count + + @ContainerDslMarker infix fun spaceIn(container: Container) = container.spaceLeft(this) >= count - @Suppress("unused") + @ContainerDslMarker + fun spaceIn(vararg containers: Container) = + containers.sumOf { it.spaceLeft(this) } >= count + + @ContainerDslMarker + infix fun spaceIn(containers: Iterable) = + containers.sumOf { it.spaceLeft(this) } >= count + companion object { - val ANYTHING = StackSelection { _, _ -> true } + val ANYTHING = StackSelection(0) { _, _ -> true } val NOTHING = StackSelection { _, _ -> false } } } -@Suppress("unused") -@ContainerMarker -class StackSelectionBuilder @ContainerMarker private constructor( - private var count: Int = 0 +@ContainerDslMarker +class StackSelectionBuilder @ContainerDslMarker private constructor( + private var count: Int = 1 ) { private val whitelistedSlots = mutableListOf() private val blacklistedSlots = mutableListOf() @@ -129,7 +154,7 @@ class StackSelectionBuilder @ContainerMarker private constructor( private var comparator: Comparator>? = null private var shulkerBoxScope: ShulkerBoxScope = ShulkerBoxScope.NotInShulkerBox - @ContainerMarker + @ContainerDslMarker private constructor( selection: StackSelection, count: Int = selection.count @@ -188,11 +213,11 @@ class StackSelectionBuilder @ContainerMarker private constructor( shulkerBoxScope = ShulkerBoxScope.InShulkerBox } - fun ofAnyItems(items: Collection) { + fun ofAnyItems(items: Iterable) { appendSelector { stack, _ -> items.contains(stack.item) } } - fun noneOfItems(items: Collection) { + fun noneOfItems(items: Iterable) { appendSelector { stack, _ -> !items.contains(stack.item) } } @@ -212,11 +237,11 @@ class StackSelectionBuilder @ContainerMarker private constructor( appendSelector { stack, _ -> stack.name.string != name } } - fun ofAnyStacks(stacks: Collection) { + fun ofAnyStacks(stacks: Iterable) { appendSelector { stack, _ -> stacks.contains(stack) } } - fun noneOfStacks(stacks: Collection) { + fun noneOfStacks(stacks: Iterable) { appendSelector { stack, _ -> !stacks.contains(stack) } } @@ -315,37 +340,11 @@ class StackSelectionBuilder @ContainerMarker private constructor( } fun isEmpty() { - appendSelector { stack, _ -> stack.isEmpty} + appendSelector { stack, _ -> stack.isEmpty } } fun notEmpty() { - appendSelector { stack, _ -> !stack.isEmpty} - } - - fun isSlot(slot: Slot) { - appendSelector { _, s -> s != null && s matches slot } - } - - fun notSlot(slot: Slot) { - appendSelector { _, s -> s == null || !s.matches(slot) } - } - - fun isSlotByReference(slot: Slot) { - whitelistedSlots.add(slot) - appendSelector { _, s -> s === slot } - } - - fun notSlotByReference(slot: Slot) { - blacklistedSlots.add(slot) - appendSelector { _, s -> s !== slot } - } - - fun inIndex(index: Int) { - appendSelector { _, s -> s?.index == index } - } - - fun notInIndex(index: Int) { - appendSelector { _, s -> s?.index != index } + appendSelector { stack, _ -> !stack.isEmpty } } fun predicate(predicate: (ItemStack, Slot?) -> Boolean) { @@ -380,16 +379,17 @@ class StackSelectionBuilder @ContainerMarker private constructor( @PublishedApi internal fun appendSelector(selector: (ItemStack, Slot?) -> Boolean) { + val currentSelector = this.selector this.selector = { stack, slot -> - this.selector(stack, slot) && selector(stack, slot) + currentSelector(stack, slot) && selector(stack, slot) } } private fun build() = StackSelection( + count, whitelistedSlots, blacklistedSlots, - count, item, itemStack, shulkerBoxScope, @@ -401,7 +401,7 @@ class StackSelectionBuilder @ContainerMarker private constructor( private val efficientToolCache = Collections.synchronizedMap(mutableMapOf()) fun stackSelection( - count: Int = 0, + count: Int = 1, builder: StackSelectionBuilder.() -> Unit ) = StackSelectionBuilder(count).apply(builder).build() diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index ca19ef387..08c4ee113 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -27,7 +27,7 @@ import com.lambda.event.events.PacketEvent import com.lambda.event.events.WorldEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.Container -import com.lambda.interaction.container.ContainerMarker +import com.lambda.interaction.container.ContainerDslMarker import com.lambda.interaction.container.ContainerSerializer import com.lambda.interaction.container.PlacedContainer import com.lambda.interaction.container.containers.external.ChestContainer @@ -235,7 +235,7 @@ object ContainerHandler : Loadable { private fun Inventory.stacks() = iterator().asSequence().toList() } -@ContainerMarker +@ContainerDslMarker context(_: AutomatedSafeContext) fun StackSelection.move( fromSelection: ContainerSelection = ContainerSelection.ACCESSED, @@ -268,7 +268,7 @@ fun StackSelection.move( return fromContainer.swap(fromSlot, toSlot, toContainer) } -@ContainerMarker +@ContainerDslMarker context(automated: Automated) fun findSlot( stackSelection: StackSelection = StackSelection.ANYTHING, @@ -277,13 +277,13 @@ fun findSlot( ) = findSlots(stackSelection, containerSelection, sorted) .firstOrNull() -@ContainerMarker +@ContainerDslMarker context(automated: Automated) fun findSlots( stackSelection: StackSelection = StackSelection.ANYTHING, containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = searchContainers(containerSelection.scope) +) = searchContainers(containerSelection) .filter { containerSelection.matches(it) } .let { if (sorted) it.sorted() @@ -296,7 +296,7 @@ fun findSlots( } .flatten() -@ContainerMarker +@ContainerDslMarker context(automated: Automated) fun findStack( stackSelection: StackSelection = StackSelection.ANYTHING, @@ -305,13 +305,13 @@ fun findStack( ) = findStacks(stackSelection, containerSelection, sorted) .firstOrNull() -@ContainerMarker +@ContainerDslMarker context(automated: Automated) fun findStacks( stackSelection: StackSelection = StackSelection.ANYTHING, containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = searchContainers(containerSelection.scope) +) = searchContainers(containerSelection) .filter { containerSelection.matches(it) } .let { if (sorted) it.sorted() @@ -324,7 +324,7 @@ fun findStacks( } .flatten() -@ContainerMarker +@ContainerDslMarker context(_: Automated) fun findContainer( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, @@ -332,19 +332,19 @@ fun findContainer( ) = findContainers(containerSelection, sorted) .firstOrNull() -@ContainerMarker +@ContainerDslMarker context(automated: Automated) fun findContainers( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = searchContainers(containerSelection.scope) +) = searchContainers(containerSelection) .filter { containerSelection.matches(it) } .let { if (sorted) it.sorted() else it } -@ContainerMarker +@ContainerDslMarker context(_: Automated) fun findContainerWithDisposable( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, @@ -352,7 +352,7 @@ fun findContainerWithDisposable( ) = findContainersWithDisposable(containerSelection, sorted) .firstOrNull() -@ContainerMarker +@ContainerDslMarker context(automated: Automated) fun findContainersWithDisposable( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, @@ -371,7 +371,9 @@ fun findContainersWithDisposable( } context(automated: Automated) -private fun searchContainers(scope: ContainerSearchScope): Sequence { +private fun searchContainers( + selection: ContainerSelection +): Sequence { fun Container.allNested(): Sequence = sequence { yield(this@allNested) @@ -384,9 +386,10 @@ private fun searchContainers(scope: ContainerSearchScope): Sequence { val placedSeq = sequenceOf(ContainerHandler.accessedPlacedContainer).filterNotNull() val baseContainers = - when (scope) { + when (selection.scope) { ContainerSearchScope.Player -> compiled - EnderChestContainer ContainerSearchScope.Compiled -> compiled + ContainerSearchScope.Loaded -> compiled + placedSeq + selection.loadedContainers ContainerSearchScope.Accessed -> placedSeq + compiled.filter { it.isAccessed } ContainerSearchScope.All -> compiled + placedSeq + ContainerSerializer.serializedContainers.filter { diskContainer -> @@ -400,8 +403,9 @@ private fun searchContainers(scope: ContainerSearchScope): Sequence { } enum class ContainerSearchScope { - Player, - Compiled, Accessed, + Compiled, + Loaded, + Player, All } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt index 5c4cbd212..b43257a5f 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/InventoryTweaks.kt @@ -24,6 +24,7 @@ import com.lambda.event.events.InventoryEvent import com.lambda.event.events.PlayerEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.ContainerType +import com.lambda.interaction.container.NestedContainer import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.containers.external.EnderChestContainer import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection @@ -73,7 +74,9 @@ object InventoryTweaks : Module( else findContainer( containerSelection { ofAnyType(ContainerType.ShulkerBox) - isNested() + predicate { container -> + container is NestedContainer && container.index == slot.index + } } ) ?: return@listen diff --git a/src/main/kotlin/com/lambda/task/Task.kt b/src/main/kotlin/com/lambda/task/Task.kt index 599c84373..65679fd1b 100644 --- a/src/main/kotlin/com/lambda/task/Task.kt +++ b/src/main/kotlin/com/lambda/task/Task.kt @@ -33,7 +33,7 @@ import kotlin.time.DurationUnit import kotlin.time.toDuration @Suppress("unused") -abstract class Task : Nameable, Muteable { +abstract class Task : Nameable, Muteable { var state = State.Init var age = 0 @@ -44,7 +44,7 @@ abstract class Task : Nameable, Muteable { override val isMuted: Boolean get() = state == State.Paused || state == State.Init - private val successCallbacks = mutableListOf Unit>() + private val successCallbacks = mutableListOf Unit>() private val completionCallbacks = mutableListOf Unit>() private val failureCallbacks = mutableListOf Unit>() @@ -63,6 +63,7 @@ abstract class Task : Nameable, Muteable { } init { + if (this is RootTask) state = State.Running listen({ Int.MAX_VALUE }) { age++ } } @@ -73,30 +74,6 @@ abstract class Task : Nameable, Muteable { @DslMarker annotation class Ta5kBuilder - /** - * Invoked when the task starts execution. - * - * This method serves as a lifecycle hook and can be overridden to define - * custom behavior or initialization steps necessary before the task begins. - * It provides a `SafeContext` to access relevant context-sensitive properties - * or actions safely. - * - * By default, this method does not contain any logic. Subclasses may override - * it to implement specific functionality, such as logging, resource allocation, - * or preparing preconditions for task execution. - */ - @Ta5kBuilder - protected open fun SafeContext.onStart() {} - - /** - * This function is called when the task is canceled. - * It can be overridden for tasks that need to perform cleanup operations, - * such as cancelling a block breaking progress, releasing resources, - * or stopping any ongoing operations that were started by the task. - */ - @Ta5kBuilder - protected open fun SafeContext.onCancel() {} - @Ta5kBuilder context(parentTask: Task<*>) fun start(pauseParent: Boolean = true) = @@ -115,7 +92,7 @@ abstract class Task : Nameable, Muteable { * @throws IllegalArgumentException if the owner task is the same as the task being executed. */ @Ta5kBuilder - fun execute(parent: Task<*>, pauseParent: Boolean = true): Task { + fun execute(parent: Task<*>, pauseParent: Boolean = true): Task { require(parent != this) { "Cannot execute a task as a sub task of itself" } parent.subTasks.add(this) this@Task.parent = parent @@ -129,8 +106,32 @@ abstract class Task : Nameable, Muteable { return this } + /** + * Invoked when the task starts execution. + * + * This method serves as a lifecycle hook and can be overridden to define + * custom behavior or initialization steps necessary before the task begins. + * It provides a `SafeContext` to access relevant context-sensitive properties + * or actions safely. + * + * By default, this method does not contain any logic. Subclasses may override + * it to implement specific functionality, such as logging, resource allocation, + * or preparing preconditions for task execution. + */ + @Ta5kBuilder + protected open fun SafeContext.onStart() {} + + /** + * This function is called when the task is canceled. + * It can be overridden for tasks that need to perform cleanup operations, + * such as cancelling a block breaking progress, releasing resources, + * or stopping any ongoing operations that were started by the task. + */ + @Ta5kBuilder + protected open fun SafeContext.onCancel() {} + @Ta5kBuilder - protected fun success(result: Result) { + protected fun success(result: R) { if (state != State.Running && state != State.Paused) return unsubscribe() state = State.Completed @@ -157,7 +158,7 @@ abstract class Task : Nameable, Muteable { e: Throwable, stacktrace: MutableList> = mutableListOf(), ) { - if (state != State.Running && state != State.Failed) return + if (state != State.Running && state != State.Paused) return unsubscribe() state = State.Failed cancelSubTasks() @@ -195,11 +196,14 @@ abstract class Task : Nameable, Muteable { @Ta5kBuilder private fun internalCancel(removeFromParent: Boolean = true) { if (state != State.Running && state != State.Paused) return + cancelSubTasks() if (this is RootTask) return unsubscribe() state = State.Cancelled - cancelSubTasks() - runSafe { onCancel() } + runSafe { + onCancel() + completionCallbacks.forEach { it.invoke(this) } + } if (removeFromParent) parent?.subTasks?.remove(this) parent?.activate() @@ -211,18 +215,18 @@ abstract class Task : Nameable, Muteable { subTasks.clear() } - @Ta5kBuilder - fun activate() { - if (state != State.Paused) return - state = State.Running - } - @Ta5kBuilder fun pause() { if (state != State.Running) return state = State.Paused } + @Ta5kBuilder + fun activate() { + if (state != State.Paused) return + state = State.Running + } + @Ta5kBuilder protected open fun onSubTaskSuccess(subTask: Task<*>) { activate() @@ -242,7 +246,7 @@ abstract class Task : Nameable, Muteable { * Registers a callback for if the task succeeds. */ @Ta5kBuilder - fun onSuccess(callback: SafeContext.(Result) -> Unit): Task { + fun onSuccess(callback: SafeContext.(R) -> Unit): Task { successCallbacks.add(callback) return this } @@ -253,7 +257,7 @@ abstract class Task : Nameable, Muteable { * This could be mistaken for [withRecovery] which is used to wrap the given task with another task that runs a recovery task if this one fails. */ @Ta5kBuilder - fun onFailure(callback: SafeContext.(Throwable) -> Unit): Task { + fun onFailure(callback: SafeContext.(Throwable) -> Unit): Task { failureCallbacks.add(callback) return this } @@ -264,7 +268,7 @@ abstract class Task : Nameable, Muteable { * This is called regardless of whether the task succeeds or fails. */ @Ta5kBuilder - fun onCompletion(callback: SafeContext.() -> Unit): Task { + fun onCompletion(callback: SafeContext.() -> Unit): Task { completionCallbacks.add(callback) return this } diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index 0f95dc667..bfd335b50 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -25,7 +25,6 @@ import com.lambda.interaction.container.selection.select import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder import com.lambda.threading.runSafeAutomated -import net.minecraft.screen.slot.Slot @Ta5kBuilder context(automated: Automated) @@ -40,17 +39,15 @@ fun acquireStack(selection: () -> StackSelection) = class AcquireStackTask @Ta5kBuilder internal constructor( val selection: StackSelection, automated: Automated -) : Task(), Automated by automated { +) : Task(), Automated by automated { override val name: String get() = "Acquiring $selection" override fun SafeContext.onStart() { runSafeAutomated { selection.transfer(toSelection = HotbarContainer.select()) - .onSuccess { slot -> success(slot) } + .onSuccess { result -> success(result.stackSelection) } .start() } } } - -class NoContainerFound(selection: StackSelection) : Exception("No container found matching $selection") diff --git a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt index 8f64d39b1..e4ca93e65 100644 --- a/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt @@ -246,7 +246,7 @@ class BuildTask @Ta5kBuilder internal constructor( lifeMaintenance && eatTask == null && runSafeAutomated { reasonEating() }.shouldEat() -> { eatTask = eat() .thenAction { eatTask = null } - .execute(this@BuildTask) + .start() return true } @@ -360,7 +360,7 @@ class BuildTask @Ta5kBuilder internal constructor( if (collectDropsTask != null) return true collectDropsTask = collectDrops(dropsToCollect) .thenAction { collectDropsTask = null } - .execute(this@BuildTask) + .start() return true } diff --git a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt index cae228e6a..19bc25c21 100644 --- a/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/CollectDropsTask.kt @@ -19,6 +19,7 @@ package com.lambda.task.tasks import baritone.api.pathing.goals.GoalBlock import com.lambda.context.Automated +import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen @@ -54,36 +55,45 @@ class CollectDropsTask @Ta5kBuilder internal constructor( init { listen { runSafeAutomated { - val target = - drops.firstOrNull() ?: run { - BaritoneHandler.cancel() - success() - return@listen - } + do { + val done = pollNextItem() + } while (!done) + } + } + } - if (!world.entities.contains(target)) { - drops.remove(target) + private fun AutomatedSafeContext.pollNextItem(): Boolean { + val target = + drops.firstOrNull() + ?: run { BaritoneHandler.cancel() - return@listen + success() + return true } - if (findStack(stackSelection { isEmpty() }, ContainerSelection.HOTBAR_AND_INVENTORY) == null) { - val stackToThrow = - player.currentScreenHandler.playerSlots.firstOrNull { - it.stack.item in inventoryConfig.disposables - } ?: run { - failure("Inventory is full and no disposable items to throw") - return@listen - } - inventoryRequest { - throwStack(stackToThrow.id) - }.submit() - return@listen - } + if (!world.entities.contains(target)) { + drops.remove(target) + BaritoneHandler.cancel() + return false + } - BaritoneHandler.setGoalAndPath(GoalBlock(target.blockPos)) - } + if (findStack(stackSelection(0) { isEmpty() }, ContainerSelection.HOTBAR_AND_INVENTORY, false) == null) { + val stackToThrow = + player.currentScreenHandler.playerSlots.firstOrNull { + it.stack.item in inventoryConfig.disposables + } ?: run { + failure("Inventory is full and no disposable items to throw") + return true + } + inventoryRequest { + throwStack(stackToThrow.id) + }.submit() + return true } + + BaritoneHandler.setGoalAndPath(GoalBlock(target.blockPos)) + + return true } override fun SafeContext.onCancel() { diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index a8036ebe4..8ab79138a 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -18,16 +18,19 @@ package com.lambda.task.tasks import com.lambda.context.Automated +import com.lambda.context.AutomatedSafeContext import com.lambda.context.SafeContext import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.container.Container import com.lambda.interaction.container.ExternalContainer -import com.lambda.interaction.container.OpenedContainerContext import com.lambda.interaction.container.selection.ContainerSelection -import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.mutate +import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection import com.lambda.interaction.container.selection.StackSelection import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.mutate +import com.lambda.interaction.container.selection.StackSelectionBuilder.Companion.stackSelection +import com.lambda.interaction.container.selection.select +import com.lambda.interaction.container.selection.selectContainers import com.lambda.interaction.handler.handlers.findContainers import com.lambda.task.Task import com.lambda.task.Task.Ta5kBuilder @@ -40,11 +43,11 @@ import net.minecraft.screen.slot.Slot @Ta5kBuilder context(automated: Automated) fun transfer( - selection: StackSelection, + fromStack: StackSelection, fromSelection: ContainerSelection = ContainerSelection.ACCESSED, toSelection: ContainerSelection, toStack: StackSelection = StackSelection.ANYTHING -) = ContainerTransferTask(selection, fromSelection, toSelection, toStack, automated) +) = ContainerTransferTask(fromStack, fromSelection, toSelection, toStack, automated) @Ta5kBuilder @JvmName("transferExt") @@ -55,170 +58,249 @@ fun StackSelection.transfer( toStack: StackSelection = StackSelection.ANYTHING ) = transfer(this, fromSelection, toSelection, toStack) +class TransferResult internal constructor( + val stackSelection: StackSelection, + val containerSelection: ContainerSelection +) + class ContainerTransferTask @Ta5kBuilder internal constructor( private val fromStack: StackSelection, private val fromSelection: ContainerSelection, private val toSelection: ContainerSelection, private val toStack: StackSelection, automated: Automated -) : Task(), Automated by automated { - override val name = "Transferring $fromStack from $fromSelection to $toSelection" +) : Task(), Automated by automated { + override val name = "Transferring $fromStack" - override fun SafeContext.onStart() { - val singleSelection = fromStack.mutate(count = if (fromStack.count == 0) 0 else 1) + private var transferred = 0 + private val resultSlots = mutableListOf() + private val resultContainers = mutableSetOf() + override fun SafeContext.onStart() { val fromContainers = findContainers( - fromSelection.mutate { - hasStack(fromStack) + containerSelection(fromSelection.scope) { + matches(fromSelection) + hasStack(fromStack.mutate(1)) } ).toList() + .takeIf { fromStack isIn it } + ?: run { + failure("Could not find source containers for $fromStack") + return + } + val toContainers = findContainers( - toSelection.mutate { - hasStack(toStack) + containerSelection(toSelection.scope) { + matches(toSelection) + hasStack(toStack.mutate(1)) } ).toList() + .takeIf { toStack isIn it } + ?: run { + failure("Could not find destination containers for $toStack") + return + } - if (fromContainers.isEmpty()) { - failure(IllegalStateException("Could not find any container to pull $fromStack from")) - return - } - if (toContainers.isEmpty()) { - failure(IllegalStateException("Could not find any container with space to push $fromStack to")) + transferNextPair(fromContainers.toMutableList(), toContainers.toMutableList()) + } + + private fun remainingSelection() = + fromStack.mutate(count = if (fromStack.count <= 0) 0 else fromStack.count - transferred) + + private fun isComplete() = + (fromStack.count <= 0 && transferred > 0) || (fromStack.count != 0 && transferred >= fromStack.count) + + private fun buildResult() = + TransferResult( + stackSelection { + predicate { _, slot -> + slot != null && + resultSlots.any { + slot.inventory::class == it.inventory::class && slot.index == it.index + } + } + }, + selectContainers(*resultContainers.toTypedArray()) + ) + + /** + * Takes the first container from each queue as a pair, builds a transfer + * chain for that pair, then advances to the next pair on completion. + * + * Calls [success] or [failure] directly on this task when done. + */ + private fun transferNextPair( + fromQueue: MutableList, + toQueue: MutableList + ) { + if (isComplete()) { + success(buildResult()) return } - if (fromStack.count > 0) { - val totalAvailable = fromContainers.sumOf { it.count(singleSelection) } - if (totalAvailable < fromStack.count) { - failure(IllegalStateException("Not enough items across all containers to pull $fromStack")) - return - } + if (fromQueue.isEmpty() || toQueue.isEmpty()) { + failure("Not enough containers to transfer $fromStack (transferred $transferred/${fromStack.count})") + return } - val fromContainer = fromContainers.first() - val toContainer = toContainers.first() + val fromContainer = fromQueue.first() + val toContainer = toQueue.first() - when { - fromContainers.all { it.isAccessed } && toContainers.all { it.isAccessed } -> - TransferTask(fromContainers, toContainers) - .onSuccess { success(it) } + val bothExternal = fromContainer is ExternalContainer && !fromContainer.isAccessed && + toContainer is ExternalContainer && !toContainer.isAccessed - fromContainer !is ExternalContainer -> - openTransferClose(toContainer, fromSelection, toSelection) + val pairChain = + if (bothExternal) pullPushChain(fromContainer, toContainer, toQueue) + else directPairChain(fromContainer, toContainer) - toContainer !is ExternalContainer -> - openTransferClose(fromContainer, fromSelection, toSelection) - - else -> - taskOrNull { fromContainer.access() } - .then { fromCtx -> - transfer(fromStack, fromSelection, ContainerSelection.HOTBAR_AND_INVENTORY) - .thenOrNull { fromCtx?.close() } - } - .thenOrNull { toContainer.access() } - .then { toCtx -> transferAndClose(toCtx, ContainerSelection.HOTBAR_AND_INVENTORY, toSelection) } - }?.start() + pairChain.onSuccess { + if (fromContainer.count(fromStack) <= 0) fromQueue.remove(fromContainer) + if (!bothExternal && toContainer.spaceLeft(fromStack) <= 0) toQueue.remove(toContainer) + transferNextPair(fromQueue, toQueue) + }.start() } /** - * Opens [containerToOpen], transfers [fromStack] from [from] to [to], then closes the opened container. - * - * Used when exactly one of the two containers is external and needs to be accessed. + * Builds a chain for a pair where at most one container is external. + * Uses [taskOrNull] to uniformly handle already-accessed containers. */ - @Ta5kBuilder - private fun openTransferClose( - containerToOpen: Container, - fromSelection: ContainerSelection, - toSelection: ContainerSelection - ) = containerToOpen - .access() - ?.then { ctx -> transferAndClose(ctx, fromSelection, toSelection) } + private fun directPairChain( + fromContainer: Container, + toContainer: Container + ) = + taskOrNull { fromContainer.access() }.then { fromContext -> + taskOrNull { toContainer.access() }.then { toContext -> + SwapTask(fromContainer.select(), toContainer.select()) + .thenOrNull { toContext?.close() } + .thenOrNull { fromContext?.close() } + } + } /** - * Transfers [fromStack] from [from] to [to], then closes the container via [ctx]. + * Builds a chain for when both containers are external. + * Pulls items from [fromContainer] into the player inventory, then delegates + * to [pushChain] to push them into [toContainer]. */ - @Ta5kBuilder - private fun transferAndClose( - ctx: OpenedContainerContext?, - fromSelection: ContainerSelection, - toSelection: ContainerSelection - ) = transfer(fromStack, fromSelection, toSelection) - .thenOrNull { slot -> - ctx - ?.close() - ?.onSuccess { success(slot) } - } + private fun pullPushChain( + fromContainer: Container, + toContainer: Container, + toQueue: MutableList + ) = + taskOrNull { fromContainer.access() }.then { fromContext -> + SwapTask( + fromContainer.select(), + ContainerSelection.HOTBAR_AND_INVENTORY, + replaceSelection = StackSelection.ANYTHING, + trackResult = false + ).thenOrNull { fromContext?.close() } + }.then { pushChain(toContainer, toQueue) } - private inner class TransferTask @Ta5kBuilder constructor( - private val fromContainers: List, - private val toContainers: List - ) : Task() { - override val name = "Transferring" + /** + * Pushes items from the player inventory into [destination]. + * If [destination] fills up but the player still has items, advances [toQueue] + * and pushes to the next destination. + */ + private fun pushChain( + destination: Container, + toQueue: MutableList + ): Task<*> = + taskOrNull { destination.access() }.then { destinationContext -> + SwapTask(ContainerSelection.HOTBAR_AND_INVENTORY, destination.select()) + .thenOrNull { destinationContext?.close() } + }.onSuccess { + if (isComplete()) return@onSuccess - private var transferred = 0 - private var lastSlot: Slot? = null + if (destination.spaceLeft(fromStack) == 0) toQueue.remove(destination) + + val playerHasItems = findContainers(ContainerSelection.HOTBAR_AND_INVENTORY) + .any { container -> fromStack.mutate(1) isIn container } + if (!playerHasItems) return@onSuccess + + val nextDestination = toQueue.firstOrNull() ?: return@onSuccess + pushChain(nextDestination, toQueue).start() + } + + /** + * Swaps items between containers matching [fromSelection] and [toSelection] one slot per tick. + * Completes when no more valid move slots can be found or the total count is reached. + * Updates [transferred], [resultSlots], and [resultContainers] on the outer task. + * + * @param trackResult whether to record destination slots in [resultSlots]/[resultContainers]. + * Set to `false` for intermediary transfers (e.g. pulling to player inventory). + */ + private inner class SwapTask @Ta5kBuilder constructor( + private val fromSelection: ContainerSelection, + private val toSelection: ContainerSelection, + private val replaceSelection: StackSelection = toStack, + private val trackResult: Boolean = true + ) : Task() { + override val name = "Swapping slots" init { listen { runSafeAutomated { - while (fromStack.count == 0 || transferred < fromStack.count) { - val currentSelection = fromStack.mutate(count = if (fromStack.count == 0) 0 else fromStack.count - transferred) - - var fromSlot: Slot? = null - var toSlot: Slot? = null - var fromContainer: Container? = null - var toContainer: Container? = null - - for (fc in fromContainers) { - for (tc in toContainers) { - val slots = fc.findMoveSlots(currentSelection, tc, toStack) - if (slots.first != null && slots.second != null) { - fromSlot = slots.first - toSlot = slots.second - fromContainer = fc - toContainer = tc - break - } - } - if (fromSlot != null) break - } - - if (fromSlot == null || toSlot == null || fromContainer == null || toContainer == null) { - lastSlot?.let { slot -> - if (fromStack.count == 0 || transferred >= fromStack.count) { - success(slot) - return@listen - } - } - checkFail() - return@listen - } - - val moveCount = minOf(fromSlot.stack.count, if (fromStack.count == 0) Int.MAX_VALUE else fromStack.count - transferred) - if (!fromContainer.swap(fromSlot, toSlot, toContainer)) { - checkFail() - return@listen - } - - transferred += moveCount - lastSlot = toSlot - - // count == 0 means single stack transfer - if (fromStack.count == 0) { - success(toSlot) - return@listen - } + while (true) { + if (swapStack()) break } - - lastSlot?.let { success(it) } ?: checkFail() } } } - private fun checkFail() { - failure(IllegalStateException("Unable to access $fromStack")) + private fun AutomatedSafeContext.swapStack(): Boolean { + val currentSelection = remainingSelection() + + val moveSlots = + findContainers(fromSelection).firstNotNullOfOrNull { fromContainer -> + findContainers(toSelection).firstNotNullOfOrNull { toContainer -> + val (from, to) = + fromContainer.findMoveSlots( + currentSelection, + toContainer, + replaceSelection + ) + if (from != null && to != null) { + Triple( + fromContainer, + toContainer, + Pair(from, to) + ) + } else null + } + } + + if (moveSlots == null) { + success() + return true + } + + val (fromContainer, toContainer, slots) = moveSlots + val (fromSlot, toSlot) = slots + val moveCount = + minOf( + fromSlot.stack.count, + if (fromStack.count == 0) Int.MAX_VALUE + else fromStack.count - transferred + ) + + if (!fromContainer.swap(fromSlot, toSlot, toContainer)) { + failure("Swap failed for $fromStack") + return true + } + + transferred += moveCount + if (trackResult) { + resultSlots.add(toSlot) + resultContainers.add(toContainer) + } + + if (fromStack.count == 0 || isComplete()) { + success() + return true + } + + return false } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/task/tasks/wrappers/ActionTasks.kt b/src/main/kotlin/com/lambda/task/tasks/wrappers/ActionTasks.kt index d1bb7290e..ea5d58a2e 100644 --- a/src/main/kotlin/com/lambda/task/tasks/wrappers/ActionTasks.kt +++ b/src/main/kotlin/com/lambda/task/tasks/wrappers/ActionTasks.kt @@ -57,6 +57,6 @@ class SequencedActionTask @Ta5kBuilder internal constructor( .onSuccess { result -> success(action(this, result)) } - .execute(this@SequencedActionTask) + .start() } } \ No newline at end of file From 6f364cf3daa4dbf1f30b6e841b1ba7b3cfa2ded7 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 13 Sep 2026 13:46:34 +0300 Subject: [PATCH 17/18] feat: implement SilentEat module, container interactions, and UI refinements --- build.gradle.kts | 4 + .../mixin/render/HeldItemRendererMixin.java | 15 +- .../command/commands/TransferCommand.kt | 15 +- .../lambda/config/blocks/InventoryConfig.kt | 26 +- .../lambda/config/blocks/InventorySettings.kt | 6 +- .../EnderChestContainerSerializer.kt | 3 +- src/main/kotlin/com/lambda/gui/DearImGui.kt | 19 +- .../kotlin/com/lambda/gui/LambdaScreen.kt | 40 ++ src/main/kotlin/com/lambda/gui/MenuBar.kt | 108 +++- .../lambda/gui/components/ClickGuiLayout.kt | 508 +++++++++++++++--- .../com/lambda/gui/components/HudGuiLayout.kt | 49 ++ .../com/lambda/gui/components/ModuleEntry.kt | 125 ++++- .../com/lambda/gui/components/QuickSearch.kt | 459 ++++++++++++---- .../lambda/gui/components/SettingsWidget.kt | 221 +++++--- .../container/selection/ContainerSelection.kt | 44 +- .../container/selection/StackSelection.kt | 61 ++- .../handler/handlers/ContainerHandler.kt | 123 +++-- .../handler/handlers/GlideHandler.kt | 16 +- .../lambda/module/modules/combat/AutoArmor.kt | 11 +- .../lambda/module/modules/combat/AutoTotem.kt | 118 +++- .../lambda/module/modules/combat/Criticals.kt | 21 +- .../module/modules/combat/CrystalAura.kt | 48 +- .../lambda/module/modules/combat/KillAura.kt | 31 +- .../module/modules/combat/PlayerTrap.kt | 4 +- .../lambda/module/modules/combat/Surround.kt | 53 +- .../module/modules/movement/BetterFirework.kt | 8 +- .../module/modules/player/AutoElytraSwap.kt | 6 +- .../module/modules/player/PacketMine.kt | 79 ++- .../lambda/module/modules/player/SilentEat.kt | 331 ++++++++++++ .../module/modules/player/StackReplenish.kt | 4 +- .../com/lambda/task/tasks/AcquireStackTask.kt | 3 +- .../task/tasks/ContainerTransferTask.kt | 39 +- .../kotlin/com/lambda/task/tasks/EatTask.kt | 18 +- 33 files changed, 2144 insertions(+), 472 deletions(-) create mode 100644 src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt diff --git a/build.gradle.kts b/build.gradle.kts index aade0e4d1..660bacb7c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -285,4 +285,8 @@ publishing { } } } +} +tasks.named("compileJava") { + dependsOn(tasks.named("compileKotlin")) + classpath += files(tasks.named("compileKotlin").get().destinationDirectory) } \ No newline at end of file diff --git a/src/main/java/com/lambda/mixin/render/HeldItemRendererMixin.java b/src/main/java/com/lambda/mixin/render/HeldItemRendererMixin.java index 97d8c5e63..260898329 100644 --- a/src/main/java/com/lambda/mixin/render/HeldItemRendererMixin.java +++ b/src/main/java/com/lambda/mixin/render/HeldItemRendererMixin.java @@ -20,6 +20,12 @@ import com.google.common.base.MoreObjects; import com.lambda.Lambda; import com.lambda.module.modules.render.ViewModel; +import com.lambda.module.modules.player.SilentEat; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemDisplayContext; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.AbstractClientPlayerEntity; @@ -53,7 +59,14 @@ private void injectRenderFirstPersonItem(AbstractClientPlayerEntity player, floa private void injectRenderArmHoldingItem(AbstractClientPlayerEntity player, float tickProgress, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, OrderedRenderCommandQueue orderedRenderCommandQueue, int light, CallbackInfo ci) { if (ViewModel.INSTANCE.isEnabled()) ViewModel.INSTANCE.transform(item, hand, matrices); } - + @WrapOperation(method = "renderFirstPersonItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderItem(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemDisplayContext;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/command/OrderedRenderCommandQueue;I)V")) + private void wrapRenderItem(HeldItemRenderer instance, LivingEntity entity, ItemStack item, ItemDisplayContext displayContext, MatrixStack matrices, OrderedRenderCommandQueue queue, int light, Operation original, @Local(argsOnly = true) Hand hand) { + if (SilentEat.isUsingOffhand() && hand == Hand.OFF_HAND && SilentEat.INSTANCE.getSilentVisual()) { + original.call(instance, entity, SilentEat.getVisualOffhandStack(), displayContext, matrices, queue, light); + return; + } + original.call(instance, entity, item, displayContext, matrices, queue, light); + } @ModifyArg(method = "updateHeldItems", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;clamp(FFF)F", ordinal = 2), index = 0) private float modifyEquipProgressMainHand(float value) { if (client.player == null || ViewModel.INSTANCE.isDisabled()) return value; diff --git a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt index def4906f1..c5740b639 100644 --- a/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt +++ b/src/main/kotlin/com/lambda/command/commands/TransferCommand.kt @@ -96,16 +96,25 @@ object TransferCommand : LambdaCommand( } executeWithResult { AutomationConfig.DEFAULT.runSafeAutomated { + fun parsePredicate(raw: String): (com.lambda.interaction.container.Container) -> Boolean { + val clean = raw.trim().removeSurrounding("\"") + val indexPrefix = clean.substringBefore(". ").toIntOrNull() + val nameAfterDot = if (indexPrefix != null) clean.substringAfter(". ").trim() else clean + return { container -> + container.name.equals(clean, ignoreCase = true) || + container.name.equals(nameAfterDot, ignoreCase = true) + } + } + val fromSelection = containerSelection { - predicate { it.name == from().value().split(".").first().trim() } + predicate(parsePredicate(from().value())) } val toSelection = containerSelection { - predicate { it.name == to().value().split(".").first().trim() } + predicate(parsePredicate(to().value())) } - lastContainerTransfer = transfer( stackSelection(amount().value()) { diff --git a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt index 6e65ca89d..a5eaa4285 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventoryConfig.kt @@ -21,6 +21,7 @@ import com.lambda.event.events.TickEvent import com.lambda.interaction.container.Container import com.lambda.interaction.container.selection.ContainerSelection import com.lambda.interaction.container.selection.ContainerSelectionBuilder.Companion.containerSelection +import com.lambda.interaction.container.selection.StackSelection import com.lambda.util.Describable import com.lambda.util.NamedEnum import net.minecraft.item.Item @@ -28,13 +29,14 @@ import net.minecraft.item.Item interface InventoryConfig { val tickStageMask: Collection val disposables: Collection + val accessPriority: ContainerPriority + val storePriority: ContainerPriority val allowedContainers: Collection val containerSelection: ContainerSelection get() = containerSelection { ofAnyType(*allowedContainers.toTypedArray()) } val enderChestSearchRadius: Int - @Suppress("unused") enum class ContainerPriority( override val displayName: String, @@ -43,6 +45,28 @@ interface InventoryConfig { WithMinItems("With Min Items", "Pick containers with the fewest matching items (or least space) first; useful for topping off or clearing leftovers."), WithMaxItems("With Max Items", "Pick containers with the most matching items (or most space) first; ideal for bulk moves with fewer transfers."); + fun materialComparator(selection: StackSelection): Comparator = + when (this) { + WithMaxItems -> compareBy { it.type } + .thenByDescending { it.count(selection) } + .thenBy { it.name } + + WithMinItems -> compareBy { it.type } + .thenBy { it.count(selection) } + .thenBy { it.name } + } + + fun spaceComparator(selection: StackSelection): Comparator = + when (this) { + WithMaxItems -> compareBy { it.type } + .thenByDescending { it.spaceLeft(selection) } + .thenBy { it.name } + + WithMinItems -> compareBy { it.type } + .thenBy { it.spaceLeft(selection) } + .thenBy { it.name } + } + fun comparator(countSelector: (Container, T) -> Int) = compareBy> { it.first.type } .thenByDescending { countSelector(it.first, it.second) } diff --git a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt index 84f059189..4a2c50c57 100644 --- a/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt +++ b/src/main/kotlin/com/lambda/config/blocks/InventorySettings.kt @@ -31,7 +31,9 @@ class InventorySettings(override val c: Config) : InventoryConfig, ConfigBlock { override val tickStageMask by c.setting("Inventory Stage Mask", ALL_STAGES.toSet(), description = "The sub-tick timing at which inventory actions are performed", displayClassName = true) override val disposables by c.setting("Disposables", ItemUtils.DEFAULT_DISPOSABLES, description = "Items that will be ignored when checking for a free slot") - override val allowedContainers by c.setting("Allowed Containers", ContainerType.entries, description = "What containers are accessible") + override val allowedContainers by c.setting("Allowed Containers", ContainerType.entries, description = "What containers to search for items in") + override val accessPriority by c.setting("Access Priority", InventoryConfig.ContainerPriority.WithMinItems, description = "What container to prefer when retrieving the item from") + override val storePriority by c.setting("Store Priority", InventoryConfig.ContainerPriority.WithMinItems, description = "What container to prefer when storing the item to") - @Group(ENDER_CHEST_GROUP) override val enderChestSearchRadius by c.setting("Initial Search Radius", 10, 0..20, unit = " blocks", description = "Initial search radius to scan for an already placed ender chest. If one isn't found, one will be placed. If an ender chest isn't found in the inventory, it scans the rest of the loaded area to find an already placed one") + @Group(ENDER_CHEST_GROUP) override val enderChestSearchRadius by c.setting("Initial Search Radius", 10, 0..20, unit = " blocks", description = "The search radius for ender chests to access if one hasn't been accessed yet") } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt b/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt index 8601077c5..0effb88ca 100644 --- a/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt +++ b/src/main/kotlin/com/lambda/config/serializers/EnderChestContainerSerializer.kt @@ -53,7 +53,8 @@ object EnderChestContainerSerializer : Serializer(EnderChes object EnderChestContainerDeserializer : Deserializer(EnderChestContainer::class.java) { override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): EnderChestContainer? { - throw initFromJsonException("EnderChestContainer") + if (p == null || ctxt == null) return null + return deserialize(p, ctxt, EnderChestContainer) } override fun deserialize(p: JsonParser, ctxt: DeserializationContext, intoValue: EnderChestContainer): EnderChestContainer { diff --git a/src/main/kotlin/com/lambda/gui/DearImGui.kt b/src/main/kotlin/com/lambda/gui/DearImGui.kt index fba0d5cf1..794b7daa1 100644 --- a/src/main/kotlin/com/lambda/gui/DearImGui.kt +++ b/src/main/kotlin/com/lambda/gui/DearImGui.kt @@ -62,6 +62,11 @@ object DearImGui : Loadable { addRanges(io.fonts.glyphRangesGreek) addChar(EXTERNAL_LINK) addChar(BREAD_CRUMB_SEPARATOR) + addChar('▼') + addChar('▶') + addChar('▲') + addChar('◀') + addChar('⚙') }.buildRanges() val fontConfig = ImFontConfig() val size = BASE_FONT_SCALE * scale @@ -80,19 +85,20 @@ object DearImGui : Loadable { val dpi = ClickGuiLayout.deviceScaleMultiplier() val base = ClickGuiLayout.BASE_SCALE_MULTI * dpi val fontScaleSetting = ClickGuiLayout.fontScale - val scale = (base * userPercent * fontScaleSetting).toFloat() + val guiScale = (base * userPercent).toFloat() + val fontScale = (guiScale * fontScaleSetting).toFloat() if (lastScale == 0f) { - targetScale = scale + targetScale = fontScale updateScale(targetScale) lastScale = targetScale } - if (scale > 0 && abs(scale - lastScale) > 0.001f) { - if (abs(scale - targetScale) > 0.001f) { + if (fontScale > 0 && abs(fontScale - lastScale) > 0.001f) { + if (abs(fontScale - targetScale) > 0.001f) { lastScaleChangeTimestamp = System.currentTimeMillis() scaleChanged = true - targetScale = scale + targetScale = fontScale } } @@ -101,7 +107,6 @@ object DearImGui : Loadable { lastScale = targetScale scaleChanged = false } - val framebuffer = mc.framebuffer val prevFramebuffer = (framebuffer.getColorAttachment() as GlTexture).getOrCreateFramebuffer( (RenderSystem.getDevice() as GlBackend).bufferManager, @@ -120,7 +125,7 @@ object DearImGui : Loadable { implGlfw.newFrame() implGl3.newFrame() - ClickGuiLayout.applyStyle(lastScale) + ClickGuiLayout.applyStyle(guiScale) ImGui.newFrame() GuiEvent.NewImguiFrame.post() diff --git a/src/main/kotlin/com/lambda/gui/LambdaScreen.kt b/src/main/kotlin/com/lambda/gui/LambdaScreen.kt index 64b3c2804..56d9817a4 100644 --- a/src/main/kotlin/com/lambda/gui/LambdaScreen.kt +++ b/src/main/kotlin/com/lambda/gui/LambdaScreen.kt @@ -18,9 +18,13 @@ package com.lambda.gui import com.lambda.gui.components.ClickGuiLayout +import com.lambda.gui.components.QuickSearch import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen +import net.minecraft.client.input.KeyInput +import net.minecraft.client.util.InputUtil import net.minecraft.text.Text +import org.lwjgl.glfw.GLFW object LambdaScreen : Screen(Text.of("Lambda")) { /** @@ -30,6 +34,12 @@ object LambdaScreen : Screen(Text.of("Lambda")) { var parentScreen: Screen? = null override fun shouldPause() = false + override fun shouldCloseOnEsc(): Boolean { + if (QuickSearch.isOpen || System.currentTimeMillis() - QuickSearch.lastClosedTimestamp < 200L) { + return false + } + return true + } override fun removed() = ClickGuiLayout.close() override fun render(context: DrawContext?, mouseX: Int, mouseY: Int, deltaTicks: Float) {} @@ -55,11 +65,41 @@ object LambdaScreen : Screen(Text.of("Lambda")) { } override fun close() { + if (QuickSearch.isOpen) { + QuickSearch.close() + return + } + if (System.currentTimeMillis() - QuickSearch.lastClosedTimestamp < 200L) { + return + } val previous = parentScreen parentScreen = null client?.setScreen(previous) } + override fun keyPressed(input: KeyInput): Boolean { + val win = client?.window + val isCtrl = (input.modifiers() and GLFW.GLFW_MOD_CONTROL != 0) + || (win != null && (InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_LEFT_CONTROL) || InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_RIGHT_CONTROL))) + + if (input.key() == GLFW.GLFW_KEY_F && isCtrl) { + QuickSearch.toggle() + return true + } + + if (input.key() == GLFW.GLFW_KEY_ESCAPE) { + if (QuickSearch.isOpen) { + QuickSearch.close() + return true + } + if (System.currentTimeMillis() - QuickSearch.lastClosedTimestamp < 200L) { + return true + } + } + + return super.keyPressed(input) + } + override fun applyBlur(context: DrawContext?) { if (!ClickGuiLayout.backgroundBlur) return super.applyBlur(context) diff --git a/src/main/kotlin/com/lambda/gui/MenuBar.kt b/src/main/kotlin/com/lambda/gui/MenuBar.kt index df50b2a31..0f8b8fb23 100644 --- a/src/main/kotlin/com/lambda/gui/MenuBar.kt +++ b/src/main/kotlin/com/lambda/gui/MenuBar.kt @@ -61,6 +61,7 @@ import java.util.* object MenuBar { private var aboutRequested = false + private var shortcutsModalOpen = false var newConfigName = "" val headerLogo = upload("textures/lambda_text_color.png") val lambdaLogo = upload("textures/lambda.png") @@ -79,6 +80,7 @@ object MenuBar { menu("Automation Configs") { buildAutomationConfigsMenu() } menu("Minecraft") { buildMinecraftMenu() } menu("Help") { buildHelpMenu() } + buildSearchButton() buildGitHubReference() } @@ -88,6 +90,13 @@ object MenuBar { } aboutPopup() + + if (shortcutsModalOpen) { + ImGui.openPopup("Keyboard Shortcuts") + shortcutsModalOpen = false + } + + shortcutsPopup() } private fun ImGuiBuilder.lambdaMenu() { @@ -245,10 +254,10 @@ object MenuBar { } private fun ImGuiBuilder.buildHudMenu() { - menuItem(if (HudGuiLayout.isLocked) "Unlock" else "Lock") { + menuItem(if (HudGuiLayout.isLocked) "Unlock HUD (Enable Dragging)" else "Lock HUD (Disable Dragging)") { HudGuiLayout.isLocked = !HudGuiLayout.isLocked } - menuItem(if (HudGuiLayout.isShownInGUI) "Hide" else "Show") { + menuItem(if (HudGuiLayout.isShownInGUI) "Hide HUD in GUI" else "Show HUD in GUI") { HudGuiLayout.isShownInGUI = !HudGuiLayout.isShownInGUI } separator() @@ -258,9 +267,46 @@ object MenuBar { } private fun ImGuiBuilder.buildGuiMenu() { - buildConfigSettingsContext(ClickGuiLayout) + menu("Layout & Windows") { + menuItem("Tile Windows (Auto-Arrange)") { ClickGuiLayout.tileWindows() } + menuItem("Reset Window Positions") { ClickGuiLayout.resetWindowPositions() } + separator() + menuItem("Collapse All Modules") { ClickGuiLayout.collapseAllModules() } + } + menu("Theme Presets") { + ClickGuiLayout.ThemePreset.entries.forEach { preset -> + menuItem(preset.displayName, selected = ClickGuiLayout.themePreset == preset) { + ClickGuiLayout.applyTheme(preset) + } + } + separator() + menuItem("Sync Theme to Accent Color") { + ClickGuiLayout.syncThemeToAccent(ClickGuiLayout.primaryColor) + } + } + separator() + menu("Display Options") { + menuItem("Show Keybind Badges", selected = ClickGuiLayout.showKeybindBadges) { + ClickGuiLayout.showKeybindBadges = !ClickGuiLayout.showKeybindBadges + } + menuItem("Highlight Enabled Modules", selected = ClickGuiLayout.highlightEnabledModules) { + ClickGuiLayout.highlightEnabledModules = !ClickGuiLayout.highlightEnabledModules + } + menuItem("Allow Window Collapse", selected = ClickGuiLayout.allowWindowCollapse) { + ClickGuiLayout.allowWindowCollapse = !ClickGuiLayout.allowWindowCollapse + } + menuItem("Category Window Search", selected = ClickGuiLayout.categoryWindowSearch) { + ClickGuiLayout.categoryWindowSearch = !ClickGuiLayout.categoryWindowSearch + } + menuItem("Show Category Counts", selected = ClickGuiLayout.showCategoryCounts) { + ClickGuiLayout.showCategoryCounts = !ClickGuiLayout.showCategoryCounts + } + } + separator() + menu("All GUI Settings") { + buildConfigSettingsContext(ClickGuiLayout) + } } - private fun ImGuiBuilder.buildModulesMenu() { menu("Module Tag") { ModuleTag.defaults.forEach { tag -> @@ -438,9 +484,13 @@ object MenuBar { } private fun ImGuiBuilder.buildHelpMenu() { - menuItem("Quick Search...", "Shift+Shift") { + menuItem("Quick Search...", "Ctrl+F / Shift+Shift") { QuickSearch.open() } + menuItem("Keyboard Shortcuts Guide") { + shortcutsModalOpen = true + } + separator() menuItem("Documentation $EXTERNAL_LINK") { Util.getOperatingSystem().open("$REPO_URL/wiki") } @@ -531,4 +581,52 @@ object MenuBar { } } } + + private fun ImGuiBuilder.buildSearchButton() { + val label = "Search (Ctrl+F)" + val btnW = ImGui.calcTextSize(label).x + style.framePadding.x * 2.5f + val iconSize = (frameHeight - 6f).coerceAtLeast(14f) + val spacingPx = 8f + sameLine() + cursorPosX = windowContentRegionMaxX - iconSize - spacingPx - btnW - 8f + withStyleVar(ImGuiStyleVar.FramePadding, style.framePadding.x * 0.8f, 2f) { + smallButton(label) { + QuickSearch.open() + } + } + lambdaTooltip("Search modules, settings and commands (Ctrl+F or Double Shift)") + } + + private fun ImGuiBuilder.shortcutsPopup() { + popupModal("Keyboard Shortcuts", ImGuiWindowFlags.AlwaysAutoResize) { + text("Lambda Client - Shortcuts & Controls") + separator() + + val shortcuts = listOf( + "Ctrl + F / Double Shift" to "Open Quick Search modal", + "Up / Down Arrow" to "Navigate through search results", + "Enter" to "Toggle module or run selected search result", + "Tab" to "Cycle search filters (All, Modules, Settings, Commands)", + "Escape" to "Close Quick Search / Close GUI", + "Left Click (Module)" to "Toggle module on / off", + "Right Click (Module)" to "Expand / collapse inline settings or open popup", + "Small Arrow (▼ / ▶)" to "Expand or collapse module settings inline", + "Double Click (Header)" to "Collapse or expand category window", + "Drag Title Bar" to "Move category window (snaps to grid & edges)", + "Drag HUD Element" to "Move HUD component (when HUD is unlocked)", + "Right Click (Window)" to "Open window layout menu (Tile, Reset, etc.)" + ) + + shortcuts.forEach { (key, desc) -> + ImGui.textColored(0.9f, 0.75f, 0.2f, 1f, key) + sameLine(220f) + text(desc) + } + + separator() + smallButton("Got it") { + closeCurrentPopup() + } + } + } } diff --git a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt index 9bc94da3f..49d332477 100644 --- a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt +++ b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt @@ -46,6 +46,7 @@ import com.lambda.imgui.flag.ImGuiCol import com.lambda.imgui.flag.ImGuiCond import com.lambda.imgui.flag.ImGuiHoveredFlags import com.lambda.imgui.flag.ImGuiWindowFlags +import com.lambda.imgui.type.ImString import com.lambda.module.ModuleRegistry import com.lambda.module.ModuleTag import com.lambda.module.ModuleTag.Companion.shownTags @@ -68,7 +69,7 @@ import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen import net.minecraft.client.util.Icons import java.awt.Color import kotlin.math.abs - +import kotlin.math.max @Suppress("unused") object ClickGuiLayout : Loadable, Config( "GUI", @@ -135,7 +136,7 @@ object ClickGuiLayout : Loadable, Config( } const val BASE_SCALE = 100 - const val BASE_SCALE_MULTI = 1.8 + const val BASE_SCALE_MULTI = 1.45 fun deviceScaleMultiplier() = try { val monitorWidth = mc.window.monitor!!.currentVideoMode!!.width.toDouble() @@ -144,6 +145,12 @@ object ClickGuiLayout : Loadable, Config( 1.0 } + val currentScale: Float + get() { + val userPercent = scaleSetting / 100.0 + val dpi = deviceScaleMultiplier() + return (BASE_SCALE_MULTI * dpi * userPercent).toFloat() + } // General @Tab(GENERAL_TAB) internal val scaleSetting by setting("Scale", BASE_SCALE, 50..300, 1, unit = "%") @Tab(GENERAL_TAB) val alpha by setting("Alpha", 1.0f, 0.0f..1.0f, 0.01f) @@ -162,6 +169,18 @@ object ClickGuiLayout : Loadable, Config( @Tab(GENERAL_TAB) val backgroundBlur by setting("Background Blur", true) @Tab(GENERAL_TAB) val backgroundDarkening by setting("Background Darkening", true) + enum class SettingsMode(override val displayName: String) : NamedEnum { + INLINE("Inline"), + POPUP("Popup"), + BOTH("Both") + } + @Tab(GENERAL_TAB) var settingsMode by setting("Settings Mode", SettingsMode.INLINE, "How module settings open (Inline in category window, Popup menu, or Both)") + @Tab(GENERAL_TAB) var showKeybindBadges by setting("Show Keybind Badges", true, "Show assigned keybind pill on module entries") + @Tab(GENERAL_TAB) var highlightEnabledModules by setting("Highlight Enabled Modules", true, "Show visual accent bar and highlight on active modules") + @Tab(GENERAL_TAB) var allowWindowCollapse by setting("Allow Window Collapse", true, "Allow category windows to collapse by clicking arrow or double-clicking title bar") + @Tab(GENERAL_TAB) var categoryWindowSearch by setting("Category Window Search", false, "Show a search filter at the top of category windows") + @Tab(GENERAL_TAB) var showCategoryCounts by setting("Show Category Counts", true, "Display enabled/total module count in window titles [X/Y]") + // Snapping @Tab(SNAPPING_TAB) val snapEnabled by setting("Enable Snapping", true, "Master toggle for GUI/HUD snapping") @Tab(SNAPPING_TAB) val gridSize by setting("Grid Size", 25f, 2f..128f, 1f, "Grid step in pixels") { snapEnabled } @@ -177,14 +196,14 @@ object ClickGuiLayout : Loadable, Config( // Sizing @Tab(SIZING_TAB) val windowPaddingX by setting("Window Padding X", 8.0f, 0.0f..20.0f, 0.1f) @Tab(SIZING_TAB) val windowPaddingY by setting("Window Padding Y", 8.0f, 0.0f..20.0f, 0.1f) - @Tab(SIZING_TAB) val windowMinSizeX by setting("Window Min Size X", 32.0f, 0.0f..100.0f, 1.0f) + @Tab(SIZING_TAB) val windowMinSizeX by setting("Window Min Size X", 180.0f, 50.0f..300.0f, 1.0f) @Tab(SIZING_TAB) val windowMinSizeY by setting("Window Min Size Y", 32.0f, 0.0f..100.0f, 1.0f) @Tab(SIZING_TAB) val windowTitleAlignX by setting("Window Title Align X", 0.0f, 0.0f..1.0f, 0.01f) @Tab(SIZING_TAB) val windowTitleAlignY by setting("Window Title Align Y", 0.5f, 0.0f..1.0f, 0.01f) - @Tab(SIZING_TAB) val framePaddingX by setting("Frame Padding X", 4.0f, 0.0f..20.0f, 0.1f) - @Tab(SIZING_TAB) val framePaddingY by setting("Frame Padding Y", 3.0f, 0.0f..20.0f, 0.1f) + @Tab(SIZING_TAB) val framePaddingX by setting("Frame Padding X", 5.0f, 0.0f..20.0f, 0.1f) + @Tab(SIZING_TAB) val framePaddingY by setting("Frame Padding Y", 3.5f, 0.0f..20.0f, 0.1f) @Tab(SIZING_TAB) val itemSpacingX by setting("Item Spacing X", 8.0f, 0.0f..20.0f, 0.1f) - @Tab(SIZING_TAB) val itemSpacingY by setting("Item Spacing Y", 4.0f, 0.0f..20.0f, 0.1f) + @Tab(SIZING_TAB) val itemSpacingY by setting("Item Spacing Y", 3.0f, 0.0f..20.0f, 0.1f) @Tab(SIZING_TAB) val itemInnerSpacingX by setting("Item Inner Spacing X", 4.0f, 0.0f..20.0f, 0.1f) @Tab(SIZING_TAB) val itemInnerSpacingY by setting("Item Inner Spacing Y", 4.0f, 0.0f..20.0f, 0.1f) @Tab(SIZING_TAB) val indentSpacing by setting("Indent Spacing", 21.0f, 0.0f..50.0f, 0.1f) @@ -210,65 +229,386 @@ object ClickGuiLayout : Loadable, Config( @Tab(FONT_TAB) val fontScale by setting("Font Scale", 1.0, 0.5..2.0, 0.1) // Colors - @Tab(COLORS_TAB) val primaryColor by setting("Primary Color", Color(130, 200, 255)) - @Tab(COLORS_TAB) val secondaryColor by setting("Secondary Color", Color(225, 130, 225)) - - @Tab(COLORS_TAB) val text by setting("Text", Color(255, 255, 255, 255)) - @Tab(COLORS_TAB) val textDisabled by setting("Text Disabled", Color(128, 128, 128, 255)) - @Tab(COLORS_TAB) val windowBg by setting("Window Background", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val childBg by setting("Child Background", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val popupBg by setting("Popup Background", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val border by setting("Border", Color(130, 12, 60, 240)) - @Tab(COLORS_TAB) val borderShadow by setting("Border Shadow", Color(51, 0, 21, 240)) - @Tab(COLORS_TAB) val frameBg by setting("Frame Background", Color(171, 32, 93, 102)) - @Tab(COLORS_TAB) val frameBgHovered by setting("Frame Background Hovered", Color(214, 45, 119, 102)) - @Tab(COLORS_TAB) val frameBgActive by setting("Frame Background Active", Color(255, 50, 140, 102)) - @Tab(COLORS_TAB) val titleBg by setting("Title Background", Color(125, 0, 50, 240)) - @Tab(COLORS_TAB) val titleBgActive by setting("Title Background Active", Color(162, 0, 68, 240)) - @Tab(COLORS_TAB) val titleBgCollapsed by setting("Title Background Collapsed", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val menuBarBg by setting("MenuBar Background", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val scrollbarBg by setting("Scrollbar Background", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val scrollbarGrab by setting("Scrollbar Grab", Color(159, 30, 83, 240)) - @Tab(COLORS_TAB) val scrollbarGrabHovered by setting("Scrollbar Grab Hovered", Color(198, 40, 105, 240)) - @Tab(COLORS_TAB) val scrollbarGrabActive by setting("Scrollbar Grab Active", Color(235, 49, 126, 240)) - @Tab(COLORS_TAB) val checkMark by setting("Check Mark", Color(255, 64, 148, 220)) - @Tab(COLORS_TAB) val sliderGrab by setting("Slider Grab", Color(207, 46, 117, 200)) - @Tab(COLORS_TAB) val sliderGrabActive by setting("Slider Grab Active", Color(241, 67, 143, 200)) - @Tab(COLORS_TAB) val button by setting("Button", Color(171, 32, 93, 102)) - @Tab(COLORS_TAB) val buttonHovered by setting("Button Hovered", Color(214, 45, 119, 102)) - @Tab(COLORS_TAB) val buttonActive by setting("Button Active", Color(255, 50, 140, 102)) - @Tab(COLORS_TAB) val header by setting("Header", Color(192, 30, 94, 115)) - @Tab(COLORS_TAB) val headerHovered by setting("Header Hovered", Color(255, 59, 136, 115)) - @Tab(COLORS_TAB) val headerActive by setting("Header Active", Color(202, 36, 101, 115)) - @Tab(COLORS_TAB) val separator by setting("Separator", Color(107, 0, 47, 128)) - @Tab(COLORS_TAB) val separatorHovered by setting("Separator Hovered", Color(146, 0, 64, 128)) - @Tab(COLORS_TAB) val separatorActive by setting("Separator Active", Color(186, 0, 82, 128)) - @Tab(COLORS_TAB) val resizeGrip by setting("Resize Grip", Color(214, 45, 119, 102)) - @Tab(COLORS_TAB) val resizeGripHovered by setting("Resize Grip Hovered", Color(214, 45, 119, 102)) - @Tab(COLORS_TAB) val resizeGripActive by setting("Resize Grip Active", Color(214, 45, 119, 102)) - @Tab(COLORS_TAB) val tab by setting("Tab", Color(121, 21, 65, 140)) - @Tab(COLORS_TAB) val tabHovered by setting("Tab Hovered", Color(169, 34, 94, 140)) - @Tab(COLORS_TAB) val tabActive by setting("Tab Active", Color(209, 34, 112, 140)) - @Tab(COLORS_TAB) val tabUnfocused by setting("Tab Unfocused", Color(121, 21, 65, 120)) - @Tab(COLORS_TAB) val tabUnfocusedActive by setting("Tab Unfocused Active", Color(196, 36, 107, 120)) - @Tab(COLORS_TAB) val dockingPreview by setting("Docking Preview", Color(208, 47, 117, 102)) - @Tab(COLORS_TAB) val dockingEmptyBg by setting("Docking Empty Background", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val plotLines by setting("Plot Lines", Color(178, 36, 95, 240)) - @Tab(COLORS_TAB) val plotLinesHovered by setting("Plot Lines Hovered", Color(209, 40, 110, 240)) - @Tab(COLORS_TAB) val plotHistogram by setting("Plot Histogram", Color(192, 32, 91, 255)) - @Tab(COLORS_TAB) val plotHistogramHovered by setting("Plot Histogram Hovered", Color(226, 38, 108, 255)) - @Tab(COLORS_TAB) val tableHeaderBg by setting("Table Header Background", Color(75, 0, 31, 240)) - @Tab(COLORS_TAB) val tableBorderStrong by setting("Table Border Strong", Color(88, 0, 36, 240)) - @Tab(COLORS_TAB) val tableBorderLight by setting("Table Border Light", Color(67, 0, 28, 240)) - @Tab(COLORS_TAB) val tableRowBg by setting("Table Row Background", Color(35, 0, 14, 240)) - @Tab(COLORS_TAB) val tableRowBgAlt by setting("Table Row Background Alt", Color(242, 140, 182, 240)) - @Tab(COLORS_TAB) val textSelectedBg by setting("Text Selected Background", Color(218, 54, 121, 240)) - @Tab(COLORS_TAB) val dragDropTarget by setting("Drag Drop Target", Color(218, 54, 121, 240)) - @Tab(COLORS_TAB) val navHighlight by setting("Nav Highlight", Color(218, 54, 121, 240)) - @Tab(COLORS_TAB) val navWindowingHighlight by setting("Nav Windowing Highlight", Color(242, 140, 182, 240)) - @Tab(COLORS_TAB) val navWindowingDimBg by setting("Nav Windowing Dim Background", Color(242, 140, 182, 240)) - @Tab(COLORS_TAB) val modalWindowDimBg by setting("Modal Window Dim Background", Color(35, 0, 14, 90)) + enum class ThemePreset(override val displayName: String) : NamedEnum { + CUSTOM("Custom"), + LAMBDA_VIOLET("Lambda Violet"), + MIDNIGHT_BLUE("Midnight Blue"), + NORDIC_FROST("Nordic Frost"), + CYBERPUNK_NEON("Cyberpunk Neon"), + DRACULA("Dracula"), + EMERALD_OBSIDIAN("Emerald Obsidian"), + MONOKAI_GOLD("Monokai Gold") + } + @Tab(COLORS_TAB) val themePreset by setting("Theme Preset", ThemePreset.LAMBDA_VIOLET, "Predefined theme palettes for the ClickGUI") + .onValueChange { _, preset -> applyTheme(preset) } + + @Tab(COLORS_TAB) var primaryColor by setting("Primary Color", Color(130, 200, 255)) + @Tab(COLORS_TAB) var secondaryColor by setting("Secondary Color", Color(225, 130, 225)) + + @Tab(COLORS_TAB) var text by setting("Text", Color(255, 255, 255, 255)) + @Tab(COLORS_TAB) var textDisabled by setting("Text Disabled", Color(128, 128, 128, 255)) + @Tab(COLORS_TAB) var windowBg by setting("Window Background", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var childBg by setting("Child Background", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var popupBg by setting("Popup Background", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var border by setting("Border", Color(130, 12, 60, 240)) + @Tab(COLORS_TAB) var borderShadow by setting("Border Shadow", Color(51, 0, 21, 240)) + @Tab(COLORS_TAB) var frameBg by setting("Frame Background", Color(171, 32, 93, 102)) + @Tab(COLORS_TAB) var frameBgHovered by setting("Frame Background Hovered", Color(214, 45, 119, 102)) + @Tab(COLORS_TAB) var frameBgActive by setting("Frame Background Active", Color(255, 50, 140, 102)) + @Tab(COLORS_TAB) var titleBg by setting("Title Background", Color(125, 0, 50, 240)) + @Tab(COLORS_TAB) var titleBgActive by setting("Title Background Active", Color(162, 0, 68, 240)) + @Tab(COLORS_TAB) var titleBgCollapsed by setting("Title Background Collapsed", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var menuBarBg by setting("MenuBar Background", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var scrollbarBg by setting("Scrollbar Background", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var scrollbarGrab by setting("Scrollbar Grab", Color(159, 30, 83, 240)) + @Tab(COLORS_TAB) var scrollbarGrabHovered by setting("Scrollbar Grab Hovered", Color(198, 40, 105, 240)) + @Tab(COLORS_TAB) var scrollbarGrabActive by setting("Scrollbar Grab Active", Color(235, 49, 126, 240)) + @Tab(COLORS_TAB) var checkMark by setting("Check Mark", Color(255, 64, 148, 220)) + @Tab(COLORS_TAB) var sliderGrab by setting("Slider Grab", Color(207, 46, 117, 200)) + @Tab(COLORS_TAB) var sliderGrabActive by setting("Slider Grab Active", Color(241, 67, 143, 200)) + @Tab(COLORS_TAB) var button by setting("Button", Color(171, 32, 93, 102)) + @Tab(COLORS_TAB) var buttonHovered by setting("Button Hovered", Color(214, 45, 119, 102)) + @Tab(COLORS_TAB) var buttonActive by setting("Button Active", Color(255, 50, 140, 102)) + @Tab(COLORS_TAB) var header by setting("Header", Color(192, 30, 94, 115)) + @Tab(COLORS_TAB) var headerHovered by setting("Header Hovered", Color(255, 59, 136, 115)) + @Tab(COLORS_TAB) var headerActive by setting("Header Active", Color(202, 36, 101, 115)) + @Tab(COLORS_TAB) var separator by setting("Separator", Color(107, 0, 47, 128)) + @Tab(COLORS_TAB) var separatorHovered by setting("Separator Hovered", Color(146, 0, 64, 128)) + @Tab(COLORS_TAB) var separatorActive by setting("Separator Active", Color(186, 0, 82, 128)) + @Tab(COLORS_TAB) var resizeGrip by setting("Resize Grip", Color(214, 45, 119, 102)) + @Tab(COLORS_TAB) var resizeGripHovered by setting("Resize Grip Hovered", Color(214, 45, 119, 102)) + @Tab(COLORS_TAB) var resizeGripActive by setting("Resize Grip Active", Color(214, 45, 119, 102)) + @Tab(COLORS_TAB) var tab by setting("Tab", Color(121, 21, 65, 140)) + @Tab(COLORS_TAB) var tabHovered by setting("Tab Hovered", Color(169, 34, 94, 140)) + @Tab(COLORS_TAB) var tabActive by setting("Tab Active", Color(209, 34, 112, 140)) + @Tab(COLORS_TAB) var tabUnfocused by setting("Tab Unfocused", Color(121, 21, 65, 120)) + @Tab(COLORS_TAB) var tabUnfocusedActive by setting("Tab Unfocused Active", Color(196, 36, 107, 120)) + @Tab(COLORS_TAB) var dockingPreview by setting("Docking Preview", Color(208, 47, 117, 102)) + @Tab(COLORS_TAB) var dockingEmptyBg by setting("Docking Empty Background", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var plotLines by setting("Plot Lines", Color(178, 36, 95, 240)) + @Tab(COLORS_TAB) var plotLinesHovered by setting("Plot Lines Hovered", Color(209, 40, 110, 240)) + @Tab(COLORS_TAB) var plotHistogram by setting("Plot Histogram", Color(192, 32, 91, 255)) + @Tab(COLORS_TAB) var plotHistogramHovered by setting("Plot Histogram Hovered", Color(226, 38, 108, 255)) + @Tab(COLORS_TAB) var tableHeaderBg by setting("Table Header Background", Color(75, 0, 31, 240)) + @Tab(COLORS_TAB) var tableBorderStrong by setting("Table Border Strong", Color(88, 0, 36, 240)) + @Tab(COLORS_TAB) var tableBorderLight by setting("Table Border Light", Color(67, 0, 28, 240)) + @Tab(COLORS_TAB) var tableRowBg by setting("Table Row Background", Color(35, 0, 14, 240)) + @Tab(COLORS_TAB) var tableRowBgAlt by setting("Table Row Background Alt", Color(242, 140, 182, 240)) + @Tab(COLORS_TAB) var textSelectedBg by setting("Text Selected Background", Color(218, 54, 121, 240)) + @Tab(COLORS_TAB) var dragDropTarget by setting("Drag Drop Target", Color(218, 54, 121, 240)) + @Tab(COLORS_TAB) var navHighlight by setting("Nav Highlight", Color(218, 54, 121, 240)) + @Tab(COLORS_TAB) var navWindowingHighlight by setting("Nav Windowing Highlight", Color(242, 140, 182, 240)) + @Tab(COLORS_TAB) var navWindowingDimBg by setting("Nav Windowing Dim Background", Color(242, 140, 182, 240)) + @Tab(COLORS_TAB) var modalWindowDimBg by setting("Modal Window Dim Background", Color(35, 0, 14, 90)) + + val expandedModules = mutableSetOf() + fun isModuleExpanded(name: String) = expandedModules.contains(name) + fun toggleModuleExpanded(name: String) { + if (expandedModules.contains(name)) expandedModules.remove(name) + else expandedModules.add(name) + } + fun collapseAllModules() = expandedModules.clear() + fun expandAllModules(tag: ModuleTag) = ModuleRegistry.modules.filter { it.tag == tag }.forEach { expandedModules.add(it.name) } + + private val categoryFilters = mutableMapOf() + fun getCategoryFilter(name: String) = categoryFilters.getOrPut(name) { ImString(64) } + + fun tileWindows() { + val startX = 20f + val startY = MenuBar.height + 15f + val padding = 14f + val scale = currentScale + val windowWidth = 200f * scale + val displayWidth = DearImGui.io.displaySize.x + val cols = max(1, ((displayWidth - startX * 2) / (windowWidth + padding)).toInt()) + + var col = 0 + var row = 0 + val tags = if (developerMode) shownTags + ModuleTag.DEBUG else shownTags + tags.forEach { tag -> + val x = startX + col * (windowWidth + padding) + val y = startY + row * (280f * scale) + pendingPositions[tag.name] = x to y + col++ + if (col >= cols) { + col = 0 + row++ + } + } + } + + fun resetWindowPositions() { + pendingPositions.clear() + pendingSizes.clear() + val startX = 20f + val baseY = MenuBar.height + 12f + val padding = 14f + val scale = currentScale + val windowWidth = 200f * scale + val displayWidth = DearImGui.io.displaySize.x + val cols = max(1, ((displayWidth - startX * 2) / (windowWidth + padding)).toInt()) + + var col = 0 + var row = 0 + val tags = if (developerMode) shownTags + ModuleTag.DEBUG else shownTags + tags.forEach { tag -> + val x = startX + col * (windowWidth + padding) + val y = baseY + row * (280f * scale) + pendingPositions[tag.name] = x to y + col++ + if (col >= cols) { + col = 0 + row++ + } + } + } + + fun applyTheme(preset: ThemePreset) { + when (preset) { + ThemePreset.CUSTOM -> {} + ThemePreset.LAMBDA_VIOLET -> { + primaryColor = Color(130, 200, 255) + secondaryColor = Color(225, 130, 225) + windowBg = Color(35, 0, 14, 240) + childBg = Color(35, 0, 14, 240) + popupBg = Color(35, 0, 14, 240) + border = Color(130, 12, 60, 240) + borderShadow = Color(51, 0, 21, 240) + frameBg = Color(171, 32, 93, 102) + frameBgHovered = Color(214, 45, 119, 102) + frameBgActive = Color(255, 50, 140, 102) + titleBg = Color(125, 0, 50, 240) + titleBgActive = Color(162, 0, 68, 240) + titleBgCollapsed = Color(35, 0, 14, 240) + menuBarBg = Color(35, 0, 14, 240) + button = Color(171, 32, 93, 102) + buttonHovered = Color(214, 45, 119, 102) + buttonActive = Color(255, 50, 140, 102) + header = Color(192, 30, 94, 115) + headerHovered = Color(255, 59, 136, 115) + headerActive = Color(202, 36, 101, 115) + checkMark = Color(255, 64, 148, 220) + sliderGrab = Color(207, 46, 117, 200) + sliderGrabActive = Color(241, 67, 143, 200) + scrollbarBg = Color(35, 0, 14, 240) + scrollbarGrab = Color(159, 30, 83, 240) + scrollbarGrabHovered = Color(198, 40, 105, 240) + scrollbarGrabActive = Color(235, 49, 126, 240) + separator = Color(107, 0, 47, 128) + separatorHovered = Color(146, 0, 64, 128) + separatorActive = Color(186, 0, 82, 128) + } + ThemePreset.MIDNIGHT_BLUE -> { + primaryColor = Color(56, 189, 248) + secondaryColor = Color(129, 140, 248) + windowBg = Color(15, 20, 28, 245) + childBg = Color(15, 20, 28, 245) + popupBg = Color(18, 24, 36, 245) + border = Color(40, 60, 90, 240) + borderShadow = Color(10, 14, 20, 240) + frameBg = Color(30, 45, 70, 140) + frameBgHovered = Color(40, 65, 105, 160) + frameBgActive = Color(56, 189, 248, 140) + titleBg = Color(20, 30, 48, 245) + titleBgActive = Color(30, 50, 85, 245) + titleBgCollapsed = Color(15, 20, 28, 245) + menuBarBg = Color(12, 16, 24, 245) + button = Color(35, 55, 88, 140) + buttonHovered = Color(48, 75, 120, 160) + buttonActive = Color(56, 189, 248, 160) + header = Color(32, 50, 80, 160) + headerHovered = Color(45, 70, 115, 180) + headerActive = Color(56, 189, 248, 180) + checkMark = Color(56, 189, 248, 240) + sliderGrab = Color(56, 189, 248, 200) + sliderGrabActive = Color(125, 211, 252, 240) + scrollbarBg = Color(15, 20, 28, 245) + scrollbarGrab = Color(35, 55, 88, 240) + scrollbarGrabHovered = Color(50, 75, 120, 240) + scrollbarGrabActive = Color(56, 189, 248, 240) + separator = Color(30, 45, 70, 180) + separatorHovered = Color(45, 70, 110, 180) + separatorActive = Color(56, 189, 248, 180) + } + ThemePreset.NORDIC_FROST -> { + primaryColor = Color(0, 210, 255) + secondaryColor = Color(136, 192, 208) + windowBg = Color(24, 28, 36, 245) + childBg = Color(24, 28, 36, 245) + popupBg = Color(30, 35, 46, 245) + border = Color(55, 75, 95, 240) + borderShadow = Color(12, 16, 20, 240) + frameBg = Color(40, 52, 68, 140) + frameBgHovered = Color(55, 72, 95, 160) + frameBgActive = Color(0, 210, 255, 140) + titleBg = Color(30, 40, 52, 245) + titleBgActive = Color(42, 60, 80, 245) + titleBgCollapsed = Color(24, 28, 36, 245) + menuBarBg = Color(18, 22, 28, 245) + button = Color(44, 58, 76, 140) + buttonHovered = Color(60, 80, 105, 160) + buttonActive = Color(0, 210, 255, 160) + header = Color(40, 56, 75, 160) + headerHovered = Color(55, 78, 105, 180) + headerActive = Color(0, 210, 255, 180) + checkMark = Color(0, 210, 255, 240) + sliderGrab = Color(0, 210, 255, 200) + sliderGrabActive = Color(136, 235, 255, 240) + scrollbarBg = Color(24, 28, 36, 245) + scrollbarGrab = Color(44, 58, 76, 240) + scrollbarGrabHovered = Color(60, 80, 105, 240) + scrollbarGrabActive = Color(0, 210, 255, 240) + separator = Color(40, 55, 72, 180) + separatorHovered = Color(55, 75, 100, 180) + separatorActive = Color(0, 210, 255, 180) + } + ThemePreset.CYBERPUNK_NEON -> { + primaryColor = Color(255, 42, 133) + secondaryColor = Color(0, 240, 255) + windowBg = Color(12, 12, 16, 245) + childBg = Color(12, 12, 16, 245) + popupBg = Color(18, 18, 24, 245) + border = Color(255, 42, 133, 180) + borderShadow = Color(0, 0, 0, 240) + frameBg = Color(35, 20, 30, 150) + frameBgHovered = Color(60, 25, 45, 180) + frameBgActive = Color(255, 42, 133, 160) + titleBg = Color(25, 14, 22, 245) + titleBgActive = Color(180, 20, 90, 245) + titleBgCollapsed = Color(12, 12, 16, 245) + menuBarBg = Color(8, 8, 12, 245) + button = Color(45, 20, 35, 150) + buttonHovered = Color(80, 25, 55, 180) + buttonActive = Color(255, 42, 133, 180) + header = Color(60, 20, 42, 160) + headerHovered = Color(110, 25, 70, 180) + headerActive = Color(255, 42, 133, 180) + checkMark = Color(0, 240, 255, 255) + sliderGrab = Color(0, 240, 255, 220) + sliderGrabActive = Color(255, 42, 133, 240) + scrollbarBg = Color(12, 12, 16, 245) + scrollbarGrab = Color(60, 20, 42, 240) + scrollbarGrabHovered = Color(100, 25, 65, 240) + scrollbarGrabActive = Color(255, 42, 133, 240) + separator = Color(60, 20, 40, 180) + separatorHovered = Color(100, 25, 65, 180) + separatorActive = Color(0, 240, 255, 180) + } + ThemePreset.DRACULA -> { + primaryColor = Color(189, 147, 249) + secondaryColor = Color(255, 121, 198) + windowBg = Color(40, 42, 54, 245) + childBg = Color(40, 42, 54, 245) + popupBg = Color(48, 50, 64, 245) + border = Color(98, 114, 164, 200) + borderShadow = Color(20, 20, 28, 240) + frameBg = Color(68, 71, 90, 150) + frameBgHovered = Color(98, 114, 164, 180) + frameBgActive = Color(189, 147, 249, 150) + titleBg = Color(33, 34, 44, 245) + titleBgActive = Color(68, 71, 90, 245) + titleBgCollapsed = Color(33, 34, 44, 245) + menuBarBg = Color(28, 29, 38, 245) + button = Color(68, 71, 90, 150) + buttonHovered = Color(98, 114, 164, 180) + buttonActive = Color(189, 147, 249, 180) + header = Color(68, 71, 90, 160) + headerHovered = Color(98, 114, 164, 180) + headerActive = Color(189, 147, 249, 180) + checkMark = Color(80, 250, 123, 240) + sliderGrab = Color(189, 147, 249, 220) + sliderGrabActive = Color(255, 121, 198, 240) + scrollbarBg = Color(40, 42, 54, 245) + scrollbarGrab = Color(68, 71, 90, 240) + scrollbarGrabHovered = Color(98, 114, 164, 240) + scrollbarGrabActive = Color(189, 147, 249, 240) + separator = Color(68, 71, 90, 180) + separatorHovered = Color(98, 114, 164, 180) + separatorActive = Color(189, 147, 249, 180) + } + ThemePreset.EMERALD_OBSIDIAN -> { + primaryColor = Color(16, 185, 129) + secondaryColor = Color(52, 211, 153) + windowBg = Color(15, 23, 19, 245) + childBg = Color(15, 23, 19, 245) + popupBg = Color(20, 30, 25, 245) + border = Color(30, 70, 50, 220) + borderShadow = Color(8, 14, 10, 240) + frameBg = Color(25, 50, 38, 140) + frameBgHovered = Color(35, 75, 55, 160) + frameBgActive = Color(16, 185, 129, 150) + titleBg = Color(18, 32, 25, 245) + titleBgActive = Color(25, 60, 42, 245) + titleBgCollapsed = Color(15, 23, 19, 245) + menuBarBg = Color(10, 16, 12, 245) + button = Color(28, 58, 42, 140) + buttonHovered = Color(38, 80, 58, 160) + buttonActive = Color(16, 185, 129, 170) + header = Color(25, 55, 40, 160) + headerHovered = Color(35, 80, 56, 180) + headerActive = Color(16, 185, 129, 180) + checkMark = Color(16, 185, 129, 240) + sliderGrab = Color(16, 185, 129, 220) + sliderGrabActive = Color(52, 211, 153, 240) + scrollbarBg = Color(15, 23, 19, 245) + scrollbarGrab = Color(28, 58, 42, 240) + scrollbarGrabHovered = Color(38, 80, 58, 240) + scrollbarGrabActive = Color(16, 185, 129, 240) + separator = Color(28, 55, 40, 180) + separatorHovered = Color(38, 75, 55, 180) + separatorActive = Color(16, 185, 129, 180) + } + ThemePreset.MONOKAI_GOLD -> { + primaryColor = Color(230, 219, 116) + secondaryColor = Color(253, 151, 31) + windowBg = Color(39, 40, 34, 245) + childBg = Color(39, 40, 34, 245) + popupBg = Color(48, 49, 42, 245) + border = Color(90, 85, 65, 220) + borderShadow = Color(20, 20, 16, 240) + frameBg = Color(60, 58, 46, 140) + frameBgHovered = Color(85, 80, 60, 160) + frameBgActive = Color(230, 219, 116, 140) + titleBg = Color(30, 31, 26, 245) + titleBgActive = Color(65, 62, 48, 245) + titleBgCollapsed = Color(30, 31, 26, 245) + menuBarBg = Color(24, 25, 20, 245) + button = Color(60, 58, 46, 140) + buttonHovered = Color(85, 80, 60, 160) + buttonActive = Color(230, 219, 116, 160) + header = Color(60, 58, 46, 160) + headerHovered = Color(85, 80, 60, 180) + headerActive = Color(230, 219, 116, 180) + checkMark = Color(166, 226, 46, 240) + sliderGrab = Color(230, 219, 116, 220) + sliderGrabActive = Color(253, 151, 31, 240) + scrollbarBg = Color(39, 40, 34, 245) + scrollbarGrab = Color(60, 58, 46, 240) + scrollbarGrabHovered = Color(85, 80, 60, 240) + scrollbarGrabActive = Color(230, 219, 116, 240) + separator = Color(60, 58, 46, 180) + separatorHovered = Color(85, 80, 60, 180) + separatorActive = Color(230, 219, 116, 180) + } + } + } + + fun syncThemeToAccent(accent: Color) { + primaryColor = accent + val r = accent.red + val g = accent.green + val b = accent.blue + header = Color(r, g, b, 120) + headerHovered = Color((r * 1.15f).coerceAtMost(255f).toInt(), (g * 1.15f).coerceAtMost(255f).toInt(), (b * 1.15f).coerceAtMost(255f).toInt(), 160) + headerActive = Color((r * 0.9f).toInt(), (g * 0.9f).toInt(), (b * 0.9f).toInt(), 180) + buttonActive = Color(r, g, b, 150) + checkMark = Color(r, g, b, 230) + sliderGrab = Color(r, g, b, 200) + sliderGrabActive = Color((r * 1.2f).coerceAtMost(255f).toInt(), (g * 1.2f).coerceAtMost(255f).toInt(), (b * 1.2f).coerceAtMost(255f).toInt(), 230) + scrollbarGrabActive = Color(r, g, b, 230) + border = Color((r * 0.6f).toInt(), (g * 0.6f).toInt(), (b * 0.6f).toInt(), 200) + } init { listenUnsafe { if (!open) return@listenUnsafe @@ -322,15 +662,48 @@ object ClickGuiLayout : Loadable, Config( ImGui.setNextWindowPos(nextX, baseY, ImGuiCond.FirstUseEver) } + val scale = currentScale + ImGui.setNextWindowSize(200f * scale, 0f, ImGuiCond.FirstUseEver) pendingSizes[tag.name]?.let { (w, h) -> ImGui.setNextWindowSizeConstraints(w, h, w, h) + } ?: run { + ImGui.setNextWindowSizeConstraints(185f * scale, 0f, 360f * scale, io.displaySize.y * 0.88f) } + val windowFlags = if (allowWindowCollapse) ImGuiWindowFlags.None else ImGuiWindowFlags.NoCollapse - window(tag.name, flags = ImGuiWindowFlags.NoCollapse) { - ModuleRegistry.modules - .filter { it.tag == tag && it.showInClickGui.value } + val categoryModules = ModuleRegistry.modules.filter { it.tag == tag && it.showInClickGui.value } + val enabledCount = categoryModules.count { it.isEnabled } + val totalCount = categoryModules.size + + val windowTitle = if (showCategoryCounts) { + "${tag.name} [$enabledCount/$totalCount]###Category-${tag.name}" + } else { + "${tag.name}###Category-${tag.name}" + } + + window(windowTitle, flags = windowFlags) { + // Optional category search filter + if (categoryWindowSearch) { + val filter = getCategoryFilter(tag.name) + withItemWidth(ImGui.getContentRegionAvailX()) { + ImGui.inputTextWithHint("##cat-filter-${tag.name}", "Filter ${tag.name}...", filter) + } + separator() + } + + val filterText = if (categoryWindowSearch) getCategoryFilter(tag.name).get().trim() else "" + categoryModules + .filter { filterText.isEmpty() || it.name.contains(filterText, ignoreCase = true) } .forEach { with(ModuleEntry(it)) { buildLayout() } } + popupContextWindow("##cat-ctx-${tag.name}") { + menuItem("Tile Windows (Auto-Arrange)") { tileWindows() } + menuItem("Reset Layout") { resetWindowPositions() } + separator() + menuItem("Expand All in ${tag.name}") { expandAllModules(tag) } + menuItem("Collapse All") { collapseAllModules() } + } + snapOverlays[tag.name]?.let { vis -> drawSnapLines(vis.snapX, vis.kindX, vis.snapY, vis.kindY) } @@ -350,7 +723,6 @@ object ClickGuiLayout : Loadable, Config( } renderQuickSearch() - if (developerMode) { ImGui.showDemoWindow() ImPlot.showDemoWindow() diff --git a/src/main/kotlin/com/lambda/gui/components/HudGuiLayout.kt b/src/main/kotlin/com/lambda/gui/components/HudGuiLayout.kt index b070261d3..99cb830d9 100644 --- a/src/main/kotlin/com/lambda/gui/components/HudGuiLayout.kt +++ b/src/main/kotlin/com/lambda/gui/components/HudGuiLayout.kt @@ -134,6 +134,10 @@ object HudGuiLayout : Loadable, Config( huds.forEach { hud -> registerHudElement(hud) } + + if (ClickGuiLayout.open) { + renderHudStatusBar() + } } } } @@ -176,11 +180,18 @@ object HudGuiLayout : Loadable, Config( with(hud) { buildLayout() } if (ClickGuiLayout.open) { + if (!isLocked && ImGui.isWindowHovered()) { + lambdaTooltip("Drag to move ${hud.name} • Right-click for options") + } + popupContextWindow("##ctx-${hud.name}") { menuItem("Remove HUD Element") { hud.disable() SnapHandler.unregisterElement(hud.name) } + menuItem(if (isLocked) "Unlock HUD" else "Lock HUD") { + isLocked = !isLocked + } separator() buildConfigSettingsContext(hud) } @@ -293,4 +304,42 @@ object HudGuiLayout : Loadable, Config( // BL: 0.5pi -> pi strokeArc(blCx, blCy, HALF_PI_F, PI_F) } + + private fun ImGuiBuilder.renderHudStatusBar() { + val statusText = if (isLocked) "HUD: Locked (Click to unlock)" else "HUD: Unlocked (Draggable • Click to lock)" + val textW = ImGui.calcTextSize(statusText).x + val padX = 14f + val padY = 5f + val pillW = textW + padX * 2f + val pillH = ImGui.getTextLineHeight() + padY * 2f + val pillX = (io.displaySize.x - pillW) * 0.5f + val pillY = io.displaySize.y - pillH - 12f + + ImGui.setNextWindowPos(pillX, pillY) + ImGui.setNextWindowSize(pillW, pillH) + withStyleVar(ImGuiStyleVar.WindowRounding, 8f) { + withStyleVar(ImGuiStyleVar.WindowPadding, padX, padY) { + val primary = ClickGuiLayout.primaryColor + val bgAlpha = if (isLocked) 170 else 220 + val pillBg = if (isLocked) Color(24, 24, 24, bgAlpha) else Color((primary.red * 0.2f).toInt(), (primary.green * 0.2f).toInt(), (primary.blue * 0.2f).toInt(), bgAlpha) + val borderR = if (isLocked) 0.35f else primary.red / 255f + val borderG = if (isLocked) 0.35f else primary.green / 255f + val borderB = if (isLocked) 0.35f else primary.blue / 255f + withStyleColor(ImGuiCol.WindowBg, pillBg.red / 255f, pillBg.green / 255f, pillBg.blue / 255f, pillBg.alpha / 255f) { + withStyleColor(ImGuiCol.Border, borderR, borderG, borderB, 0.7f) { + window("##hud-status-bar", flags = ImGuiWindowFlags.NoDecoration or ImGuiWindowFlags.NoMove or ImGuiWindowFlags.NoDocking) { + if (isLocked) { + textDisabled(statusText) + } else { + ImGui.textColored(primary.red / 255f, primary.green / 255f, primary.blue / 255f, 1f, statusText) + } + if (ImGui.isWindowHovered() && isMouseClicked()) { + isLocked = !isLocked + } + } + } + } + } + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt b/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt index 7c73ae9ab..a9adf6ace 100644 --- a/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt +++ b/src/main/kotlin/com/lambda/gui/components/ModuleEntry.kt @@ -20,36 +20,129 @@ package com.lambda.gui.components import com.lambda.gui.Layout import com.lambda.gui.components.SettingsWidget.buildConfigSettingsContext import com.lambda.gui.dsl.ImGuiBuilder +import com.lambda.imgui.ImColor import com.lambda.imgui.ImGui +import com.lambda.imgui.ImVec2 +import com.lambda.imgui.flag.ImGuiCol import com.lambda.imgui.flag.ImGuiHoveredFlags +import com.lambda.imgui.flag.ImGuiMouseButton import com.lambda.imgui.flag.ImGuiPopupFlags +import com.lambda.imgui.flag.ImGuiStyleVar import com.lambda.module.Module -class ModuleEntry(val module: Module): Layout { +class ModuleEntry(val module: Module) : Layout { override fun ImGuiBuilder.buildLayout() { - selectable(module.name, selected = module.isEnabled) { + val isEnabled = module.isEnabled + val isExpanded = ClickGuiLayout.isModuleExpanded(module.name) + val primary = ClickGuiLayout.primaryColor + val scale = ClickGuiLayout.currentScale + + val rowStartY = cursorPosY + val textHeight = ImGui.getTextLineHeight() + val rowHeight = textHeight + style.framePadding.y * 2f + + // Visual highlight / accent bar for enabled modules + if (isEnabled && ClickGuiLayout.highlightEnabledModules) { + val minX = ImGui.getWindowPosX() + style.windowPadding.x * 0.4f + val maxX = ImGui.getWindowPosX() + ImGui.getWindowWidth() - style.windowPadding.x * 0.4f + val minY = ImGui.getWindowPosY() + rowStartY - ImGui.getScrollY() + val maxY = minY + rowHeight + + // Soft tint background + val accentCol = ImColor.rgba(primary.red, primary.green, primary.blue, 25) + windowDrawList.addRectFilled(minX, minY, maxX, maxY, accentCol, style.frameRounding) + + // Distinct left accent bar + val barWidth = 2.5f * scale + val barCol = ImColor.rgba(primary.red, primary.green, primary.blue, 240) + windowDrawList.addRectFilled(minX, minY, minX + barWidth, maxY, barCol, style.frameRounding) + } + + // Invisible selectable covering the entire row + selectable("##sel-${module.name}", selected = false, 0, ImVec2(0f, rowHeight)) { module.toggle() } + val isRowHovered = ImGui.isItemHovered() lambdaTooltip(module.description) - val popupId = "##ctx-${module.name}" - val entryId = getId(popupId) - + // Right-click handling: toggle inline settings expansion inside the category window onItemHover(ImGuiHoveredFlags.AllowWhenBlockedByPopup) { - if (isMouseClicked() && isPopupOpen(popupId)) suppressedEntryId = entryId - if (isMouseReleased() && suppressedEntryId != entryId) openPopup(popupId) + if (isMouseClicked(ImGuiMouseButton.Right)) { + ClickGuiLayout.toggleModuleExpanded(module.name) + } } - if (isMouseReleased() && suppressedEntryId == entryId) suppressedEntryId = null + // Measure right-side elements + val bind = module.keybind + val hasBind = (bind.isKeyBind || bind.isMouseBind) && ClickGuiLayout.showKeybindBadges + val bindText = if (hasBind) "[${bind.name}]" else "" + val bindWidth = if (hasBind) ImGui.calcTextSize(bindText).x + 6f else 0f + val indicatorWidth = 14f * scale - ImGui.setNextWindowSizeConstraints(0f, 0f, Float.MAX_VALUE, io.displaySize.y * 0.5f) - popupContextItem(popupId, ImGuiPopupFlags.MouseButtonRight) { - buildConfigSettingsContext(module) + val winLeft = ImGui.getWindowPosX() + val winWidth = ImGui.getWindowWidth() + val rightEdge = winLeft + winWidth - style.windowPadding.x - 4f + + // Draw keybind badge if present + if (hasBind) { + val bindX = rightEdge - indicatorWidth - bindWidth + val textY = ImGui.getWindowPosY() + rowStartY + style.framePadding.y - ImGui.getScrollY() + windowDrawList.addText(bindX, textY, ImColor.rgba(255, 205, 75, 230), bindText) } - } - private companion object { - /** Entry whose reopen is pending suppression; only one item can be pressed at a time. */ - var suppressedEntryId: Int? = null + // Draw expander indicator (vector-drawn, never broken or missing glyph!) + val triCenterY = ImGui.getWindowPosY() + rowStartY + rowHeight * 0.5f - ImGui.getScrollY() + val triCenterX = rightEdge - 5f * scale + val triSize = 3.5f * scale + + if (isExpanded) { + // Downward pointing arrow for expanded + windowDrawList.addTriangleFilled( + triCenterX - triSize, triCenterY - triSize * 0.5f, + triCenterX + triSize, triCenterY - triSize * 0.5f, + triCenterX, triCenterY + triSize * 0.7f, + ImColor.rgba(primary.red, primary.green, primary.blue, 220) + ) + } else if (isRowHovered) { + // Right-pointing subtle arrow on hover to indicate settings exist + windowDrawList.addTriangleFilled( + triCenterX - triSize * 0.5f, triCenterY - triSize, + triCenterX - triSize * 0.5f, triCenterY + triSize, + triCenterX + triSize * 0.7f, triCenterY, + ImColor.rgba(200, 200, 200, 160) + ) + } + + // Draw Module Name (clipped if needed to prevent overlap with badges) + val nameIndent = if (isEnabled && ClickGuiLayout.highlightEnabledModules) 6f * scale else 2f + val nameX = winLeft + style.windowPadding.x + nameIndent + val nameY = ImGui.getWindowPosY() + rowStartY + style.framePadding.y - ImGui.getScrollY() + val maxNameWidth = (rightEdge - indicatorWidth - bindWidth - nameX - 4f).coerceAtLeast(20f) + + val nameCol = if (isEnabled) { + ImColor.rgba(primary.red, primary.green, primary.blue, 255) + } else { + val c = ClickGuiLayout.text + ImColor.rgba(c.red, c.green, c.blue, c.alpha) + } + + // Use clip rect to guarantee text NEVER bleeds into the keybind badge + windowDrawList.pushClipRect(nameX, nameY - 2f, nameX + maxNameWidth, nameY + textHeight + 2f, true) + windowDrawList.addText(nameX, nameY, nameCol, module.name) + windowDrawList.popClipRect() + + + // Inline expanded settings view + if (isExpanded) { + val childBgCol = ClickGuiLayout.childBg + withStyleVar(ImGuiStyleVar.ChildRounding, 4f) { + withStyleColor(ImGuiCol.ChildBg, childBgCol.red / 255f, childBgCol.green / 255f, childBgCol.blue / 255f, childBgCol.alpha / 255f) { + indent(8f) + buildConfigSettingsContext(module) + unindent(8f) + separator() + } + } + } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt b/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt index e21cec084..affba406f 100644 --- a/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt +++ b/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt @@ -23,11 +23,13 @@ import com.lambda.command.LambdaCommand import com.lambda.config.Config import com.lambda.config.ConfigLoader import com.lambda.config.entries.Setting +import com.lambda.config.settings.comparable.BooleanSetting import com.lambda.event.events.ButtonEvent import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.gui.LambdaScreen import com.lambda.gui.Layout import com.lambda.gui.dsl.ImGuiBuilder +import com.lambda.imgui.ImColor import com.lambda.imgui.ImGui import com.lambda.imgui.flag.ImGuiHoveredFlags import com.lambda.imgui.flag.ImGuiInputTextFlags @@ -43,19 +45,36 @@ import com.lambda.util.KeyCode import com.lambda.util.StringUtils.capitalize import com.lambda.util.StringUtils.levenshteinDistance import net.minecraft.client.gui.screen.ChatScreen +import net.minecraft.client.util.InputUtil +import org.lwjgl.glfw.GLFW import kotlin.math.max -// ToDo: Add support for searching of menu bar entries @Suppress("unused") object QuickSearch { private val searchInput = ImString(256) var isOpen = false private set + var lastClosedTimestamp = 0L + private set private var shouldFocus = false private var pendingClose = false private var lastShiftPressTime = 0L private var lastShiftKeyCode = -1 + var selectedIndex = 0 + private var needScrollToSelected = false + private var lastSearchedQuery = "" + + enum class SearchFilter(val label: String) { + ALL("All"), + MODULES("Modules"), + SETTINGS("Settings"), + COMMANDS("Commands") + } + + var currentFilter = SearchFilter.ALL + private var currentResults: List = emptyList() + private const val DOUBLE_SHIFT_WINDOW_MS = 500L private const val MAX_RESULTS = 50 private const val POPUP_ID = "QuickSearch" @@ -75,46 +94,129 @@ object QuickSearch { } interface SearchResult : Layout { + val title: String val breadcrumb: String + val category: String + val description: String + fun onActivate() } private class ModuleResult(val module: Module) : SearchResult { - override val breadcrumb = if (module is HudModule) "HUD" else "Module" + override val title: String = module.name + override val breadcrumb: String = if (module is HudModule) "HUD" else module.tag.name + override val category: String = if (module is HudModule) "HUD" else module.tag.name + override val description: String = module.description + + override fun onActivate() { + module.toggle() + } override fun ImGuiBuilder.buildLayout() { - with(ModuleEntry(module)) { - buildLayout { - withItemWidth(ImGui.getContentRegionAvailX()) { - buildLayout() - } - } + val isEnabled = module.isEnabled + val primary = ClickGuiLayout.primaryColor + + // Category tag + ImGui.textColored(primary.red / 255f, primary.green / 255f, primary.blue / 255f, 1f, "[${category.uppercase()}]") + sameLine() + + // Module name + text(module.name) + sameLine() + + // Status badge + if (isEnabled) { + ImGui.textColored(0.2f, 0.9f, 0.3f, 1.0f, "[ON]") + } else { + ImGui.textColored(0.55f, 0.55f, 0.55f, 1.0f, "[OFF]") + } + + // Keybind badge + val bind = module.keybind + if (bind.isKeyBind || bind.isMouseBind) { + sameLine() + ImGui.textColored(1.0f, 0.8f, 0.2f, 1.0f, "[${bind.name}]") + } + + // Action button + val btnLabel = if (isEnabled) "Disable##m-${module.name}" else "Enable##m-${module.name}" + val btnW = ImGui.calcTextSize(if (isEnabled) "Disable" else "Enable").x + style.framePadding.x * 2f + sameLine(windowContentRegionMaxX - btnW - style.windowPadding.x) + smallButton(btnLabel) { + module.toggle() + } + + if (module.description.isNotBlank()) { + textDisabled(" ${module.description}") } } } private class CommandResult(val command: LambdaCommand) : SearchResult { - override val breadcrumb = "Command" + override val title: String = command.name.capitalize() + override val breadcrumb: String = "Command" + override val category: String = "Command" + override val description: String = command.description + + override fun onActivate() { + close() + mc.setScreen(ChatScreen("${CommandRegistry.prefix}${command.name} ", true)) + } + override fun ImGuiBuilder.buildLayout() { - text(command.name.capitalize()) + ImGui.textColored(1.0f, 0.6f, 0.2f, 1.0f, "[COMMAND]") sameLine() - smallButton("Insert") { mc.setScreen(ChatScreen("${CommandRegistry.prefix}${command.name} ", true)) } + text("${CommandRegistry.prefix}${command.name}") + + val btnLabel = "Insert##cmd-${command.name}" + val btnW = ImGui.calcTextSize("Insert").x + style.framePadding.x * 2f + sameLine(windowContentRegionMaxX - btnW - style.windowPadding.x) + smallButton(btnLabel) { + onActivate() + } + if (command.description.isNotBlank()) { - sameLine() - textDisabled(command.description) + textDisabled(" ${command.description}") } } } private class SettingResult(val setting: Setting<*>, val config: Config) : SearchResult { + override val title: String = setting.name override val breadcrumb: String by lazy { buildSettingBreadcrumb(config.name, setting) } + override val category: String = "Setting" + override val description: String = setting.description + + override fun onActivate() { + if (setting is BooleanSetting) { + setting.value = !setting.value + } + } override fun ImGuiBuilder.buildLayout() { - with(setting) { - buildLayout { - withItemWidth(ImGui.getContentRegionAvailX()) { - buildLayout() - } + ImGui.textColored(0.4f, 0.7f, 1.0f, 1.0f, "[SETTING]") + sameLine() + text(setting.name) + sameLine() + textDisabled("($breadcrumb)") + + // Quick toggle if boolean + if (setting is BooleanSetting) { + val stateText = if (setting.value) "Disable" else "Enable" + val btnW = ImGui.calcTextSize(stateText).x + style.framePadding.x * 2f + sameLine(windowContentRegionMaxX - btnW - style.windowPadding.x) + smallButton("$stateText##st-${setting.name}") { + setting.value = !setting.value } + } else { + val valStr = setting.value.toString() + val valPreview = if (valStr.length > 20) valStr.take(18) + "…" else valStr + val previewW = ImGui.calcTextSize(valPreview).x + style.framePadding.x * 2f + sameLine(windowContentRegionMaxX - previewW - style.windowPadding.x) + textDisabled(valPreview) + } + + if (setting.description.isNotBlank()) { + textDisabled(" ${setting.description}") } } } @@ -123,6 +225,7 @@ object QuickSearch { isOpen = true shouldFocus = true pendingClose = false + selectedIndex = 0 searchInput.clear() } @@ -130,26 +233,41 @@ object QuickSearch { isOpen = false shouldFocus = false pendingClose = true + lastClosedTimestamp = System.currentTimeMillis() } fun toggle() { if (isOpen) close() else open() } + fun moveSelection(delta: Int) { + if (currentResults.isEmpty()) return + selectedIndex = (selectedIndex + delta).let { + if (it < 0) currentResults.lastIndex + else if (it >= currentResults.size) 0 + else it + } + needScrollToSelected = true + } + + fun activateSelected() { + currentResults.getOrNull(selectedIndex)?.onActivate() + } + fun ImGuiBuilder.renderQuickSearch() { if (!isOpen && !pendingClose) return if (isOpen) openPopup(POPUP_ID) ImGui.setNextFrameWantCaptureKeyboard(true) - val maxW = io.displaySize.x * 0.5f - val maxH = io.displaySize.y * 0.5f + val maxW = (io.displaySize.x * 0.55f).coerceAtLeast(420f) + val maxH = (io.displaySize.y * 0.55f).coerceAtLeast(300f) val popupX = (io.displaySize.x - maxW) * 0.5f - val popupY = io.displaySize.y * 0.3f + val popupY = (io.displaySize.y - maxH) * 0.28f ImGui.setNextWindowPos(popupX, popupY) ImGui.setNextWindowSize(maxW, 0f) - ImGui.setNextWindowSizeConstraints(0f, 0f, maxW, maxH) + ImGui.setNextWindowSizeConstraints(maxW, 0f, maxW, maxH) popupModal(POPUP_ID, WINDOW_FLAGS) { if (pendingClose) { @@ -168,46 +286,137 @@ object QuickSearch { shouldFocus = false } + // Search Header & Input Box withItemWidth(ImGui.getContentRegionAvailX()) { - withStyleVar(ImGuiStyleVar.FramePadding, style.framePadding.x, style.framePadding.y) { + withStyleVar(ImGuiStyleVar.FramePadding, style.framePadding.x * 1.5f, style.framePadding.y * 1.5f) { ImGui.inputTextWithHint( "##qs-input", - "Type to search modules, settings, and commands...", + "Search modules, settings, commands... (Ctrl+F, Esc to close)", searchInput, ImGuiInputTextFlags.AutoSelectAll ) } } - val query = searchInput.get().trim() - if (query.isEmpty()) return@popupModal + val rawInput = searchInput.get().trim() + + // Detect prefix filters (m: modules, s: settings, c: commands) + val (effectiveFilter, query) = when { + rawInput.startsWith("m:", ignoreCase = true) || rawInput.startsWith("mod:", ignoreCase = true) -> { + SearchFilter.MODULES to rawInput.substringAfter(':').trim() + } + rawInput.startsWith("s:", ignoreCase = true) || rawInput.startsWith("set:", ignoreCase = true) -> { + SearchFilter.SETTINGS to rawInput.substringAfter(':').trim() + } + rawInput.startsWith("c:", ignoreCase = true) || rawInput.startsWith("cmd:", ignoreCase = true) -> { + SearchFilter.COMMANDS to rawInput.substringAfter(':').trim() + } + else -> currentFilter to rawInput + } + + // Category Filter Buttons + cursorPosY += 2f + SearchFilter.entries.forEach { filter -> + val isSelected = effectiveFilter == filter + val label = filter.label + + if (isSelected) { + val primary = ClickGuiLayout.primaryColor + withStyleColor(com.lambda.imgui.flag.ImGuiCol.Button, primary.red / 255f, primary.green / 255f, primary.blue / 255f, 0.8f) { + smallButton("$label##filter") { + currentFilter = filter + selectedIndex = 0 + } + } + } else { + smallButton("$label##filter") { + currentFilter = filter + selectedIndex = 0 + } + } + sameLine(0f, 6f) + } + newLine() + separator() + + val results = if (query.isEmpty()) { + SearchService.getQuickAccessList(effectiveFilter) + } else { + SearchService.performSearch(query, effectiveFilter) + } + + if (query != lastSearchedQuery) { + lastSearchedQuery = query + selectedIndex = 0 + } + + currentResults = results - val results = SearchService.performSearch(query) if (results.isEmpty()) { - textDisabled("Nothing found.") + if (query.isNotEmpty()) { + textDisabled("No results found for \"$query\".") + } else { + textDisabled("Type to search or select a filter tab above.") + } + renderFooterTips() return@popupModal } - val rowH = frameHeightWithSpacing + val rowH = frameHeightWithSpacing * 1.9f val topArea = cursorPosY + style.windowPadding.y - val listH = (results.size * rowH).coerceAtMost(maxH - topArea).coerceAtLeast(rowH) + val listH = (results.size * rowH).coerceAtMost(maxH - topArea - 30f).coerceAtLeast(rowH) child("qs_rows", 0f, listH, false) { results.forEachIndexed { idx, result -> withId(idx) { + val isSelected = idx == selectedIndex + val startY = cursorPosY + + if (isSelected && needScrollToSelected) { + ImGui.setScrollHereY(0.5f) + needScrollToSelected = false + } + + // Background highlight for selected row + val highlightAlpha = if (isSelected) 85 else 0 + if (highlightAlpha > 0) { + val minX = ImGui.getWindowPosX() + style.windowPadding.x + val maxX = ImGui.getWindowPosX() + ImGui.getWindowWidth() - style.windowPadding.x + val minY = ImGui.getWindowPosY() + startY - ImGui.getScrollY() + val maxY = minY + rowH + val col = ClickGuiLayout.headerHovered + val packedCol = ImColor.rgba(col.red, col.green, col.blue, highlightAlpha) + windowDrawList.addRectFilled(minX, minY, maxX, maxY, packedCol, style.frameRounding) + } + + // Interactive selectable for row selection and double-click activation + selectable("##row-sel-$idx", isSelected) { + selectedIndex = idx + result.onActivate() + } + if (ImGui.isItemHovered()) { + selectedIndex = idx + } + + // Overlay content + cursorPosY = startY + 2f with(result) { - if (breadcrumb.isNotBlank()) { - textDisabled(breadcrumb) - sameLine() - } buildLayout() } + cursorPosY = startY + rowH } } } + + renderFooterTips() } } + private fun ImGuiBuilder.renderFooterTips() { + separator() + textDisabled("Navigate: [↑/↓] • Execute: [Enter] • Close: [Esc] • Prefixes: m: s: c:") + } + private object SearchService { private data class RankedSearchResult(val result: SearchResult, val score: Int) @@ -215,92 +424,99 @@ object QuickSearch { private const val HUD_MODULE_PRIORITY_BONUS = 270 private const val COMMAND_PRIORITY_BONUS = 200 - /** - * Calculates a relevance score for a query against a target string. - * Returns 0 for no match. Higher scores are better. - * The `lenient` flag adjusts the threshold for fuzzy matching. - */ + fun getQuickAccessList(filter: SearchFilter): List { + val list = mutableListOf() + if (filter == SearchFilter.ALL || filter == SearchFilter.MODULES) { + // Show enabled modules first, then prominent default modules + val enabled = ModuleRegistry.modules.filter { it.isEnabled }.map { ModuleResult(it) } + list.addAll(enabled) + if (list.size < 8) { + val defaults = ModuleRegistry.modules.filter { !it.isEnabled }.take(10 - list.size).map { ModuleResult(it) } + list.addAll(defaults) + } + } + if (filter == SearchFilter.COMMANDS) { + list.addAll(CommandRegistry.commands.take(10).map { CommandResult(it) }) + } + return list.take(MAX_RESULTS) + } + private fun calculateScore(query: String, target: String, lenient: Boolean = false): Int { if (query.isEmpty() || target.isEmpty()) return 0 - // 1. Strong Matches (Exact, Prefix, Substring) if (target == query) return 200 if (target.startsWith(query)) { val completeness = (query.length * 50) / target.length - return 100 + completeness // Score: 101 - 150 + return 100 + completeness } if (target.contains(query)) { val completeness = (query.length * 40) / target.length - return 50 + completeness // Score: 51 - 90 + return 50 + completeness } - // 2. Weak Match (Fuzzy) val distance = query.levenshteinDistance(target) val strictThreshold = (query.length / 3).coerceAtLeast(1).coerceAtMost(4) val lenientThreshold = (query.length / 2).coerceAtLeast(2).coerceAtMost(6) val threshold = if (lenient) lenientThreshold else strictThreshold return if (distance <= threshold) { - (50 - (distance * 10)).coerceAtLeast(1) // Score: 1-40 + (50 - (distance * 10)).coerceAtLeast(1) } else { 0 } } - /** - * Performs a search and returns a list of ranked results. This is the internal - * implementation that can be run in strict or lenient mode. - */ - private fun searchInternal(query: String, lenient: Boolean): List { + private fun searchInternal(query: String, filter: SearchFilter, lenient: Boolean): List { val lowerCaseQuery = query.lowercase() - val moduleResults = ModuleRegistry.modules.mapNotNull { module -> - val nameScore = calculateScore(lowerCaseQuery, module.name.lowercase(), lenient) - val tagScore = calculateScore(lowerCaseQuery, module.tag.name.lowercase(), lenient) - val bestScore = max(nameScore, tagScore) - - if (bestScore > 0) { - when(module) { - is HudModule -> RankedSearchResult(ModuleResult(module), bestScore + HUD_MODULE_PRIORITY_BONUS) - else -> RankedSearchResult(ModuleResult(module), bestScore + MODULE_PRIORITY_BONUS) - } - } else null - } + val moduleResults = if (filter == SearchFilter.ALL || filter == SearchFilter.MODULES) { + ModuleRegistry.modules.mapNotNull { module -> + val nameScore = calculateScore(lowerCaseQuery, module.name.lowercase(), lenient) + val tagScore = calculateScore(lowerCaseQuery, module.tag.name.lowercase(), lenient) + val bestScore = max(nameScore, tagScore) - val commandResults = CommandRegistry.commands.mapNotNull { command -> - val nameScore = calculateScore(lowerCaseQuery, command.name.lowercase(), lenient) - val aliasScore = command.aliases.maxOfOrNull { calculateScore(lowerCaseQuery, it.lowercase(), lenient) } ?: 0 - val bestScore = max(nameScore, aliasScore) + if (bestScore > 0) { + when (module) { + is HudModule -> RankedSearchResult(ModuleResult(module), bestScore + HUD_MODULE_PRIORITY_BONUS) + else -> RankedSearchResult(ModuleResult(module), bestScore + MODULE_PRIORITY_BONUS) + } + } else null + } + } else emptyList() - if (bestScore > 0) { - RankedSearchResult(CommandResult(command), bestScore + COMMAND_PRIORITY_BONUS) - } else null - } + val commandResults = if (filter == SearchFilter.ALL || filter == SearchFilter.COMMANDS) { + CommandRegistry.commands.mapNotNull { command -> + val nameScore = calculateScore(lowerCaseQuery, command.name.lowercase(), lenient) + val aliasScore = command.aliases.maxOfOrNull { calculateScore(lowerCaseQuery, it.lowercase(), lenient) } ?: 0 + val bestScore = max(nameScore, aliasScore) - val settingResults = buildList { - ConfigLoader.configCategories.forEach { category -> - category.configs.forEach { config -> - config.settingLayers.forEachEntry { _, single -> - val setting = single.entry - if (setting.visibility()) { - val score = calculateScore(lowerCaseQuery, setting.name.lowercase(), lenient) - if (score > 0) add(RankedSearchResult(SettingResult(setting, config), score)) + if (bestScore > 0) { + RankedSearchResult(CommandResult(command), bestScore + COMMAND_PRIORITY_BONUS) + } else null + } + } else emptyList() + + val settingResults = if (filter == SearchFilter.ALL || filter == SearchFilter.SETTINGS) { + buildList { + ConfigLoader.configCategories.forEach { category -> + category.configs.forEach { config -> + config.settingLayers.forEachEntry { _, single -> + val setting = single.entry + if (setting.visibility()) { + val score = calculateScore(lowerCaseQuery, setting.name.lowercase(), lenient) + if (score > 0) add(RankedSearchResult(SettingResult(setting, config), score)) + } } } } } - } + } else emptyList() return moduleResults + commandResults + settingResults } - /** - * Main search entry point. It first attempts a strict search. If no results - * are found, it falls back to a more lenient fuzzy search. - */ - fun performSearch(query: String): List { - // First pass: strict search for high-quality matches. - val strictResults = searchInternal(query, lenient = false) + fun performSearch(query: String, filter: SearchFilter = SearchFilter.ALL): List { + val strictResults = searchInternal(query, filter, lenient = false) if (strictResults.isNotEmpty()) { return strictResults .sortedByDescending { it.score } @@ -308,8 +524,7 @@ object QuickSearch { .take(MAX_RESULTS) } - // Second pass: if nothing was found, perform a more generous fuzzy search. - return searchInternal(query, lenient = true) + return searchInternal(query, filter, lenient = true) .sortedByDescending { it.score } .map { it.result } .take(MAX_RESULTS) @@ -324,19 +539,63 @@ object QuickSearch { private fun handleKeyPress(event: ButtonEvent.Keyboard.Press) { if (AutoUpdater.showInstallModal || AutoUpdater.showUninstallModal) return - if ((!event.isPressed || event.isRepeated) || - !(event.keyCode == KeyCode.LeftShift.code || event.keyCode == KeyCode.RightShift.code)) return - - val currentTime = System.currentTimeMillis() - if (lastShiftKeyCode == event.keyCode && - currentTime - lastShiftPressTime <= DOUBLE_SHIFT_WINDOW_MS - ) { + if (!event.isPressed || event.isRepeated) return + + // Navigation when QuickSearch is open + if (isOpen) { + when (event.keyCode) { + GLFW.GLFW_KEY_DOWN -> { + moveSelection(1) + event.cancel() + return + } + GLFW.GLFW_KEY_UP -> { + moveSelection(-1) + event.cancel() + return + } + GLFW.GLFW_KEY_ENTER, GLFW.GLFW_KEY_KP_ENTER -> { + activateSelected() + event.cancel() + return + } + GLFW.GLFW_KEY_ESCAPE -> { + close() + event.cancel() + return + } + GLFW.GLFW_KEY_TAB -> { + // Cycle filter + val values = SearchFilter.entries + val nextIdx = (currentFilter.ordinal + 1) % values.size + currentFilter = values[nextIdx] + selectedIndex = 0 + event.cancel() + return + } + } + } + // Ctrl+F shortcut to open/toggle + val win = mc.window + val isCtrl = (event.modifiers and GLFW.GLFW_MOD_CONTROL != 0) + || (win != null && (InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_LEFT_CONTROL) || InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_RIGHT_CONTROL))) + if (event.keyCode == GLFW.GLFW_KEY_F && isCtrl) { toggle() - lastShiftPressTime = 0L - lastShiftKeyCode = -1 - } else { - lastShiftPressTime = currentTime - lastShiftKeyCode = event.keyCode + event.cancel() + return + } + if (event.keyCode == KeyCode.LeftShift.code || event.keyCode == KeyCode.RightShift.code) { + val currentTime = System.currentTimeMillis() + if (lastShiftKeyCode == event.keyCode && + currentTime - lastShiftPressTime <= DOUBLE_SHIFT_WINDOW_MS + ) { + toggle() + lastShiftPressTime = 0L + lastShiftKeyCode = -1 + } else { + lastShiftPressTime = currentTime + lastShiftKeyCode = event.keyCode + } } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/gui/components/SettingsWidget.kt b/src/main/kotlin/com/lambda/gui/components/SettingsWidget.kt index 4b4efeab8..5e255a1f6 100644 --- a/src/main/kotlin/com/lambda/gui/components/SettingsWidget.kt +++ b/src/main/kotlin/com/lambda/gui/components/SettingsWidget.kt @@ -29,118 +29,165 @@ import com.lambda.gui.dsl.ImGuiBuilder import com.lambda.imgui.ImGui import com.lambda.imgui.flag.ImGuiPopupFlags import com.lambda.imgui.flag.ImGuiTabBarFlags +import com.lambda.imgui.type.ImString import com.lambda.module.HudModule import com.lambda.module.Module import com.lambda.module.modules.client.AutoUpdater object SettingsWidget { + private val settingFilters = mutableMapOf() + /** - * Builds the settings context popup content for the given config. + * Builds the settings content for the given config (used in popups and inline expansion). */ fun ImGuiBuilder.buildConfigSettingsContext(config: Config) { group { if (config is Module && config != AutoUpdater) { - button("Module Settings") { - ImGui.openPopup("##module-settings-popup-${config.name}") - } - ImGui.setNextWindowSizeConstraints(0f, 0f, Float.MAX_VALUE, io.displaySize.y * 0.5f) - popupContextItem("##module-settings-popup-${config.name}", ImGuiPopupFlags.None) { - with(config.keybindSetting) { buildLayout() } - with(config.prioritySetting) { buildLayout() } - with(config.disableOnReleaseSetting) { buildLayout() } - with(config.drawSetting) { buildLayout() } - if (config is HudModule) { - with(config.backgroundColor) { buildLayout() } - } - smallButton("Reset") { - config.resetSettings() - } - } + withId("##header-${config.name}") { + // Row 1: Keybind setting + Reset button + with(config.keybindSetting) { buildLayout() } + + sameLine() + val resetText = "Reset" + val resetBtnW = ImGui.calcTextSize(resetText).x + style.framePadding.x * 2.5f + cursorPosX = (windowContentRegionMaxX - resetBtnW - style.windowPadding.x).coerceAtLeast(cursorPosX + 10f) + smallButton("$resetText##rst-${config.name}") { + config.resetSettings() + } + lambdaTooltip("Reset all settings for ${config.name} to their default values") + + // Row 2: Draw on HUD and Toggle on Release checkboxes + checkbox("Draw on HUD##draw-${config.name}", config.drawSetting::value) + lambdaTooltip(config.drawSetting.description) + + sameLine(0f, 15f) + checkbox("Toggle on Release##rel-${config.name}", config.disableOnReleaseSetting::value) + lambdaTooltip("Disable this module when the bound key is released") + + if (config is HudModule) { + sameLine(0f, 15f) + with(config.backgroundColor) { buildLayout() } + } + + // Collapsible Advanced section for priority + treeNode("Advanced Options##adv-${config.name}") { + with(config.prioritySetting) { buildLayout() } + } + } } - lambdaTooltip("Resets all settings for this module to their default values") + if (config is IMutableAutomationConfig && config.automationConfig !== AutomationConfig.DEFAULT) { - button("Automation Config") { + button("Automation Config##btn-${config.name}") { ImGui.openPopup("##automation-config-popup-${config.name}") } - if (config.backingAutomationConfig !== config.defaultAutomationConfig) { - sameLine() - text("(${config.backingAutomationConfig.name})") - } + if (config.backingAutomationConfig !== config.defaultAutomationConfig) { + sameLine() + text("(${config.backingAutomationConfig.name})") + } ImGui.setNextWindowSizeConstraints(0f, 0f, Float.MAX_VALUE, io.displaySize.y * 0.5f) popupContextItem("##automation-config-popup-${config.name}", ImGuiPopupFlags.None) { - combo("##LinkedConfig", preview = "Linked Config: ${config.backingAutomationConfig.name}") { - val addItem: (Config) -> Unit = { item -> - val selected = item === config.backingAutomationConfig - - selectable(item.name, selected) { - if (!selected) { - (config.backingAutomationConfig as? UserAutomationConfig)?.linkedModules?.value?.remove(config.name) - (item as? UserAutomationConfig)?.linkedModules?.value?.add(config.name) - config.automationConfig = item as? AutomationConfig ?: return@selectable - } - } - } - addItem(config.defaultAutomationConfig) - UserAutomationCategory.configs.forEach { addItem(it) } - } + combo("##LinkedConfig", preview = "Linked Config: ${config.backingAutomationConfig.name}") { + val addItem: (Config) -> Unit = { item -> + val selected = item === config.backingAutomationConfig + + selectable(item.name, selected) { + if (!selected) { + (config.backingAutomationConfig as? UserAutomationConfig)?.linkedModules?.value?.remove(config.name) + (item as? UserAutomationConfig)?.linkedModules?.value?.add(config.name) + config.automationConfig = item as? AutomationConfig ?: return@selectable + } + } + } + addItem(config.defaultAutomationConfig) + UserAutomationCategory.configs.forEach { addItem(it) } + } buildConfigSettingsContext(config.automationConfig) } } } - if (!hasVisibleSettings(config.settingLayers)) return - separator() - drawLayers(config.settingLayers, config.name) + if (!hasVisibleSettings(config.settingLayers)) return + separator() + + // Setting search filter if module has 4 or more visible settings + val visibleCount = countVisibleSettings(config.settingLayers) + var filterQuery = "" + if (visibleCount >= 4) { + val filter = settingFilters.getOrPut(config.name) { ImString(64) } + withItemWidth(ImGui.getContentRegionAvailX()) { + ImGui.inputTextWithHint("##st-filter-${config.name}", "Filter ${config.name} settings...", filter) + } + filterQuery = filter.get().trim() + separator() + } + + drawLayers(config.settingLayers, config.name, filterQuery) } - private fun ImGuiBuilder.drawLayers(root: EntryLayer.Multiple>, idPrefix: String) { - var tabsDrawn = false - - root.layers.forEach { layer -> - when (layer) { - is EntryLayer.Single> -> drawSetting(layer.entry) - is EntryLayer.Group -> { - if (hasVisibleSettings(layer)) { - treeNode("${layer.name}##$idPrefix-group-${layer.name}") { - drawLayers(layer, "$idPrefix-${layer.name}") - } - } - } - is EntryLayer.Tab -> { - if (!tabsDrawn) { - tabsDrawn = true - val allTabs = root.layers - .filterIsInstance>>() - .filter { hasVisibleSettings(it) } - if (allTabs.isNotEmpty()) { - tabBar("##$idPrefix-tabs", ImGuiTabBarFlags.FittingPolicyResizeDown) { - allTabs.forEach { tab -> - tabItem(tab.name) { - drawLayers(tab, "$idPrefix-${tab.name}") - } - } - } - } - } - } - else -> {} - } - } + private fun ImGuiBuilder.drawLayers(root: EntryLayer.Multiple>, idPrefix: String, filter: String) { + var tabsDrawn = false + + root.layers.forEach { layer -> + when (layer) { + is EntryLayer.Single> -> { + if (filter.isEmpty() || layer.entry.name.contains(filter, ignoreCase = true)) { + drawSetting(layer.entry) + } + } + is EntryLayer.Group -> { + if (hasVisibleSettings(layer, filter)) { + treeNode("${layer.name}##$idPrefix-group-${layer.name}") { + drawLayers(layer, "$idPrefix-${layer.name}", filter) + } + } + } + is EntryLayer.Tab -> { + if (!tabsDrawn) { + tabsDrawn = true + val allTabs = root.layers + .filterIsInstance>>() + .filter { hasVisibleSettings(it, filter) } + if (allTabs.isNotEmpty()) { + tabBar("##$idPrefix-tabs", ImGuiTabBarFlags.FittingPolicyResizeDown) { + allTabs.forEach { tab -> + tabItem(tab.name) { + drawLayers(tab, "$idPrefix-${tab.name}", filter) + } + } + } + } + } + } + else -> {} + } + } } private fun ImGuiBuilder.drawSetting(setting: Setting<*>) { - if (!setting.visibility()) return - if (setting.disabled()) ImGui.beginDisabled() - with(setting) { buildLayout() } - if (setting.disabled()) ImGui.endDisabled() + if (!setting.visibility()) return + if (setting.disabled()) ImGui.beginDisabled() + with(setting) { buildLayout() } + if (setting.disabled()) ImGui.endDisabled() } - private fun hasVisibleSettings(layer: EntryLayer.Multiple>): Boolean = - layer.layers.any { layer -> - when (layer) { - is SettingEntryLayer<*, *> -> layer.entry.visibility() - is EntryLayer.Multiple> -> hasVisibleSettings(layer) - else -> false - } - } -} \ No newline at end of file + private fun countVisibleSettings(layer: EntryLayer.Multiple>): Int { + var count = 0 + layer.layers.forEach { l -> + when (l) { + is SettingEntryLayer<*, *> -> if (l.entry.visibility()) count++ + is EntryLayer.Multiple> -> count += countVisibleSettings(l) + else -> {} + } + } + return count + } + + private fun hasVisibleSettings(layer: EntryLayer.Multiple>, filter: String = ""): Boolean = + layer.layers.any { l -> + when (l) { + is SettingEntryLayer<*, *> -> l.entry.visibility() && (filter.isEmpty() || l.entry.name.contains(filter, ignoreCase = true)) + is EntryLayer.Multiple> -> hasVisibleSettings(l, filter) + else -> false + } + } +} diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt index 3316a6afb..a72854a9a 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/ContainerSelection.kt @@ -46,6 +46,12 @@ fun selectContainers( scope: ContainerSearchScope = ContainerSearchScope.Accessed ) = containerSelection(scope) { ofAny(*containers) } +@ContainerDslMarker +fun selectContainer( + scope: ContainerSearchScope = ContainerSearchScope.Accessed, + builder: ContainerSelectionBuilder.() -> Unit +) = containerSelection(scope, builder) + /** * ContainerSelection is a class that holds a predicate for matching containers. */ @@ -59,28 +65,36 @@ class ContainerSelection @ContainerDslMarker internal constructor( val accessScope: AccessScope = AccessScope.Both, val comparator: Comparator = compareBy { it.type } ) { + private val whitelistSet = containersWhitelist.takeIf { it.isNotEmpty() }?.toSet() + private val blacklistSet = containersBlacklist.takeIf { it.isNotEmpty() }?.toSet() + @ContainerDslMarker fun bestMatch(containers: Iterable) = filter(containers).firstOrNull() @ContainerDslMarker - fun matches(container: Container): Boolean = selector(container) + fun matches(container: Container): Boolean { + if (whitelistSet != null && container !in whitelistSet) return false + if (blacklistSet != null && container in blacklistSet) return false + if (accessScope.accessed != null && container.isAccessed != accessScope.accessed) return false + return selector(container) + } @ContainerDslMarker - fun filter(containers: Iterable) = - run { - containersWhitelist - .takeIf { it.isNotEmpty() } - ?.asSequence() - ?.filter { it in containers && (accessScope.accessed?.equals(it.isAccessed) != false) } - ?: containers.asSequence() - }.filter { it !in containersBlacklist } - .filter(selector) + fun filter(containers: Iterable): List = + containers.asSequence() + .filter { container -> + (whitelistSet == null || container in whitelistSet) && + (blacklistSet == null || container !in blacklistSet) && + (accessScope.accessed == null || container.isAccessed == accessScope.accessed) && + selector(container) + } .sortedWith(comparator) .toList() companion object { - val ACCESSED = ContainerSelection({ true }) - val NOTHING = ContainerSelection({ false }) + val ACCESSED = ContainerSelection({ true }, ContainerSearchScope.Accessed) + val EVERYTHING = ContainerSelection({ true }, ContainerSearchScope.All) + val NOTHING = ContainerSelection({ false }, ContainerSearchScope.Accessed) val HOTBAR_AND_INVENTORY = selectContainers(HotbarContainer, InventoryContainer) val PLAYER = selectContainers( @@ -128,24 +142,18 @@ class ContainerSelectionBuilder @ContainerDslMarker private constructor( fun ofAny(vararg containers: Container) { containersWhitelist.addAll(containers) - withContainers(*containers) - appendSelector { container -> container in containersWhitelist } } fun ofAny(containers: Iterable) { containersWhitelist.addAll(containers) - withContainers(containers) - appendSelector { container -> container in containersWhitelist } } fun noneOf(vararg containers: Container) { containersBlacklist.addAll(containers) - appendSelector { container -> container !in containersBlacklist } } fun noneOf(containers: Iterable) { containersBlacklist.addAll(containers) - appendSelector { container -> container !in containersBlacklist } } fun ofAnyType(vararg types: ContainerType) { diff --git a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt index 19716278e..21fa3e9f6 100644 --- a/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt +++ b/src/main/kotlin/com/lambda/interaction/container/selection/StackSelection.kt @@ -44,6 +44,12 @@ fun Item.select(count: Int = 1) = stackSelection(count) { isItem(this@select) } @ContainerDslMarker fun ItemStack.select(count: Int = 1) = stackSelection(count) { isItemStack(this@select) } +@ContainerDslMarker +fun selectStack( + count: Int = 1, + builder: StackSelectionBuilder.() -> Unit +) = stackSelection(count, builder) + class StackSelection @ContainerDslMarker internal constructor( val count: Int = 1, val whitelistedSlots: Collection = emptyList(), @@ -54,7 +60,9 @@ class StackSelection @ContainerDslMarker internal constructor( val comparator: Comparator> = compareBy { it.stack.count }, val selector: (ItemStack, Slot?) -> Boolean, ) { - val optimalStack = itemStack ?: item?.let { ItemStack(it, count) } + val optimalStack = itemStack ?: item?.let { ItemStack(it, count.coerceIn(1, it.maxCount)) } + private val whitelistSet = whitelistedSlots.takeIf { it.isNotEmpty() }?.toSet() + private val blacklistSet = blacklistedSlots.takeIf { it.isNotEmpty() }?.toSet() @ContainerDslMarker fun bestMatch(stacks: Iterable) = filter(stacks).firstOrNull() @@ -66,9 +74,9 @@ class StackSelection @ContainerDslMarker internal constructor( fun matches(stack: ItemStack): Boolean { val matchesSelf = selector(stack, null) return when (shulkerBoxScope.inShulkerBox) { - true -> stack.shulkerBoxStacks.any { selector(it, null) } + true -> if (stack.item in ItemUtils.SHULKER_BOXES) stack.shulkerBoxStacks.any { selector(it, null) } else false false -> matchesSelf - null -> matchesSelf || stack.shulkerBoxStacks.any { selector(it, null) } + null -> matchesSelf || (stack.item in ItemUtils.SHULKER_BOXES && stack.shulkerBoxStacks.any { selector(it, null) }) } } @@ -76,9 +84,9 @@ class StackSelection @ContainerDslMarker internal constructor( fun matches(slot: Slot): Boolean { val matchesSelf = selector(slot.stack, slot) return when (shulkerBoxScope.inShulkerBox) { - true -> slot.stack.shulkerBoxStacks.any { selector(it, null) } + true -> if (slot.stack.item in ItemUtils.SHULKER_BOXES) slot.stack.shulkerBoxStacks.any { selector(it, null) } else false false -> matchesSelf - null -> matchesSelf || slot.stack.shulkerBoxStacks.any { selector(it, null) } + null -> matchesSelf || (slot.stack.item in ItemUtils.SHULKER_BOXES && slot.stack.shulkerBoxStacks.any { selector(it, null) }) } } @@ -86,7 +94,6 @@ class StackSelection @ContainerDslMarker internal constructor( @JvmName("filter1") fun filter(stacks: Iterable) = stacks - .let { if (whitelistedSlots.isNotEmpty()) emptyList() else it } .asSequence() .filter(::matches) .map { StackAndSlot(it, null) } @@ -98,15 +105,12 @@ class StackSelection @ContainerDslMarker internal constructor( @JvmName("filter2") fun filter(slots: Iterable) = slots - .let { slots -> - if (whitelistedSlots.isNotEmpty()) { - whitelistedSlots - .asSequence() - .filter { it in slots } - } else slots.asSequence() + .asSequence() + .filter { slot -> + (whitelistSet == null || slot in whitelistSet) && + (blacklistSet == null || slot !in blacklistSet) && + matches(slot) } - .filter { it !in blacklistedSlots } - .filter(::matches) .map { StackAndSlot(it.stack, it) } .sortedWith(comparator) .map { it.slot } @@ -114,34 +118,36 @@ class StackSelection @ContainerDslMarker internal constructor( @ContainerDslMarker infix fun isIn(container: Container) = - container.count(this) >= count + if (count <= 0) container.count(this) > 0 else container.count(this) >= count @ContainerDslMarker fun isIn(vararg containers: Container) = - containers.sumOf { it.count(this) } >= count + if (count <= 0) containers.any { it.count(this) > 0 } else containers.sumOf { it.count(this) } >= count @ContainerDslMarker infix fun isIn(containers: Iterable) = - containers.sumOf { it.count(this) } >= count + if (count <= 0) containers.any { it.count(this) > 0 } else containers.sumOf { it.count(this) } >= count @ContainerDslMarker infix fun spaceIn(container: Container) = - container.spaceLeft(this) >= count + if (count <= 0) container.spaceLeft(this) > 0 else container.spaceLeft(this) >= count @ContainerDslMarker fun spaceIn(vararg containers: Container) = - containers.sumOf { it.spaceLeft(this) } >= count + if (count <= 0) containers.any { it.spaceLeft(this) > 0 } else containers.sumOf { it.spaceLeft(this) } >= count @ContainerDslMarker infix fun spaceIn(containers: Iterable) = - containers.sumOf { it.spaceLeft(this) } >= count + if (count <= 0) containers.any { it.spaceLeft(this) > 0 } else containers.sumOf { it.spaceLeft(this) } >= count companion object { val ANYTHING = StackSelection(0) { _, _ -> true } - val NOTHING = StackSelection { _, _ -> false } + val EVERYTHING = ANYTHING + val NOTHING = StackSelection(0) { _, _ -> false } } } + @ContainerDslMarker class StackSelectionBuilder @ContainerDslMarker private constructor( private var count: Int = 1 @@ -178,13 +184,18 @@ class StackSelectionBuilder @ContainerDslMarker private constructor( } inline fun isItem() { - val kClass = T::class - appendSelector { stack, _ -> stack::class == kClass } + appendSelector { stack, _ -> stack.item is T } } inline fun notItem() { - val kClass = T::class - appendSelector { stack, _ -> stack::class != kClass } + appendSelector { stack, _ -> stack.item !is T } + } + + fun inverted(builder: StackSelectionBuilder.() -> Unit) { + val nested = StackSelectionBuilder().apply(builder).build() + appendSelector { stack, slot -> + if (slot != null) !nested.matches(slot) else !nested.matches(stack) + } } fun isItemStack(stack: ItemStack) { diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt index 08c4ee113..3a0519983 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/ContainerHandler.kt @@ -48,6 +48,8 @@ import com.lambda.util.item.ItemStackUtils.count import com.lambda.util.item.ItemStackUtils.shulkerBoxStacks import com.lambda.util.item.ItemUtils.SHULKER_BOXES import com.lambda.util.player.SlotUtils.typeSafe +import net.minecraft.item.ItemStack +import net.minecraft.screen.slot.Slot import net.minecraft.block.ChestBlock import net.minecraft.block.ShulkerBoxBlock import net.minecraft.block.entity.BlockEntity @@ -246,7 +248,7 @@ fun StackSelection.move( findContainer( containerSelection { matches(fromSelection) - hasStack(mutate(count.coerceAtMost(64))) + hasStack(this@move) isAccessed() } ) @@ -256,7 +258,7 @@ fun StackSelection.move( findContainer( containerSelection { matches(toSelection) - hasStack(replaceSelection) + hasSpace(this@move) isAccessed() } ) @@ -274,8 +276,7 @@ fun findSlot( stackSelection: StackSelection = StackSelection.ANYTHING, containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = findSlots(stackSelection, containerSelection, sorted) - .firstOrNull() +) = findSlots(stackSelection, containerSelection, sorted).firstOrNull() @ContainerDslMarker context(automated: Automated) @@ -283,18 +284,14 @@ fun findSlots( stackSelection: StackSelection = StackSelection.ANYTHING, containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = searchContainers(containerSelection) - .filter { containerSelection.matches(it) } - .let { - if (sorted) it.sorted() - else it - } - .mapNotNull { container -> - val slots = stackSelection.filter(container.slots) - if (slots.count >= stackSelection.count) slots - else null - } - .flatten() +): Sequence = + findContainers(containerSelection, sorted) + .mapNotNull { container -> + val slots = stackSelection.filter(container.slots) + if (slots.count >= stackSelection.count) slots + else null + } + .flatten() @ContainerDslMarker context(automated: Automated) @@ -302,8 +299,7 @@ fun findStack( stackSelection: StackSelection = StackSelection.ANYTHING, containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = findStacks(stackSelection, containerSelection, sorted) - .firstOrNull() +) = findStacks(stackSelection, containerSelection, sorted).firstOrNull() @ContainerDslMarker context(automated: Automated) @@ -311,53 +307,95 @@ fun findStacks( stackSelection: StackSelection = StackSelection.ANYTHING, containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = searchContainers(containerSelection) - .filter { containerSelection.matches(it) } - .let { - if (sorted) it.sorted() - else it - } - .mapNotNull { container -> - val stacks = stackSelection.filter(container.stacks) - if (stacks.count >= stackSelection.count) stacks - else null - } - .flatten() +): Sequence = + findContainers(containerSelection, sorted) + .mapNotNull { container -> + val stacks = stackSelection.filter(container.stacks) + if (stacks.count >= stackSelection.count) stacks + else null + } + .flatten() @ContainerDslMarker context(_: Automated) fun findContainer( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = findContainers(containerSelection, sorted) - .firstOrNull() +) = findContainers(containerSelection, sorted).firstOrNull() + +@ContainerDslMarker +context(automated: Automated) +fun findContainer( + stackSelection: StackSelection, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +): Container? = findContainers(stackSelection, containerSelection, sorted).firstOrNull() @ContainerDslMarker context(automated: Automated) fun findContainers( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = searchContainers(containerSelection) - .filter { containerSelection.matches(it) } - .let { - if (sorted) it.sorted() - else it +): Sequence { + val containers = searchContainers(containerSelection) + return if (sorted) { + containerSelection.filter(containers.asIterable()).asSequence() + } else { + containers.filter { containerSelection.matches(it) } } +} + +@ContainerDslMarker +context(automated: Automated) +fun findContainers( + stackSelection: StackSelection, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +): Sequence = + findContainers( + containerSelection(containerSelection.scope) { + matches(containerSelection) + hasStack(stackSelection) + }, + sorted + ) + +@ContainerDslMarker +context(automated: Automated) +fun findContainerWithSpace( + stackSelection: StackSelection, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +): Container? = findContainersWithSpace(stackSelection, containerSelection, sorted).firstOrNull() + +@ContainerDslMarker +context(automated: Automated) +fun findContainersWithSpace( + stackSelection: StackSelection, + containerSelection: ContainerSelection = ContainerSelection.ACCESSED, + sorted: Boolean = true +): Sequence = + findContainers( + containerSelection(containerSelection.scope) { + matches(containerSelection) + hasSpace(stackSelection) + }, + sorted + ) @ContainerDslMarker context(_: Automated) fun findContainerWithDisposable( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = findContainersWithDisposable(containerSelection, sorted) - .firstOrNull() +) = findContainersWithDisposable(containerSelection, sorted).firstOrNull() @ContainerDslMarker context(automated: Automated) fun findContainersWithDisposable( containerSelection: ContainerSelection = ContainerSelection.ACCESSED, sorted: Boolean = true -) = +): Sequence = with(automated) { findContainers( containerSelection(containerSelection.scope) { @@ -369,7 +407,6 @@ fun findContainersWithDisposable( sorted ) } - context(automated: Automated) private fun searchContainers( selection: ContainerSelection @@ -386,7 +423,7 @@ private fun searchContainers( val placedSeq = sequenceOf(ContainerHandler.accessedPlacedContainer).filterNotNull() val baseContainers = - when (selection.scope) { + (when (selection.scope) { ContainerSearchScope.Player -> compiled - EnderChestContainer ContainerSearchScope.Compiled -> compiled ContainerSearchScope.Loaded -> compiled + placedSeq + selection.loadedContainers @@ -395,7 +432,7 @@ private fun searchContainers( ContainerSerializer.serializedContainers.filter { diskContainer -> diskContainer.pos != ContainerHandler.accessedPlacedContainer?.pos } - } + } + selection.containersWhitelist.asSequence()).distinct() return baseContainers .flatMap { it.allNested() } diff --git a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt index 2a8d1b498..db54e5943 100644 --- a/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt +++ b/src/main/kotlin/com/lambda/interaction/handler/handlers/GlideHandler.kt @@ -59,17 +59,17 @@ object GlideHandler { predicate { stack, _ -> stack.damage < stack.maxDamage } sortedWith { compareByDescending> { - it.stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) - ?.modifiers + val modifiers = it.stack.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + ?: it.stack.item.components.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + modifiers?.modifiers ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR } - ?.modifier?.value - ?: 0.0 + ?.modifier?.value ?: 0.0 }.thenByDescending { - it.stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) - ?.modifiers + val modifiers = it.stack.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + ?: it.stack.item.components.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + modifiers?.modifiers ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR_TOUGHNESS } - ?.modifier?.value - ?: 0.0 + ?.modifier?.value ?: 0.0 }.thenByDescending { it.stack.getEnchantment(Enchantments.UNBREAKING) }.thenByDescending { diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt index b5a5518d5..0aa6a9298 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoArmor.kt @@ -75,18 +75,19 @@ object AutoArmor : Module( else 0.0 } else 0.0 }.thenByDescending { - it.stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) - ?.modifiers + val modifiers = it.stack.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + ?: it.stack.item.components.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + modifiers?.modifiers ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR } ?.modifier?.value ?: 0.0 }.thenByDescending { - it.stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, null) - ?.modifiers + val modifiers = it.stack.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + ?: it.stack.item.components.get(DataComponentTypes.ATTRIBUTE_MODIFIERS) + modifiers?.modifiers ?.find { modifier -> modifier.attribute == EntityAttributes.ARMOR_TOUGHNESS } ?.modifier?.value ?: 0.0 - }.thenByDescending { val stack = it.stack when { stack.isIn(ItemTags.FOOT_ARMOR) -> stack.getEnchantment(feetProtection.enchant) diff --git a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt index 517625872..2a39fbea3 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/AutoTotem.kt @@ -33,6 +33,10 @@ import com.lambda.util.combat.DamageUtils.isFallDeadly import com.lambda.util.extension.fullHealth import com.lambda.util.extension.tickDeltaF import com.lambda.util.world.fastEntitySearch +import com.lambda.util.Describable +import com.lambda.util.NamedEnum +import net.minecraft.registry.tag.ItemTags +import net.minecraft.item.Item import net.minecraft.entity.mob.CreeperEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Items @@ -40,20 +44,42 @@ import net.minecraft.item.Items @Suppress("unused") object AutoTotem : Module( name = "AutoTotem", - description = "Swaps the your off-hand item to a totem", + description = "Intelligently manages offhand items with CPvP modes (Totem, Crystal, Gapple) and safety swaps", tag = ModuleTag.COMBAT, modulePriority = 100 ) { - private val always by setting("Always", true, "Always attempt to keep a totem in offhand") - private val ignoreWhenHolding by setting("Ignore When Holding", false, "Ignore swapping to offhand when already holding a totem") - private val minimumHealth by setting("Min Health", 10, 6..36, 1, "Set the minimum health threshold to swap", unit = " half-hearts") { !always } - private val falls by setting("Falls", true, "Swap if the player will die of fall damage") { !always } - private val fallDistance by setting("Falls Time", 10, 0..30, 1, "Number of blocks fallen before swapping", unit = " blocks") { !always && falls } - private val crystals by setting("Crystals", true, "Swap if an End Crystal explosion would be lethal") { !always } - private val creeper by setting("Creepers", true, "Swap when an ignited Creeper is nearby") { !always } - private val players by setting("Players", false, "Swap if a nearby player is detected within the set distance") { !always } - private val minPlayerDistance by setting("Player Distance", 64, 32..128, 4, "Set the distance to detect players to swap") { !always && players } - private val friends by setting("Friends", false, "Exclude friends from triggering player-based swaps") { !always && players } + enum class OffhandMode( + override val displayName: String, + override val description: String, + val item: Item + ) : NamedEnum, Describable { + Totem("Totem", "Always equips Totem of Undying in the offhand.", Items.TOTEM_OF_UNDYING), + Crystal("Crystal", "Equips End Crystals in the offhand for CPvP.", Items.END_CRYSTAL), + Gapple("Gapple", "Equips Enchanted Golden Apples in the offhand.", Items.ENCHANTED_GOLDEN_APPLE), + GoldenApple("Golden Apple", "Equips regular Golden Apples in the offhand.", Items.GOLDEN_APPLE), + Shield("Shield", "Equips a Shield in the offhand for defense.", Items.SHIELD) + } + + private val mode by setting("Mode", OffhandMode.Totem, "Primary item to hold in the offhand when safe") + private val always by setting("Always Totem", false, "Always keeps a totem in the offhand regardless of safe state or selected mode") + private val swordGap by setting("Sword Gap", true, "Swaps to Golden Apple when holding a sword or axe and pressing use/right-click") + private val crystalOnCA by setting("Crystal on CA", true, "Automatically equips crystals in offhand when CrystalAura is active") + private val fallbackToTotem by setting("Fallback to Totem", true, "Falls back to a Totem if the desired offhand item is missing from inventory") + private val ignoreWhenHolding by setting("Ignore When Holding", false, "Ignore swapping to offhand when already holding a totem in main hand") + private val minimumHealth by setting("Min Health", 12, 4..36, 1, "Minimum health threshold to force a totem swap", unit = " half-hearts") + private val falls by setting("Falls", true, "Swap to totem if the player will die of fall damage") + private val fallDistance by setting("Falls Distance", 8, 0..30, 1, "Number of blocks fallen before swapping", unit = " blocks") { falls } + private val crystals by setting("Crystals", true, "Swap to totem if an End Crystal explosion would be lethal") + private val creeper by setting("Creepers", true, "Swap to totem when an ignited Creeper is nearby") + private val elytraSafety by setting("Elytra Safety", true, "Swap to totem when flying with Elytra at dangerous speeds or low altitude") + private val players by setting("Players", false, "Swap to totem if a nearby hostile player is detected") + private val minPlayerDistance by setting("Player Distance", 32, 8..64, 2, "Distance to detect players to force totem") { players } + private val friends by setting("Friends", false, "Exclude friends from triggering player-based swaps") { players } + + @JvmStatic var offhandOverride: (() -> Boolean)? = null + + fun isDangerous(context: SafeContext): Boolean = + Reason.entries.any { it.check(context) } init { setDefaultAutomationConfig() @@ -62,26 +88,61 @@ object AutoTotem : Module( } listen { - if (!always && Reason.entries.none { it.check(this) }) return@listen - - if ((!ignoreWhenHolding || !player.isHolding(Items.TOTEM_OF_UNDYING)) && player.offHandStack.item != Items.TOTEM_OF_UNDYING) { - Items.TOTEM_OF_UNDYING.select() - .filter(player.currentScreenHandler.slots) - .takeIf { it.isNotEmpty() } - ?.let { totems -> - val cursor = player.currentScreenHandler.cursorStack - val targetSlot = player.currentScreenHandler.slots - .findLast { !cursor.isEmpty && it.canInsert(cursor) } - - inventoryRequest { - targetSlot?.let { pickup(it.id, 0) } - swapWithHotbar(totems.first().id, 40) - }.submit() - } + // Prevent swapping when an external container (chest, furnace, etc.) is open + if (player.currentScreenHandler !== player.playerScreenHandler && player.currentScreenHandler.syncId != 0) return@listen + + val dangerous = isDangerous(this) + if (!dangerous && offhandOverride?.invoke() == true) return@listen + + val targetItem = when { + dangerous || always -> Items.TOTEM_OF_UNDYING + swordGap && isHoldingWeaponAndUsing() -> Items.ENCHANTED_GOLDEN_APPLE + crystalOnCA && CrystalAura.isEnabled -> Items.END_CRYSTAL + else -> mode.item } + + equipOffhand(targetItem) } } + private fun SafeContext.isHoldingWeaponAndUsing(): Boolean { + val holdingWeapon = player.mainHandStack.isIn(ItemTags.SWORDS) || player.mainHandStack.isIn(ItemTags.AXES) + return holdingWeapon && mc.options.useKey.isPressed + } + + private fun SafeContext.equipOffhand(targetItem: Item) { + if (player.offHandStack.item == targetItem) return + if (targetItem == Items.TOTEM_OF_UNDYING && ignoreWhenHolding && player.isHolding(Items.TOTEM_OF_UNDYING)) return + + // Find the slot with target item in player's current screen handler + var slot = targetItem.select() + .filter(player.currentScreenHandler.slots) + .firstOrNull() + + // Fallback between enchanted golden apple and standard golden apple for eating + if (slot == null && targetItem == Items.ENCHANTED_GOLDEN_APPLE) { + slot = Items.GOLDEN_APPLE.select().filter(player.currentScreenHandler.slots).firstOrNull() + } else if (slot == null && targetItem == Items.GOLDEN_APPLE) { + slot = Items.ENCHANTED_GOLDEN_APPLE.select().filter(player.currentScreenHandler.slots).firstOrNull() + } + + // If requested item is missing, fallback to totem if permitted + if (slot == null && targetItem != Items.TOTEM_OF_UNDYING && fallbackToTotem) { + slot = Items.TOTEM_OF_UNDYING.select().filter(player.currentScreenHandler.slots).firstOrNull() + } + + if (slot == null) return + if (player.offHandStack.item == slot.stack.item) return + + val cursor = player.currentScreenHandler.cursorStack + val emptySlot = player.currentScreenHandler.slots.findLast { !cursor.isEmpty && it.canInsert(cursor) } + + inventoryRequest { + emptySlot?.let { pickup(it.id, 0) } + swapWithHotbar(slot.id, 40) + }.submit() + } + enum class Reason(val check: SafeContext.() -> Boolean) { Health({ player.fullHealth < minimumHealth }), Creeper({ creeper && fastEntitySearch(15.0).any { @@ -94,6 +155,7 @@ object AutoTotem : Module( && (!friends || !FriendHandler.isFriend(otherPlayer.uuid)) } }), EndCrystal({ crystals && hasDeadlyCrystal() }), - FallDamage({ falls && isFallDeadly() && player.fallDistance > fallDistance }) + FallDamage({ falls && (isFallDeadly() || player.fallDistance > fallDistance) }), + Elytra({ elytraSafety && player.isGliding && (player.velocity.lengthSquared() > 0.8 || player.y < player.world.bottomY + 25) }) } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt b/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt index 1755d1335..2672268f3 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Criticals.kt @@ -35,6 +35,8 @@ import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction +import net.minecraft.entity.effect.StatusEffects +import net.minecraft.util.math.Vec3d @Suppress("unused") object Criticals : Module( @@ -43,7 +45,9 @@ object Criticals : Module( tag = ModuleTag.COMBAT, ) { enum class Mode { - Grim + Grim, + Packet, + MiniJump } private val mode by setting("Mode", Mode.Grim) @@ -55,7 +59,7 @@ object Criticals : Module( if (player.isOnGround) posPacket(0.00000001, rotation = player.rotation) posPacket(-0.000000001, rotation = player.eyePos.rotationTo(it.entity.boundingBox.center)) - connection.sendPacket(PlayerInteractItemC2SPacket(Hand.OFF_HAND, 0, player.yaw, player.pitch)) // TODO: This is wrong, fix it + connection.sendPacket(PlayerInteractItemC2SPacket(Hand.OFF_HAND, 0, player.yaw, player.pitch)) // TODO: offhand eating Grim desync fix connection.sendPacket { PlayerActionC2SPacket( PlayerActionC2SPacket.Action.RELEASE_USE_ITEM, @@ -64,6 +68,19 @@ object Criticals : Module( ) } } + Mode.Packet -> { + if (!player.isOnGround || player.isTouchingWater || player.isInLava || player.hasStatusEffect(StatusEffects.BLINDNESS)) return@listen + posPacket(0.0625, false, null) + posPacket(0.0, false, null) + posPacket(0.0125, false, null) + posPacket(0.0, false, null) + } + Mode.MiniJump -> { + if (player.isOnGround) { + player.jump() + player.velocity = Vec3d(player.velocity.x, 0.25, player.velocity.z) + } + } } } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 75902dad3..2c3fe1e74 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -62,6 +62,8 @@ import net.minecraft.block.Blocks import net.minecraft.entity.Entity import net.minecraft.entity.LivingEntity import net.minecraft.entity.decoration.EndCrystalEntity +import net.minecraft.entity.effect.StatusEffects +import net.minecraft.registry.tag.ItemTags import net.minecraft.item.Items import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket @@ -101,6 +103,9 @@ object CrystalAura : Module( @Tab(PLACEMENT_TAB) private val priorityMode by setting("Crystal Priority", Priority.Damage) @Tab(PLACEMENT_TAB) private val minDamageAdvantage by setting("Min Damage Advantage", 4.0, 1.0..10.0, 0.5) { priorityMode == Priority.Advantage } @Tab(PLACEMENT_TAB) private val minTargetDamage by setting("Min Target Damage", 8.0, 0.0..20.0, 0.5, "Minimum target damage to use crystals") + @Tab(PLACEMENT_TAB) private val facePlace by setting("Face Place", true, "Places crystals at lower damage thresholds to finish weak targets or break armor") + @Tab(PLACEMENT_TAB) private val facePlaceHealth by setting("Face Place Health", 10.0, 1.0..36.0, 0.5, "Maximum target health to trigger Face Place") { facePlace } + @Tab(PLACEMENT_TAB) private val facePlaceArmor by setting("Face Place Armor", 15, 1..100, 1, "Armor durability percentage to trigger Face Place", unit = "%") { facePlace } @Tab(PLACEMENT_TAB) private val maxSelfDamage by setting("Max Self Damage", 8.0, 0.0..36.0, 0.5, "Maximum self damage to use crystals") @Tab(PLACEMENT_TAB) private val minPlaceHealth by setting("Min Place Health", 5.0, 0.0..36.0, 0.5, "Minimum player health to place crystals") @Tab(PLACEMENT_TAB) private val preventDeath by setting("Prevent Death", true, "Prevent death by crystal") @@ -108,6 +113,7 @@ object CrystalAura : Module( @Tab(EXPLODING_TAB) private val explodeRange by setting("Explode Range", 3.0, 1.0..7.0, 0.1, "Range to explode crystals", " blocks") @Tab(EXPLODING_TAB) private val explodeDelay by setting("Explode Delay", 10L, 0L..1000L, 1L, "Delay between explosion attempts", " ms") + @Tab(EXPLODING_TAB) private val antiWeakness by setting("Anti Weakness", true, "Swaps to a weapon before exploding when under the Weakness effect") @Tab(PREDICTION_TAB) private val prediction by setting("Prediction", PredictionMode.None) @Tab(PREDICTION_TAB) private val packetPredictions by setting("Packet Predictions", 1, 0..20, 1) { prediction.onPacket } @@ -297,6 +303,13 @@ object CrystalAura : Module( } private fun SafeContext.explodeInternal(id: Int) { + if (antiWeakness && player.hasStatusEffect(StatusEffects.WEAKNESS)) { + val weaponIndex = findWeaponSlotIndex() + if (weaponIndex != null && weaponIndex != player.inventory.selectedSlot) { + hotbarRequest(weaponIndex).submit() + } + } + connection.sendPacket { PlayerInteractEntityC2SPacket( id, player.isSneaking, PlayerInteractEntityC2SPacket.ATTACK @@ -306,10 +319,42 @@ object CrystalAura : Module( player.swingHand(Hand.MAIN_HAND) } + private fun SafeContext.findWeaponSlotIndex(): Int? { + for (i in 0..8) { + val stack = player.inventory.getStack(i) + if (stack.isIn(ItemTags.SWORDS) || stack.isIn(ItemTags.AXES)) { + return i + } + } + return null + } + + private fun isArmorLow(entity: LivingEntity, thresholdPercent: Int): Boolean { + val armorSlots = arrayOf( + net.minecraft.entity.EquipmentSlot.HEAD, + net.minecraft.entity.EquipmentSlot.CHEST, + net.minecraft.entity.EquipmentSlot.LEGS, + net.minecraft.entity.EquipmentSlot.FEET + ) + for (slot in armorSlots) { + val armorStack = entity.getEquippedStack(slot) + if (armorStack.isEmpty || !armorStack.isDamageable) continue + val duraPercent = (1.0 - armorStack.damage.toDouble() / armorStack.maxDamage.toDouble()) * 100.0 + if (duraPercent <= thresholdPercent) return true + } + return false + } + private fun SafeContext.updateBlueprint(target: LivingEntity) = updateTimer.runIfPassed(updateDelay.milliseconds) { resetBlueprint() + val isFacePlacing = facePlace && ( + target.health <= facePlaceHealth || + isArmorLow(target, facePlaceArmor) + ) + val effectiveMinTargetDamage = if (isFacePlacing) 2.0 else minTargetDamage + fun info( pos: BlockPos, target: LivingEntity, @@ -319,8 +364,7 @@ object CrystalAura : Module( val crystalPos = pos.crystalPosition val targetDamage = crystalDamage(crystalPos, target) - if (targetDamage < minTargetDamage) return null - + if (targetDamage < effectiveMinTargetDamage) return null val selfDamage = crystalDamage(crystalPos, player) if (selfDamage > maxSelfDamage || player.fullHealth - selfDamage <= minPlaceHealth || diff --git a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt index d9962e06e..52ecd3f32 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt @@ -42,6 +42,8 @@ import com.lambda.util.math.random import com.lambda.util.player.RotationUtils.lookAtEntity import net.minecraft.entity.Entity import net.minecraft.item.ItemStack +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.AxeItem import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket import net.minecraft.util.Hand import net.minecraft.world.GameMode @@ -57,6 +59,7 @@ object KillAura : Module( @Tab(GENERAL_TAB) private val rotate by setting("Rotate", true) @Tab(GENERAL_TAB) private val swap by setting("Swap", true, "Swap to the item with the highest damage") + @Tab(GENERAL_TAB) private val antiShield by setting("Anti Shield", true, "Swaps to an axe when target is blocking with a shield to disable it") @Tab(GENERAL_TAB) private val disableWhileGliding by setting("Disable While Gliding", false, "Disables when gliding with an elytra") @Tab(GENERAL_TAB) private val damageMode by setting("Damage Mode", DamageMode.Dps) @Tab(GENERAL_TAB) private val attackMode by setting("Attack Mode", AttackMode.Cooldown) @@ -75,6 +78,7 @@ object KillAura : Module( private var lastAttackTime = 0L private var hitDelay = 100.0 private var cooldownFromSwap = false + @JvmStatic var isPaused = false enum class AttackMode { Cooldown, @@ -106,8 +110,7 @@ object KillAura : Module( listen { cooldownFromSwap = true } listen { - if (disableWhileGliding && player.isGliding) return@listen - + if (isPaused || (disableWhileGliding && player.isGliding)) return@listen target?.let { entity -> // Wait until the rotation has a hit result on the entity var rotated = true @@ -119,8 +122,12 @@ object KillAura : Module( } if (swap) { + val targetIsBlocking = antiShield && entity is PlayerEntity && entity.isBlocking val selection = stackSelection { + if (targetIsBlocking) { + isItem() + } sortedWith { compareByDescending { damageMode.block(this@listen, it.stack) @@ -128,9 +135,21 @@ object KillAura : Module( } } - selection.bestMatch(HotbarContainer.stacks)?.let { bestStack -> + val matchedStack = selection.bestMatch(HotbarContainer.stacks) + ?: if (targetIsBlocking) { + // Fallback to highest damage weapon if no axe found + stackSelection { + sortedWith { + compareByDescending { + damageMode.block(this@listen, it.stack) + } + } + }.bestMatch(HotbarContainer.stacks) + } else null + + matchedStack?.let { bestStack -> val slotId = HotbarContainer.stacks.indexOf(bestStack) - if (!hotbarRequest(slotId).submit().done) return@listen + if (slotId >= 0 && !hotbarRequest(slotId).submit().done) return@listen } } @@ -145,9 +164,9 @@ object KillAura : Module( cooldownFromSwap = false // Attack - connection.sendPacket(PlayerInteractEntityC2SPacket.attack(target, player.isSneaking)) + connection.sendPacket(PlayerInteractEntityC2SPacket.attack(entity, player.isSneaking)) if (interaction.gameMode != GameMode.SPECTATOR) { - player.attack(target) + player.attack(entity) player.resetTicksSince() } if (interactConfig.swing) player.swingHand(Hand.MAIN_HAND) diff --git a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt index 0e140935c..9755fdb84 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/PlayerTrap.kt @@ -78,8 +78,8 @@ object PlayerTrap : Module( } } - val block = findStack(selection, ContainerSelection.HOTBAR_AND_INVENTORY) - ?.item?.block + val block = (findStack(selection, ContainerSelection.HOTBAR_AND_INVENTORY)?.item as? BlockItem) + ?.block ?: return@tickingBlueprint emptyMap() val targetPlayer = diff --git a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt index 48d5eb31f..3e2fae990 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/Surround.kt @@ -21,6 +21,8 @@ import com.lambda.config.automation.setDefaultAutomationConfig import com.lambda.config.editTypedSettings import com.lambda.config.hideBlock import com.lambda.config.withEdits +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.container.selection.ContainerSelection @@ -35,7 +37,8 @@ import com.lambda.task.tasks.build import com.lambda.util.item.ItemUtils.block import net.minecraft.block.Blocks import net.minecraft.item.BlockItem - +import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket +import net.minecraft.util.math.BlockPos @Suppress("unused") object Surround : Module( name = "Surround", @@ -43,8 +46,13 @@ object Surround : Module( tag = ModuleTag.COMBAT ) { private val blocks by setting("Blocks", setOf(Blocks.OBSIDIAN, Blocks.ENDER_CHEST, Blocks.CRYING_OBSIDIAN)) + private val autoCenter by setting("Auto Center", true, "Snaps the player into the center of the block upon enabling") + private val disableOnJump by setting("Disable On Jump", true, "Automatically disables Surround when jumping or leaving the hole") + private val antiCity by setting("Anti City", true, "Places extra diagonal blocks to prevent city mining") + private val floor by setting("Floor", true, "Places a block under feet if standing on air") private var task: Task<*>? = null + private var startY = 0.0 init { setDefaultAutomationConfig() @@ -59,7 +67,24 @@ object Surround : Module( hideBlock(::eatConfig) } + listen { + if (disableOnJump && (mc.options.jumpKey.isPressed || player.y > startY + 0.25 || (!player.isOnGround && player.y < startY - 0.5))) { + disable() + } + } + onEnable { + startY = player.y + if (autoCenter) { + val center = player.blockPos.toCenterPos() + player.setPosition(center.x, player.y, center.z) + connection.sendPacket( + PlayerMoveC2SPacket.PositionAndOnGround( + center.x, player.y, center.z, player.isOnGround, player.horizontalCollision + ) + ) + } + task = tickingBlueprint { val selection = stackSelection { @@ -68,16 +93,30 @@ object Surround : Module( } } - val block = findStack(selection, ContainerSelection.HOTBAR_AND_INVENTORY) - ?.item?.block + val block = (findStack(selection, ContainerSelection.HOTBAR_AND_INVENTORY)?.item as? BlockItem) + ?.block ?: return@tickingBlueprint emptyMap() - getTrapPositions(player) - .filter { it.y <= player.blockPos.y } - .associateWith { TargetState.Block(block) } + val trapPositions = getTrapPositions(player).filter { + if (floor) it.y <= player.blockPos.y else it.y == player.blockPos.y + }.toMutableSet() + + if (antiCity) { + val feet = player.blockPos + trapPositions.add(feet.add(1, 0, 1)) + trapPositions.add(feet.add(1, 0, -1)) + trapPositions.add(feet.add(-1, 0, 1)) + trapPositions.add(feet.add(-1, 0, -1)) + } + + trapPositions.associateWith { TargetState.Block(block) } }.build(finishOnDone = false) .start() } - onDisable { task?.cancel(); task = null } + onDisable { + task?.cancel() + task = null + startY = 0.0 + } } } \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt index b2ae33205..c5e81af76 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BetterFirework.kt @@ -160,8 +160,14 @@ object BetterFirework : Module( * Return true if a firework has been used */ fun SafeContext.startFirework(inventory: Boolean) { - val selection = Items.FIREWORK_ROCKET.select(1) + if (player.offHandStack.item == Items.FIREWORK_ROCKET) { + interaction.interactItem(player, Hand.OFF_HAND) + if (clientSwing) player.swingHand(Hand.OFF_HAND) + else connection.sendPacket(HandSwingC2SPacket(Hand.OFF_HAND)) + return + } + val selection = Items.FIREWORK_ROCKET.select(1) val hotbarMatch = selection.bestMatch(HotbarContainer.slots) if (hotbarMatch != null) { swapAndFirework(hotbarMatch.index) diff --git a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt index a2fc3f1ed..1fe7d4100 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/AutoElytraSwap.kt @@ -19,6 +19,7 @@ package com.lambda.module.modules.player import com.lambda.context.SafeContext import com.lambda.interaction.container.containers.ArmorContainer +import com.lambda.interaction.container.containers.HotbarContainer import com.lambda.interaction.handler.handlers.GlideHandler.CHESTPLATE_SELECTION import com.lambda.interaction.handler.handlers.GlideHandler.ELYTRA_SELECTION import com.lambda.interaction.handler.handlers.GlideHandler.manuallySwapped @@ -49,7 +50,7 @@ object AutoElytraSwap : Module( findSlots( if (elytra) ELYTRA_SELECTION else CHESTPLATE_SELECTION - ).minByOrNull { it.index } + ).firstOrNull() ?: run { AutoElytraSwap.warn("The required armor piece was not found for AutoElytraSwap to work.") return false @@ -60,8 +61,9 @@ object AutoElytraSwap : Module( private fun swapWithChestplate(swapSlot: Slot): Boolean { val chestplateSlot = ArmorContainer.slots.getOrNull(1) ?: return false + val hotbarIndex = HotbarContainer.slots.indexOf(swapSlot) return AutoElytraSwap.inventoryRequest { - if (swapSlot.index in 0..8) swapWithHotbar(chestplateSlot.id, swapSlot.index) + if (hotbarIndex != -1) swapWithHotbar(chestplateSlot.id, hotbarIndex) else { moveSlot(swapSlot.id, chestplateSlot.id) if (!chestplateSlot.stack.isEmpty) pickup(swapSlot.id) diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index c5b7b9a13..45d138e92 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -40,6 +40,9 @@ import com.lambda.interaction.construction.verify.TargetState import com.lambda.interaction.manager.managers.breaking.BreakRequestBuilder.Companion.breakRequest import com.lambda.module.Module import com.lambda.module.ModuleTag +import com.lambda.interaction.handler.handlers.FriendHandler +import com.lambda.util.world.fastEntitySearch +import net.minecraft.entity.player.PlayerEntity import com.lambda.threading.runSafe import com.lambda.threading.runSafeAutomated import com.lambda.util.BlockUtils.blockState @@ -67,6 +70,15 @@ object PacketMine : Module( .onValueChange { _, to -> if (!to) queuePositions.clear() } private val queueOrder by setting("Queue Order", QueueOrder.Standard, "Which end of the queue to break blocks from") { queue } + private val autoCity by setting("Auto City", false, "Automatically targets and mines surround blocks of nearby enemies") + private val cityRange by setting("City Range", 5.0, 2.0..8.0, 0.5, "Maximum range to search for enemy players to city") { autoCity } + private val cityBurrow by setting("City Burrow", true, "Prioritizes burrow blocks if target is burrowed") { autoCity } + private val cityFriends by setting("City Friends", false, "Whether to target friends with Auto City") { autoCity } + + private const val CITY_RENDERS_GROUP = "City Renders" + @Group(CITY_RENDERS_GROUP) private val renderCity by setting("Render City", true, "Renders the Auto City block target") { autoCity } + @Group(CITY_RENDERS_GROUP) private val cityColor by setting("City Color", Color(0, 255, 255, 120)) { autoCity && renderCity } + private const val REBREAK_RENDERS_GROUP = "ReBreak Renders" private const val QUEUE_RENDERS_GROUP = "Queue Renders" @@ -172,11 +184,29 @@ object PacketMine : Module( } listen { + val cityTarget = findCityTarget() + val requestList = mutableListOf() + breakPositions.filterNotNull().forEach { requestList.add(it) } + requestList.addAll(queueSorted.flatten()) + + if (cityTarget != null && !requestList.contains(cityTarget)) { + requestList.add(cityTarget) + } + if (!attackedThisTick) { - requestBreakManager((breakPositions + queueSorted.flatten()).toList()) - if (!breakConfig.rebreak || (rebreakMode != RebreakMode.Auto /*&& rebreakMode != RebreakMode.AutoConstant*/)) return@listen + requestBreakManager(requestList) + } + + if (breakConfig.rebreak && (rebreakMode == RebreakMode.Auto || rebreakMode == RebreakMode.AutoConstant)) { val reBreak = rebreakPos ?: return@listen - requestBreakManager(listOf(reBreak), true) + val state = blockState(reBreak) + if (rebreakMode == RebreakMode.AutoConstant) { + if (!state.isAir && state.getHardness(world, reBreak) >= 0) { + requestBreakManager(listOf(reBreak), true) + } + } else if (!attackedThisTick) { + requestBreakManager(listOf(reBreak), true) + } } } @@ -189,6 +219,16 @@ object PacketMine : Module( } } } + if (autoCity && renderCity) { + runSafe { + findCityTarget()?.let { pos -> + box(pos) { + hideFill() + outlineColor(cityColor) + } + } + } + } if (!renderQueue) return@tickedRenderer runSafe { queueSorted.forEachIndexed { index, positions -> @@ -299,6 +339,36 @@ object PacketMine : Module( forEach { if (it.any(predicate)) return true } return false } + private fun SafeContext.findCityTarget(): BlockPos? { + if (!autoCity) return null + val targets = fastEntitySearch(cityRange).filter { + it != player && it.isAlive && (cityFriends || !FriendHandler.isFriend(it.uuid)) + }.sortedBy { it.squaredDistanceTo(player) } + + val maxReachSq = 4.5 * 4.5 + + for (target in targets) { + val feetPos = target.blockPos + if (cityBurrow) { + val state = blockState(feetPos) + if (!state.isAir && state.getHardness(world, feetPos) >= 0 && feetPos.distSq(player.eyePos) <= maxReachSq) { + return feetPos + } + } + + val surroundPositions = arrayOf( + feetPos.north(), feetPos.south(), feetPos.east(), feetPos.west() + ) + val validSurround = surroundPositions.filter { pos -> + val state = blockState(pos) + !state.isAir && state.getHardness(world, pos) >= 0 && pos.distSq(player.eyePos) <= maxReachSq + }.minByOrNull { it.distSq(player.eyePos) } + + if (validSurround != null) return validSurround + } + return null + } + private enum class RebreakMode( override val displayName: String, @@ -306,8 +376,7 @@ object PacketMine : Module( ) : NamedEnum, Describable { Manual("Manual", "Re-break only when you trigger it explicitly."), Auto("Auto", "Automatically re-break when it’s beneficial or required."), - //ToDo: Implement auto constant rebreak -// AutoConstant("Auto (Constant)", "Continuously re-break as soon as conditions allow; most aggressive.") + AutoConstant("Auto Constant", "Continuously re-break as soon as a block is placed; most aggressive civbreak.") } private enum class QueueOrder( diff --git a/src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt b/src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt new file mode 100644 index 000000000..214f69c68 --- /dev/null +++ b/src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt @@ -0,0 +1,331 @@ +/* + * Copyright 2026 Lambda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lambda.module.modules.player + +import com.lambda.config.automation.setDefaultAutomationConfig +import com.lambda.config.blocks.EatConfig +import com.lambda.config.blocks.EatConfig.Companion.reasonEating +import com.lambda.config.hideAllExcept +import com.lambda.config.withEdits +import com.lambda.context.SafeContext +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.container.containers.HotbarContainer +import com.lambda.interaction.container.selection.select +import com.lambda.interaction.manager.managers.hotbar.HotbarRequestBuilder.Companion.hotbarRequest +import com.lambda.interaction.manager.managers.inventory.InvRequestBuilder.Companion.inventoryRequest +import com.lambda.module.Module +import com.lambda.module.ModuleTag +import com.lambda.module.modules.combat.AutoTotem +import com.lambda.module.modules.combat.KillAura +import com.lambda.threading.runSafe +import com.lambda.threading.runSafeAutomated +import com.lambda.util.Describable +import com.lambda.util.NamedEnum +import com.lambda.util.extension.fullHealth +import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.util.ActionResult +import net.minecraft.util.Hand + +@Suppress("unused") +object SilentEat : Module( + name = "SilentEat", + description = "Silently eats food from inventory without equipping it", + tag = ModuleTag.PLAYER, + modulePriority = 95 +) { + val mode by setting("Mode", Mode.Smart, "Eating mode: Smart (Offhand with AutoTotem safety), Offhand, or MainHand") + val safetyHealth by setting("Safety Health", 12, 6..36, 1, "Minimum health threshold to allow offhand eating in Smart mode") + val pauseKillAura by setting("Pause KillAura", true, "Pauses KillAura during MainHand eating to prevent hit cancellation") + val silentVisual by setting("Silent Visual", true, "Hides the food item visually in first person") + + enum class Mode(override val displayName: String, override val description: String) : NamedEnum, Describable { + Smart("Smart", "Uses Offhand when safe for simultaneous KillAura/PacketMine, yields to AutoTotem when in danger"), + Offhand("Offhand", "Swaps food into offhand and restores original item afterwards"), + MainHand("MainHand", "Uses hotbar silent swap, keeping offhand completely untouched for AutoTotem") + } + + private enum class State { + IDLE, + SWAPPING, + EATING, + RESTORING + } + + private var state = State.IDLE + private var activeHand: Hand? = null + private var swappedOffhand = false + private var foodSlotId: Int = -1 + private var originalOffhandStack: ItemStack = ItemStack.EMPTY + private var swappedHotbar = false + private var originalHotbarSlot: Int = -1 + private var originalHotbarItemSlotId: Int = -1 + private var eatStack: ItemStack? = null + private var reason = EatConfig.Reason.None + private var holdingUse = false + private var ticksInState = 0 + + @JvmStatic val isSilentEating: Boolean get() = isEnabled && state == State.EATING + @JvmStatic val isUsingOffhand: Boolean get() = isEnabled && state == State.EATING && activeHand == Hand.OFF_HAND + @JvmStatic val visualOffhandStack: ItemStack get() = originalOffhandStack + + init { + setDefaultAutomationConfig() + .withEdits { + hideAllExcept(::eatConfig, ::inventoryConfig, ::hotbarConfig) + } + + AutoTotem.offhandOverride = { isUsingOffhand } + + listen { + when (state) { + State.IDLE -> { + val currentReason = runSafeAutomated { reasonEating() } + if (!currentReason.shouldEat()) return@listen + startEatingProcess(currentReason) + } + State.SWAPPING -> tickSwapping() + State.EATING -> tickEating() + State.RESTORING -> tickRestoring() + } + } + + onDisable { + runSafe { cleanupAndReset() } + } + } + + private fun SafeContext.startEatingProcess(currentReason: EatConfig.Reason) { + if (player.currentScreenHandler !== player.playerScreenHandler) return + + val targetHand = when (mode) { + Mode.Smart -> { + val inDanger = player.fullHealth < safetyHealth || (AutoTotem.isEnabled && AutoTotem.isDangerous(this)) + if (inDanger) Hand.MAIN_HAND else Hand.OFF_HAND + } + Mode.Offhand -> Hand.OFF_HAND + Mode.MainHand -> Hand.MAIN_HAND + } + + val selection = currentReason.selector() + val slots = player.currentScreenHandler.slots + + if (targetHand == Hand.OFF_HAND) { + val alreadyInOffhand = selection.matches(player.offHandStack) && !player.offHandStack.isEmpty + if (alreadyInOffhand) { + originalOffhandStack = player.offHandStack.copy() + foodSlotId = -1 + swappedOffhand = false + activeHand = Hand.OFF_HAND + reason = currentReason + eatStack = player.offHandStack.copy() + state = State.EATING + ticksInState = 0 + interactFood(Hand.OFF_HAND) + } else { + val foodSlot = slots.firstOrNull { slot -> + slot.id in 9..44 && selection.matches(slot.stack) && !slot.stack.isEmpty + } ?: return + + originalOffhandStack = player.offHandStack.copy() + foodSlotId = foodSlot.id + swappedOffhand = true + activeHand = Hand.OFF_HAND + reason = currentReason + eatStack = foodSlot.stack.copy() + state = State.SWAPPING + ticksInState = 0 + + inventoryRequest { + swapWithHotbar(foodSlot.id, 40) + }.submit() + } + } else { + // Main Hand mode + val hotbarMatch = HotbarContainer.slots.firstOrNull { selection.matches(it.stack) && !it.stack.isEmpty } + if (hotbarMatch != null) { + originalHotbarSlot = player.inventory.selectedSlot + swappedHotbar = false + activeHand = Hand.MAIN_HAND + reason = currentReason + eatStack = hotbarMatch.stack.copy() + + if (pauseKillAura) KillAura.isPaused = true + + if (hotbarMatch.index == player.inventory.selectedSlot) { + state = State.EATING + ticksInState = 0 + interactFood(Hand.MAIN_HAND) + } else { + state = State.SWAPPING + ticksInState = 0 + hotbarRequest(hotbarMatch.index).submit() + } + } else { + val invMatch = slots.firstOrNull { slot -> + slot.id in 9..35 && selection.matches(slot.stack) && !slot.stack.isEmpty + } ?: return + + originalHotbarSlot = player.inventory.selectedSlot + originalHotbarItemSlotId = invMatch.id + swappedHotbar = true + activeHand = Hand.MAIN_HAND + reason = currentReason + eatStack = invMatch.stack.copy() + + if (pauseKillAura) KillAura.isPaused = true + + state = State.SWAPPING + ticksInState = 0 + + inventoryRequest { + swapWithHotbar(invMatch.id, player.inventory.selectedSlot) + }.submit() + } + } + } + + private fun SafeContext.tickSwapping() { + ticksInState++ + + val hand = activeHand ?: run { + cleanupAndReset() + return + } + + val currentHeld = if (hand == Hand.OFF_HAND) player.offHandStack else player.mainHandStack + val selection = reason.selector() + + if (selection.matches(currentHeld) && !currentHeld.isEmpty) { + // Food is now in hand; start eating! + eatStack = currentHeld.copy() + state = State.EATING + ticksInState = 0 + interactFood(hand) + return + } + + // Swap timeout: if not in hand after 10 ticks, abort + if (ticksInState > 10) { + cleanupAndReset() + } + } + + private fun SafeContext.interactFood(hand: Hand) { + val result = interaction.interactItem(player, hand) + if (result is ActionResult.Success) { + if (result.swingSource == ActionResult.SwingSource.CLIENT) { + player.swingHand(hand) + } + mc.gameRenderer.firstPersonRenderer.resetEquipProgress(hand) + } + mc.options.useKey.isPressed = true + holdingUse = true + } + + private fun SafeContext.tickEating() { + ticksInState++ + + val hand = activeHand ?: run { + cleanupAndReset() + return + } + + // Safety check for AutoTotem in offhand mode + if (hand == Hand.OFF_HAND) { + val inDanger = player.fullHealth < safetyHealth || (AutoTotem.isEnabled && AutoTotem.isDangerous(this)) + if (inDanger) { + cleanupAndReset() + return + } + } + + // Maintain use key + if (!holdingUse || !mc.options.useKey.isPressed) { + mc.options.useKey.isPressed = true + holdingUse = true + } + + // If after 3 ticks the player isn't using item, retry interaction once + if (ticksInState == 3 && !player.isUsingItem) { + interactFood(hand) + } + + // Check if food was consumed or should stop + val currentHeld = if (hand == Hand.OFF_HAND) player.offHandStack else player.mainHandStack + val isFoodStillHeld = reason.selector().matches(currentHeld) && !currentHeld.isEmpty + + val finishedEating = (ticksInState >= 32 && !player.isUsingItem) + || (ticksInState >= 32 && !isFoodStillHeld) + || (!reason.shouldKeepEating(eatStack) && ticksInState >= 5) + + if (finishedEating || ticksInState > 45) { + state = State.RESTORING + ticksInState = 0 + } + } + + private fun SafeContext.tickRestoring() { + cleanupAndReset() + } + + private fun SafeContext.cleanupAndReset() { + if (holdingUse) { + mc.options.useKey.isPressed = false + holdingUse = false + } + interaction.stopUsingItem(player) + + if (pauseKillAura) { + KillAura.isPaused = false + } + + if (swappedOffhand) { + // Guard: Do not overwrite Totem of Undying if AutoTotem equipped one during an emergency abort + if (foodSlotId != -1 && player.offHandStack.item != Items.TOTEM_OF_UNDYING) { + inventoryRequest { + swapWithHotbar(foodSlotId, 40) + }.submit() + } + swappedOffhand = false + foodSlotId = -1 + originalOffhandStack = ItemStack.EMPTY + } + + if (swappedHotbar) { + if (originalHotbarItemSlotId != -1 && originalHotbarSlot != -1) { + inventoryRequest { + swapWithHotbar(originalHotbarItemSlotId, originalHotbarSlot) + }.submit() + } + swappedHotbar = false + originalHotbarItemSlotId = -1 + } + + if (originalHotbarSlot != -1) { + hotbarRequest(originalHotbarSlot).submit() + originalHotbarSlot = -1 + } + + state = State.IDLE + activeHand = null + eatStack = null + ticksInState = 0 + } +} diff --git a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt index 4e4d97de9..8b0d2a493 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/StackReplenish.kt @@ -65,10 +65,12 @@ object StackReplenish : Module( InventoryContainer.stacks.forEach { invStack -> if (!ItemStack.areItemsAndComponentsEqual(invStack, stack)) return@forEach val invId = invStack.slotId + val targetId = stack.slotId + if (invId == -1 || targetId == -1) return@forEach val completing = stack.count + invStack.count >= stack.maxCount val tooMany = invStack.count + stack.count > stack.maxCount inventoryRequest { - moveSlot(invId, stack.slotId) + moveSlot(invId, targetId) if (tooMany) pickup(invId) }.submit() if (completing) return diff --git a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt index bfd335b50..b9e289f4c 100644 --- a/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/AcquireStackTask.kt @@ -47,7 +47,8 @@ class AcquireStackTask @Ta5kBuilder internal constructor( runSafeAutomated { selection.transfer(toSelection = HotbarContainer.select()) .onSuccess { result -> success(result.stackSelection) } - .start() + .onFailure { failure(it) } + .execute(this@AcquireStackTask) } } } diff --git a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt index 8ab79138a..c2f46dcfe 100644 --- a/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/ContainerTransferTask.kt @@ -94,12 +94,12 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( findContainers( containerSelection(toSelection.scope) { matches(toSelection) - hasStack(toStack.mutate(1)) + hasSpace(fromStack.mutate(1)) } ).toList() - .takeIf { toStack isIn it } + .takeIf { fromStack spaceIn it } ?: run { - failure("Could not find destination containers for $toStack") + failure("Could not find destination containers with space for $fromStack") return } @@ -110,8 +110,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( fromStack.mutate(count = if (fromStack.count <= 0) 0 else fromStack.count - transferred) private fun isComplete() = - (fromStack.count <= 0 && transferred > 0) || (fromStack.count != 0 && transferred >= fromStack.count) - + fromStack.count > 0 && transferred >= fromStack.count private fun buildResult() = TransferResult( stackSelection { @@ -159,7 +158,9 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( if (fromContainer.count(fromStack) <= 0) fromQueue.remove(fromContainer) if (!bothExternal && toContainer.spaceLeft(fromStack) <= 0) toQueue.remove(toContainer) transferNextPair(fromQueue, toQueue) - }.start() + }.onFailure { + failure(it) + }.execute(this@ContainerTransferTask) } /** @@ -205,11 +206,12 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( private fun pushChain( destination: Container, toQueue: MutableList - ): Task<*> = - taskOrNull { destination.access() }.then { destinationContext -> + ): Task<*> { + val chain = taskOrNull { destination.access() }.then { destinationContext -> SwapTask(ContainerSelection.HOTBAR_AND_INVENTORY, destination.select()) .thenOrNull { destinationContext?.close() } - }.onSuccess { + } + chain.onSuccess { if (isComplete()) return@onSuccess if (destination.spaceLeft(fromStack) == 0) toQueue.remove(destination) @@ -219,8 +221,12 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( if (!playerHasItems) return@onSuccess val nextDestination = toQueue.firstOrNull() ?: return@onSuccess - pushChain(nextDestination, toQueue).start() + pushChain(nextDestination, toQueue).execute(this@ContainerTransferTask) + }.onFailure { + failure(it) } + return chain + } /** * Swaps items between containers matching [fromSelection] and [toSelection] one slot per tick. @@ -241,9 +247,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( init { listen { runSafeAutomated { - while (true) { - if (swapStack()) break - } + swapStack() } } } @@ -278,11 +282,8 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( val (fromContainer, toContainer, slots) = moveSlots val (fromSlot, toSlot) = slots val moveCount = - minOf( - fromSlot.stack.count, - if (fromStack.count == 0) Int.MAX_VALUE - else fromStack.count - transferred - ) + if (fromStack.count <= 0) fromSlot.stack.count + else minOf(fromSlot.stack.count, fromStack.count - transferred) if (!fromContainer.swap(fromSlot, toSlot, toContainer)) { failure("Swap failed for $fromStack") @@ -295,7 +296,7 @@ class ContainerTransferTask @Ta5kBuilder internal constructor( resultContainers.add(toContainer) } - if (fromStack.count == 0 || isComplete()) { + if (isComplete()) { success() return true } diff --git a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt index 1e987d79e..546523535 100644 --- a/src/main/kotlin/com/lambda/task/tasks/EatTask.kt +++ b/src/main/kotlin/com/lambda/task/tasks/EatTask.kt @@ -47,7 +47,7 @@ class EatTask @Ta5kBuilder internal constructor( private var eatStack: ItemStack? = null private var reason = EatConfig.Reason.None private var holdingUse = false - + private var activeTransfer: ContainerTransferTask? = null override fun SafeContext.onStart() { reason = runSafeAutomated { reasonEating() } } @@ -73,11 +73,17 @@ class EatTask @Ta5kBuilder internal constructor( } else { if (InventoryContainer.slots.any { selection.matches(it) }) { runSafeAutomated { - transfer( - selection, - InventoryContainer.select(), - HotbarContainer.select() - ).start() + if (activeTransfer == null || activeTransfer?.state in listOf(Task.State.Completed, Task.State.Failed, Task.State.Cancelled)) { + activeTransfer = transfer( + selection, + InventoryContainer.select(), + HotbarContainer.select() + ).apply { + onSuccess { activeTransfer = null } + onFailure { activeTransfer = null } + start() + } + } return@listen } } From 040f38609c0fa3e297af1047fde4c5ec29bdccb3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 13 Sep 2026 14:12:40 +0300 Subject: [PATCH 18/18] fix(SilentEat): ensure reliable cleanup, offhand safety, and instant item release --- .../kotlin/com/lambda/gui/LambdaScreen.kt | 2 +- .../lambda/gui/components/ClickGuiLayout.kt | 106 ++++++++++-------- .../com/lambda/gui/components/QuickSearch.kt | 4 +- .../lambda/module/modules/player/SilentEat.kt | 6 +- 4 files changed, 68 insertions(+), 50 deletions(-) diff --git a/src/main/kotlin/com/lambda/gui/LambdaScreen.kt b/src/main/kotlin/com/lambda/gui/LambdaScreen.kt index 56d9817a4..03849936b 100644 --- a/src/main/kotlin/com/lambda/gui/LambdaScreen.kt +++ b/src/main/kotlin/com/lambda/gui/LambdaScreen.kt @@ -83,7 +83,7 @@ object LambdaScreen : Screen(Text.of("Lambda")) { || (win != null && (InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_LEFT_CONTROL) || InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_RIGHT_CONTROL))) if (input.key() == GLFW.GLFW_KEY_F && isCtrl) { - QuickSearch.toggle() + if (!QuickSearch.isOpen) QuickSearch.open() return true } diff --git a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt index 49d332477..efd91f654 100644 --- a/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt +++ b/src/main/kotlin/com/lambda/gui/components/ClickGuiLayout.kt @@ -46,6 +46,7 @@ import com.lambda.imgui.flag.ImGuiCol import com.lambda.imgui.flag.ImGuiCond import com.lambda.imgui.flag.ImGuiHoveredFlags import com.lambda.imgui.flag.ImGuiWindowFlags +import com.lambda.imgui.flag.ImGuiKey import com.lambda.imgui.type.ImString import com.lambda.module.ModuleRegistry import com.lambda.module.ModuleTag @@ -67,6 +68,8 @@ import net.minecraft.client.gui.screen.ingame.CommandBlockScreen import net.minecraft.client.gui.screen.ingame.SignEditScreen import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen import net.minecraft.client.util.Icons +import net.minecraft.client.util.InputUtil +import org.lwjgl.glfw.GLFW import java.awt.Color import kotlin.math.abs import kotlin.math.max @@ -179,8 +182,16 @@ object ClickGuiLayout : Loadable, Config( @Tab(GENERAL_TAB) var highlightEnabledModules by setting("Highlight Enabled Modules", true, "Show visual accent bar and highlight on active modules") @Tab(GENERAL_TAB) var allowWindowCollapse by setting("Allow Window Collapse", true, "Allow category windows to collapse by clicking arrow or double-clicking title bar") @Tab(GENERAL_TAB) var categoryWindowSearch by setting("Category Window Search", false, "Show a search filter at the top of category windows") - @Tab(GENERAL_TAB) var showCategoryCounts by setting("Show Category Counts", true, "Display enabled/total module count in window titles [X/Y]") - + @Tab(GENERAL_TAB) var showCategoryCounts by setting("Show Category Counts", true, "Display enabled/total module count in category window headers") + @Tab(GENERAL_TAB) var categoryWindowWidth by setting("Category Width", 115, 75..220, 5, "Default width for category windows in pixels", unit = "px") + .onValueChange { _, newWidth -> + val scale = currentScale + val w = newWidth.toFloat() * scale + shownTags.forEach { pendingSizes[it.name] = w to 0f } + } + @Tab(GENERAL_TAB) var maxCategoryHeight by setting("Max Category Height", 0.72f, 0.30f..0.95f, 0.02f, "Maximum height of category windows relative to screen height", unit = "%") + @Tab(GENERAL_TAB) val tileWindowsAction by setting("Tile Windows", { tileWindows() }, "Auto-arrange all category windows into neat columns that fit the screen") + @Tab(GENERAL_TAB) val resetLayoutAction by setting("Reset Windows", { resetWindowPositions() }, "Reset all category windows to default positions and sizes") // Snapping @Tab(SNAPPING_TAB) val snapEnabled by setting("Enable Snapping", true, "Master toggle for GUI/HUD snapping") @Tab(SNAPPING_TAB) val gridSize by setting("Grid Size", 25f, 2f..128f, 1f, "Grid step in pixels") { snapEnabled } @@ -196,7 +207,7 @@ object ClickGuiLayout : Loadable, Config( // Sizing @Tab(SIZING_TAB) val windowPaddingX by setting("Window Padding X", 8.0f, 0.0f..20.0f, 0.1f) @Tab(SIZING_TAB) val windowPaddingY by setting("Window Padding Y", 8.0f, 0.0f..20.0f, 0.1f) - @Tab(SIZING_TAB) val windowMinSizeX by setting("Window Min Size X", 180.0f, 50.0f..300.0f, 1.0f) + @Tab(SIZING_TAB) val windowMinSizeX by setting("Window Min Size X", 90.0f, 40.0f..250.0f, 1.0f) @Tab(SIZING_TAB) val windowMinSizeY by setting("Window Min Size Y", 32.0f, 0.0f..100.0f, 1.0f) @Tab(SIZING_TAB) val windowTitleAlignX by setting("Window Title Align X", 0.0f, 0.0f..1.0f, 0.01f) @Tab(SIZING_TAB) val windowTitleAlignY by setting("Window Title Align Y", 0.5f, 0.0f..1.0f, 0.01f) @@ -316,20 +327,21 @@ object ClickGuiLayout : Loadable, Config( fun tileWindows() { val startX = 20f - val startY = MenuBar.height + 15f - val padding = 14f + val startY = MenuBar.height + 12f val scale = currentScale - val windowWidth = 200f * scale + val windowWidth = categoryWindowWidth.toFloat() * scale + val padding = 10f * scale val displayWidth = DearImGui.io.displaySize.x - val cols = max(1, ((displayWidth - startX * 2) / (windowWidth + padding)).toInt()) + val cols = max(1, ((displayWidth - startX * 2 + padding) / (windowWidth + padding)).toInt()) var col = 0 var row = 0 val tags = if (developerMode) shownTags + ModuleTag.DEBUG else shownTags tags.forEach { tag -> val x = startX + col * (windowWidth + padding) - val y = startY + row * (280f * scale) + val y = startY + row * (260f * scale) pendingPositions[tag.name] = x to y + pendingSizes[tag.name] = windowWidth to 0f col++ if (col >= cols) { col = 0 @@ -341,27 +353,7 @@ object ClickGuiLayout : Loadable, Config( fun resetWindowPositions() { pendingPositions.clear() pendingSizes.clear() - val startX = 20f - val baseY = MenuBar.height + 12f - val padding = 14f - val scale = currentScale - val windowWidth = 200f * scale - val displayWidth = DearImGui.io.displaySize.x - val cols = max(1, ((displayWidth - startX * 2) / (windowWidth + padding)).toInt()) - - var col = 0 - var row = 0 - val tags = if (developerMode) shownTags + ModuleTag.DEBUG else shownTags - tags.forEach { tag -> - val x = startX + col * (windowWidth + padding) - val y = baseY + row * (280f * scale) - pendingPositions[tag.name] = x to y - col++ - if (col >= cols) { - col = 0 - row++ - } - } + tileWindows() } fun applyTheme(preset: ThemePreset) { @@ -651,23 +643,42 @@ object ClickGuiLayout : Loadable, Config( val tags = if (developerMode) shownTags + ModuleTag.DEBUG else shownTags if (tags.isEmpty()) return@buildLayout + val displayWidth = DearImGui.io.displaySize.x + val scale = currentScale + val defaultWinWidth = categoryWindowWidth.toFloat() * scale + val paddingX = 10f * scale var nextX = 20f - val baseY = MenuBar.height + 10f + var nextY = MenuBar.height + 10f tags.forEach { tag -> val override = pendingPositions[tag.name] if (override != null) { ImGui.setNextWindowPos(override.first, override.second) + if (activeDragWindowName != tag.name) { + pendingPositions.remove(tag.name) + } } else if (frameCount >= 1) { - ImGui.setNextWindowPos(nextX, baseY, ImGuiCond.FirstUseEver) + if (nextX + defaultWinWidth > displayWidth - 10f && nextX > 20f) { + nextX = 20f + nextY += 260f * scale + } + ImGui.setNextWindowPos(nextX, nextY, ImGuiCond.FirstUseEver) } - val scale = currentScale - ImGui.setNextWindowSize(200f * scale, 0f, ImGuiCond.FirstUseEver) - pendingSizes[tag.name]?.let { (w, h) -> - ImGui.setNextWindowSizeConstraints(w, h, w, h) - } ?: run { - ImGui.setNextWindowSizeConstraints(185f * scale, 0f, 360f * scale, io.displaySize.y * 0.88f) + val pendingSize = pendingSizes[tag.name] + if (pendingSize != null) { + val (w, h) = pendingSize + if (h <= 0f) { + ImGui.setNextWindowSize(w, 0f) + pendingSizes.remove(tag.name) + } else { + ImGui.setNextWindowSizeConstraints(w, h, w, h) + } + } else { + val minW = windowMinSizeX.coerceAtMost(categoryWindowWidth.toFloat()) * scale + val maxH = io.displaySize.y * maxCategoryHeight + ImGui.setNextWindowSizeConstraints(minW, 0f, 320f * scale, maxH) + ImGui.setNextWindowSize(defaultWinWidth, 0f, ImGuiCond.FirstUseEver) } val windowFlags = if (allowWindowCollapse) ImGuiWindowFlags.None else ImGuiWindowFlags.NoCollapse @@ -696,13 +707,6 @@ object ClickGuiLayout : Loadable, Config( .filter { filterText.isEmpty() || it.name.contains(filterText, ignoreCase = true) } .forEach { with(ModuleEntry(it)) { buildLayout() } } - popupContextWindow("##cat-ctx-${tag.name}") { - menuItem("Tile Windows (Auto-Arrange)") { tileWindows() } - menuItem("Reset Layout") { resetWindowPositions() } - separator() - menuItem("Expand All in ${tag.name}") { expandAllModules(tag) } - menuItem("Collapse All") { collapseAllModules() } - } snapOverlays[tag.name]?.let { vis -> drawSnapLines(vis.snapX, vis.kindX, vis.snapY, vis.kindY) @@ -711,16 +715,28 @@ object ClickGuiLayout : Loadable, Config( val rect = RectF(windowPos.x, windowPos.y, windowSize.x, windowSize.y) if (mouseDown) claimInteraction(tag.name, rect) + // Clamp if window was pushed off the right of the screen + if (windowPos.x + 30f > displayWidth) { + ImGui.setWindowPos(max(10f, displayWidth - windowSize.x - 10f), windowPos.y) + } + SnapHandler.registerElement(tag.name, rect) lastBounds[tag.name] = rect - nextX += ImGui.getWindowWidth() + 20f + nextX += (if (override != null) ImGui.getWindowWidth() else defaultWinWidth) + paddingX } } if (frameCount++ == 1) { initialLayoutComplete = true } + // Global shortcut to open QuickSearch + val win = mc.window + val isCtrlDown = DearImGui.io.keyCtrl || (win != null && (InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_LEFT_CONTROL) || InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_RIGHT_CONTROL))) + if (isCtrlDown && ImGui.isKeyPressed(ImGuiKey.F, false)) { + if (!QuickSearch.isOpen) QuickSearch.open() + } + renderQuickSearch() if (developerMode) { diff --git a/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt b/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt index affba406f..aa299520b 100644 --- a/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt +++ b/src/main/kotlin/com/lambda/gui/components/QuickSearch.kt @@ -579,8 +579,8 @@ object QuickSearch { val win = mc.window val isCtrl = (event.modifiers and GLFW.GLFW_MOD_CONTROL != 0) || (win != null && (InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_LEFT_CONTROL) || InputUtil.isKeyPressed(win, GLFW.GLFW_KEY_RIGHT_CONTROL))) - if (event.keyCode == GLFW.GLFW_KEY_F && isCtrl) { - toggle() + if ((event.keyCode == GLFW.GLFW_KEY_F || event.translated == KeyCode.F) && isCtrl) { + if (!isOpen) open() else close() event.cancel() return } diff --git a/src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt b/src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt index 214f69c68..d8fc689fd 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/SilentEat.kt @@ -106,7 +106,7 @@ object SilentEat : Module( } } - onDisable { + onDisableUnsafe { runSafe { cleanupAndReset() } } } @@ -290,7 +290,9 @@ object SilentEat : Module( mc.options.useKey.isPressed = false holdingUse = false } - interaction.stopUsingItem(player) + if (player.isUsingItem) { + interaction.stopUsingItem(player) + } if (pauseKillAura) { KillAura.isPaused = false