Skip to content

Commit

Permalink
Full predicate logic selection support
Browse files Browse the repository at this point in the history
  • Loading branch information
Avanatiker committed Aug 12, 2023
1 parent 856f5f4 commit 02d3d64
Show file tree
Hide file tree
Showing 18 changed files with 300 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import baritone.api.BaritoneAPI
import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.inventory.AcquireItemInActiveHand
import com.lambda.client.activity.activities.inventory.core.SwapOrSwitchToSlot
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.activity.activities.travel.CollectDrops
import com.lambda.client.activity.types.*
import com.lambda.client.event.SafeClientEvent
Expand Down Expand Up @@ -334,15 +334,15 @@ class BreakBlock(
context = BuildActivity.Context.RESTOCK

addSubActivities(AcquireItemInActiveHand(
ItemInfo(tool, predicate = {
when {
forceSilk -> EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, it) == 1
forceNoSilk -> EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, it) == 0
forceFortune -> EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, it) > 0
forceNoFortune -> EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, it) == 0
else -> true
StackSelection().apply {
selection = isItem(tool) and when {
forceSilk -> hasEnchantment(Enchantments.SILK_TOUCH)
forceNoSilk -> hasEnchantment(Enchantments.SILK_TOUCH).not()
forceFortune -> hasEnchantment(Enchantments.FORTUNE)
forceNoFortune -> hasEnchantment(Enchantments.FORTUNE).not()
else -> isItem<Item>()
}
}),
}
))
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.lambda.client.activity.activities.construction.core
import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.interaction.Rotate
import com.lambda.client.activity.activities.inventory.AcquireItemInActiveHand
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.activity.types.*
import com.lambda.client.event.SafeClientEvent
import com.lambda.client.event.events.PacketEvent
Expand Down Expand Up @@ -305,9 +305,9 @@ class PlaceBlock(
) {
context = BuildActivity.Context.RESTOCK

addSubActivities(AcquireItemInActiveHand(
ItemInfo(optimalStack.item, metadata = optimalStack.metadata)
))
addSubActivities(AcquireItemInActiveHand(StackSelection().apply {
selection = isItem(optimalStack.item) and hasMetadata(optimalStack.metadata)
}))
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.lambda.client.activity.activities.interaction
import com.lambda.client.LambdaMod
import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.inventory.AcquireItemInActiveHand
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.activity.types.RotatingActivity
import com.lambda.client.activity.types.TimeoutActivity
import com.lambda.client.event.SafeClientEvent
Expand Down Expand Up @@ -31,7 +31,7 @@ class AttachItemFrame(
rotation = getRotationTo(getHitVec(placePos, facing))

addSubActivities(
AcquireItemInActiveHand(ItemInfo(Items.ITEM_FRAME))
AcquireItemInActiveHand(StackSelection().apply { selection = isItem(Items.ITEM_FRAME) })
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.lambda.client.activity.activities.interaction

import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.inventory.AcquireItemInActiveHand
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.activity.types.RotatingActivity
import com.lambda.client.activity.types.TimeoutActivity
import com.lambda.client.event.SafeClientEvent
Expand All @@ -29,7 +29,7 @@ class AttachMap(
rotation = getRotationToEntity(itemFrame)

addSubActivities(
AcquireItemInActiveHand(ItemInfo(Items.MAP, predicate = { it.itemDamage == mapID })),
AcquireItemInActiveHand(StackSelection().apply { selection = isItem(Items.MAP) and hasDamage(mapID) })
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ package com.lambda.client.activity.activities.interaction.crafting

import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.inventory.AcquireItemInActiveHand
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.event.SafeClientEvent
import com.lambda.client.util.items.item
import net.minecraft.init.Blocks
import net.minecraft.init.Items

class CraftShulkerBox : Activity() {
override fun SafeClientEvent.onInitialize() {
addSubActivities(
AcquireItemInActiveHand(ItemInfo(Items.SHULKER_SHELL)),
AcquireItemInActiveHand(ItemInfo(Blocks.CHEST.item)),
AcquireItemInActiveHand(StackSelection().apply { selection = isItem(Items.SHULKER_SHELL) }),
AcquireItemInActiveHand(StackSelection().apply { selection = isBlock(Blocks.CHEST) }),
// InventoryTransaction(0, )
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.interaction.UseThrowableOnEntity
import com.lambda.client.activity.activities.inventory.AcquireItemInActiveHand
import com.lambda.client.activity.activities.inventory.TakeOffArmor
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.activity.types.LoopWhileActivity
import com.lambda.client.event.SafeClientEvent
import net.minecraft.init.Items
Expand All @@ -19,7 +19,7 @@ class ReachXPLevel(
override fun SafeClientEvent.onInitialize() {
addSubActivities(
TakeOffArmor(),
AcquireItemInActiveHand(ItemInfo(Items.EXPERIENCE_BOTTLE)),
AcquireItemInActiveHand(StackSelection().apply { selection = isItem(Items.EXPERIENCE_BOTTLE) }),
UseThrowableOnEntity(player)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import com.lambda.client.activity.activities.inventory.core.SwapOrSwitchToSlot
import com.lambda.client.activity.activities.inventory.core.SwitchToHotbarSlot
import com.lambda.client.activity.activities.storage.BreakDownEnderChests
import com.lambda.client.activity.activities.storage.ShulkerTransaction
import com.lambda.client.activity.activities.storage.types.ContainerAction
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.ShulkerOrder
import com.lambda.client.activity.getShulkerInventory
import com.lambda.client.activity.activities.storage.types.*
import com.lambda.client.activity.types.AttemptActivity
import com.lambda.client.event.SafeClientEvent
import com.lambda.client.module.modules.client.BuildTools
Expand All @@ -24,12 +21,9 @@ import net.minecraft.item.ItemStack

/**
* [AcquireItemInActiveHand] is an [Activity] that attempts to acquire an [Item] in the player's active hand.
* It will attempt to acquire the item in the following order:
* 1. Switch to the hotbar slot that contains the item
* 2. Swap the item with an item in the hotbar
*/
class AcquireItemInActiveHand(
private val itemInfo: ItemInfo,
private val order: StackSelection,
private val searchShulkerBoxes: Boolean = true,
private val searchEnderChest: Boolean = true,
) : AttemptActivity, Activity() {
Expand All @@ -38,37 +32,39 @@ class AcquireItemInActiveHand(

override fun SafeClientEvent.onInitialize() {
// If the item is already in the player's hand, we're done
if (itemInfo.stackFilter(player.heldItemMainhand)) {
if (order.selection(player.heldItemMainhand)) {
success()
return
}

// If the item is in the hotbar, switch to it
player.hotbarSlots.firstOrNull(itemInfo.slotFilter)?.let {
player.hotbarSlots.firstOrNull(order.filter)?.let {
addSubActivities(SwitchToHotbarSlot(it))
return
}

// If we are in game mode creative, we can just use the creative inventory (if item not yet in hotbar)
if (pickBlock && player.capabilities.isCreativeMode) {
addSubActivities(CreativeInventoryAction(itemInfo.optimalStack))
return
order.optimalStack?.let {
addSubActivities(CreativeInventoryAction(it))
return
}
}

// If the item is in the inventory, swap it with next best slot in hotbar
player.allSlots.firstOrNull(itemInfo.slotFilter)?.let { slotFrom ->
// If the item is in the inventory, swap it with the next best slot in hotbar
player.allSlots.firstOrNull(order.filter)?.let { slotFrom ->
addSubActivities(SwapOrSwitchToSlot(slotFrom))
return
}

// If the item is in a shulker box, extract it
if (searchShulkerBoxes && itemInfo.item !is ItemShulkerBox) {
addSubActivities(ShulkerTransaction(ShulkerOrder(ContainerAction.PULL, itemInfo.item, itemInfo.number)))
if (searchShulkerBoxes && order.item !is ItemShulkerBox) {
addSubActivities(ShulkerTransaction(ContainerAction.PULL, order))
return
}

// If the item is obsidian, break down ender chests
if (itemInfo.item == Blocks.OBSIDIAN.item) {
if (order.item == Blocks.OBSIDIAN.item) {
addSubActivities(BreakDownEnderChests(maximumRepeats = BuildTools.breakDownCycles))
return
}
Expand All @@ -77,22 +73,22 @@ class AcquireItemInActiveHand(
// if (searchEnderChest) {
// // TODO: Check cached ender chest inventory if item is in there directly or in a shulker box
// player.allSlots.firstOrNull { it.stack.item == Blocks.ENDER_CHEST.item }?.let { slot ->
// addSubActivities(ExtractItemFromContainerStack(slot.stack, itemInfo))
// addSubActivities(EnderChestTransaction(ShulkerOrder(ContainerAction.PULL, order.item, order.amount), slot))
// return
// }
//
// addSubActivities(AcquireItemInActiveHand(ItemInfo(Blocks.ENDER_CHEST.item), searchEnderChest = false))
// addSubActivities(AcquireItemInActiveHand(order, searchEnderChest = false))
// return
// }

failedWith(NoItemFoundException(itemInfo))
failedWith(NoItemFoundException(order))
}

override fun SafeClientEvent.onSuccess() {
val currentItemStack = player.heldItemMainhand

if (!itemInfo.stackFilter(currentItemStack)) {
failedWith(FailedToMoveItemException(itemInfo, currentItemStack))
if (!order.selection(currentItemStack)) {
failedWith(FailedToMoveItemException(order, currentItemStack))
}
}

Expand All @@ -102,14 +98,6 @@ class AcquireItemInActiveHand(
status = Status.UNINITIALIZED
}

private fun SafeClientEvent.selectOptimalShulker() = player.allSlots.mapNotNull { slot ->
getShulkerInventory(slot.stack)?.let { inventory ->
val count = inventory.count(itemInfo.stackFilter)

if (count > 0) slot to count else null
}
}.minByOrNull { it.second }?.first

class NoItemFoundException(itemInfo: ItemInfo) : Exception("No $itemInfo found in inventory")
class FailedToMoveItemException(itemInfo: ItemInfo, currentStack: ItemStack) : Exception("Failed to move $itemInfo} to hotbar (current item: ${currentStack.item.registryName})")
class NoItemFoundException(order: StackSelection) : Exception("No $order found in inventory")
class FailedToMoveItemException(order: StackSelection, currentStack: ItemStack) : Exception("Failed to move ${order.item?.registryName?.path} to hotbar (current item: ${currentStack.item.registryName?.path})")
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.construction.core.BreakBlock
import com.lambda.client.activity.activities.inventory.AcquireItemInActiveHand
import com.lambda.client.activity.activities.storage.core.PlaceContainer
import com.lambda.client.activity.activities.storage.types.ContainerAction
import com.lambda.client.activity.activities.storage.types.ItemInfo
import com.lambda.client.activity.activities.storage.types.ItemOrder
import com.lambda.client.activity.activities.storage.types.ShulkerOrder
import com.lambda.client.activity.activities.storage.types.*
import com.lambda.client.activity.types.RepeatingActivity
import com.lambda.client.event.SafeClientEvent
import com.lambda.client.module.modules.client.BuildTools
Expand All @@ -33,7 +30,9 @@ class BreakDownEnderChests(
if (freeSlots.isEmpty()) {
if (player.inventorySlots.countItem(Blocks.OBSIDIAN.item) > 0) {
addSubActivities(
ShulkerTransaction(ShulkerOrder(ContainerAction.PUSH, Blocks.OBSIDIAN.item, 0))
ShulkerTransaction(ContainerAction.PUSH, StackSelection().apply {
selection = isBlock(Blocks.OBSIDIAN)
})
)
return
}
Expand All @@ -42,22 +41,20 @@ class BreakDownEnderChests(
return
}

// ToDo: Better way to find ender chest
addSubActivities(
PlaceContainer(ItemStack(Blocks.ENDER_CHEST, 1, 0), onlyItem = true)
PlaceContainer(StackSelection().apply {
selection = isBlock(Blocks.ENDER_CHEST)
})
)
}

override fun SafeClientEvent.onChildSuccess(childActivity: Activity) {
if (childActivity !is PlaceContainer) return

addSubActivities(
AcquireItemInActiveHand(ItemInfo(
Items.DIAMOND_PICKAXE,
predicate = {
EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, it) == 0
}
)),
AcquireItemInActiveHand(StackSelection().apply {
selection = isItem(Items.DIAMOND_PICKAXE) and hasEnchantment(Enchantments.SILK_TOUCH).not()
}),
BreakBlock(
childActivity.containerPos,
collectDrops = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@ import com.lambda.client.activity.activities.storage.core.CloseContainer
import com.lambda.client.activity.activities.storage.core.ContainerWindowTransaction
import com.lambda.client.activity.activities.storage.core.PlaceContainer
import com.lambda.client.activity.activities.storage.types.ContainerAction
import com.lambda.client.activity.activities.storage.types.ItemOrder
import com.lambda.client.activity.activities.storage.types.ShulkerOrder
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.event.SafeClientEvent
import com.lambda.client.util.items.allSlots

/**
* Push or pull item from a fitting shulker from inventory
*/
class ShulkerTransaction(
val order: ShulkerOrder
val action: ContainerAction,
val order: StackSelection
) : Activity() {
override fun SafeClientEvent.onInitialize() {
if (order.action == ContainerAction.PULL) {
if (action == ContainerAction.PULL) {
player.allSlots.mapNotNull {
order.findShulkerToPull(it)
}.minByOrNull { it.second }?.first?.let { slot ->
addSubActivities(
PlaceContainer(slot.stack.copy(), open = true)
PlaceContainer(StackSelection().apply {
selection = isItemStack(slot.stack)
}, open = true)
)
return
}
Expand All @@ -32,7 +34,9 @@ class ShulkerTransaction(
order.findShulkerToPush(it)
}.minByOrNull { it.second }?.first?.let { slot ->
addSubActivities(
PlaceContainer(slot.stack.copy(), open = true)
PlaceContainer(StackSelection().apply {
selection = isItemStack(slot.stack)
}, open = true)
)
return
}
Expand All @@ -43,7 +47,7 @@ class ShulkerTransaction(
if (childActivity !is PlaceContainer) return

addSubActivities(
ContainerWindowTransaction(ItemOrder(order.action, order.item, order.amount)),
ContainerWindowTransaction(action, order),
CloseContainer(),
BreakBlock(
childActivity.containerPos,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package com.lambda.client.activity.activities.storage

import baritone.api.pathing.goals.GoalBlock
import baritone.api.pathing.goals.GoalGetToBlock
import baritone.api.pathing.goals.GoalXZ
import com.lambda.client.activity.Activity
import com.lambda.client.activity.activities.storage.core.CloseContainer
import com.lambda.client.activity.activities.storage.core.ContainerWindowTransaction
import com.lambda.client.activity.activities.storage.core.OpenContainer
import com.lambda.client.activity.activities.storage.types.ContainerAction
import com.lambda.client.activity.activities.storage.types.Stash
import com.lambda.client.activity.activities.storage.types.ContainerOrder
import com.lambda.client.activity.activities.storage.types.StackSelection
import com.lambda.client.activity.activities.travel.CustomGoal
import com.lambda.client.activity.types.LoopWhileActivity
import com.lambda.client.event.SafeClientEvent
Expand All @@ -22,12 +22,12 @@ import net.minecraft.tileentity.TileEntity
* @param orders The orders to pull or push items.
*/
class StashTransaction(
private val orders: Set<Pair<Stash, ContainerOrder>>
private val orders: Set<Triple<Stash, ContainerAction, StackSelection>>
) : LoopWhileActivity, Activity() {
override val loopWhile: SafeClientEvent.() -> Boolean = { orderQueue.isNotEmpty() }
override var currentLoops = 0

private val orderQueue = ArrayDeque(orders.sortedBy { it.second.action })
private val orderQueue = ArrayDeque(orders.sortedBy { it.second })
// try different containers in case one is not matching the search
private val containerQueue = ArrayDeque<TileEntity>()

Expand Down Expand Up @@ -68,7 +68,7 @@ class StashTransaction(
addSubActivities(
CustomGoal(GoalGetToBlock(container.pos)),
OpenContainer(container.pos),
ContainerWindowTransaction(order.second),
ContainerWindowTransaction(order.second, order.third),
CloseContainer()
)
}
Expand Down
Loading

0 comments on commit 02d3d64

Please sign in to comment.