Skip to content

Commit

Permalink
Allow autoTool to pull tools from the inventory
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeroMemes committed Jul 6, 2023
1 parent 827ce7e commit bc18f0e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 56 deletions.
22 changes: 16 additions & 6 deletions src/main/java/baritone/behavior/InventoryBehavior.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
import baritone.api.utils.InventorySlot;
import baritone.api.utils.Pair;
import baritone.utils.ToolSet;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.Reference2BooleanMap;
import it.unimi.dsi.fastutil.objects.Reference2BooleanOpenHashMap;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
Expand Down Expand Up @@ -140,6 +141,7 @@ private boolean requestSwapWithHotBar(int inInventory, int inHotbar) {
}

private InventorySlot bestToolAgainst(final Block against, final Class<? extends ItemTool> cla$$) {
// TODO: Replace with ToolSet.getBestSlot
return this.findBestSlotMatching(
Comparator.comparingDouble(stack -> ToolSet.calculateSpeedVsBlock(stack, against.getDefaultState())),
stack -> {
Expand Down Expand Up @@ -189,11 +191,11 @@ public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
}

public boolean canSelectItem(Predicate<? super ItemStack> desired) {
return this.resolveSelectionStrategy(desired) != null;
return this.resolveSelectionStrategy(this.findSlotMatching(desired)) != null;
}

public boolean trySelectItem(Predicate<? super ItemStack> desired) {
final SelectionStrategy strategy = this.resolveSelectionStrategy(desired);
final SelectionStrategy strategy = this.resolveSelectionStrategy(this.findSlotMatching(desired));
if (strategy != null) {
strategy.run();
// TODO: Consider cases where returning the SelectionType is needed/useful to the caller
Expand All @@ -202,8 +204,7 @@ public boolean trySelectItem(Predicate<? super ItemStack> desired) {
return false;
}

public SelectionStrategy resolveSelectionStrategy(Predicate<? super ItemStack> desired) {
final InventorySlot slot = this.findSlotMatching(desired);
public SelectionStrategy resolveSelectionStrategy(final InventorySlot slot) {
if (slot != null) {
switch (slot.getType()) {
case HOTBAR:
Expand Down Expand Up @@ -232,6 +233,7 @@ public SelectionStrategy resolveSelectionStrategy(Predicate<? super ItemStack> d
if (this.canAccessInventory()) {
return SelectionStrategy.of(SelectionType.ENQUEUED, () -> {
// TODO: Determine if hotbar swap can be immediate, and return type accordingly
// Also don't only swap into slot 7 that's silly
requestSwapWithHotBar(slot.getInventoryIndex(), 7);
ctx.player().inventory.currentItem = 7;
});
Expand All @@ -244,6 +246,14 @@ public SelectionStrategy resolveSelectionStrategy(Predicate<? super ItemStack> d
return null;
}

public InventorySlot findBestAccessibleMatching(final Comparator<? super ItemStack> comparator,
final Predicate<? super ItemStack> filter) {
final Stream<Pair<InventorySlot, ItemStack>> accessible = this.canAccessInventory()
? ctx.inventory().allSlots()
: Stream.concat(ctx.inventory().hotbarSlots(), Stream.of(ctx.inventory().offhand()));
return this.findBestMatching0(accessible, comparator, filter);
}

public InventorySlot findSlotMatching(final Predicate<? super ItemStack> filter) {
return this.findBestSlotMatching(null, filter);
}
Expand Down Expand Up @@ -320,7 +330,7 @@ public enum SelectionType {

private static final class ItemInteractionHelper {

private static final Map<Class<? extends Item>, Boolean> CACHE = new Reference2ReferenceOpenHashMap<>();
private static final Reference2BooleanMap<Class<? extends Item>> CACHE = new Reference2BooleanOpenHashMap<>();

public static boolean couldInteract(final ItemStack stack) {
if (stack.isEmpty()) {
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/baritone/pathing/movement/MovementHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
package baritone.pathing.movement;

import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.*;
import baritone.api.utils.input.Input;
import baritone.behavior.InventoryBehavior;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.pathing.precompute.Ternary;
import baritone.utils.BlockStateInterface;
Expand Down Expand Up @@ -592,8 +592,13 @@ static void switchToBestToolFor(IPlayerContext ctx, IBlockState state) {
* @param ts Previously calculated ToolSet
*/
static void switchToBestToolFor(IPlayerContext ctx, IBlockState state, ToolSet ts, boolean preferSilkTouch) {
if (Baritone.settings().autoTool.value && !Baritone.settings().assumeExternalAutoTool.value) {
ctx.player().inventory.currentItem = ts.getBestSlot(state, preferSilkTouch, false);
if (ToolSet.isAutoTool()) {
// TODO: Submit through InventoryBehavior, instead of executing the strategy here
final InventorySlot slot = ts.getBestSlot(state, preferSilkTouch);
final InventoryBehavior.SelectionStrategy strategy = ((Baritone) ctx.baritone()).getInventoryBehavior().resolveSelectionStrategy(slot);
if (strategy != null) {
strategy.run();
}
}
}

Expand Down
83 changes: 36 additions & 47 deletions src/main/java/baritone/utils/ToolSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,21 @@
import baritone.Baritone;
import baritone.PerformanceCritical;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.InventorySlot;
import baritone.utils.accessor.IItemTool;
import it.unimi.dsi.fastutil.HashCommon;
import it.unimi.dsi.fastutil.objects.Reference2DoubleOpenHashMap;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.init.Enchantments;
import net.minecraft.init.Items;
import net.minecraft.init.MobEffects;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.item.ItemTool;

import java.util.Comparator;
import java.util.function.ToDoubleFunction;

/**
Expand Down Expand Up @@ -84,7 +87,9 @@ public double getStrVsBlock(IBlockState state) {
* @return A double containing the destruction speed with the best tool
*/
private double getBestDestructionSpeed(IBlockState state) {
final ItemStack stack = ctx.player().inventory.getStackInSlot(this.getBestSlot(state, false, true));
final ItemStack stack = isAutoTool()
? ctx.inventory().itemAt(this.getBestSlot(state, false))
: ctx.player().getHeldItemMainhand();
return calculateSpeedVsBlock(stack, state) * avoidanceMultiplier(state.getBlock());
}

Expand All @@ -93,13 +98,12 @@ private double getBestDestructionSpeed(IBlockState state) {
* harvest level order; there is a chance for multiple at the same with modded tools
* but in that case we don't really care.
*
* @param itemStack a possibly empty ItemStack
* @param stack a possibly empty ItemStack
* @return The tool's harvest level, or {@code -1} if the stack isn't a tool
*/
private static int getMaterialCost(ItemStack itemStack) {
if (itemStack.getItem() instanceof ItemTool) {
ItemTool tool = (ItemTool) itemStack.getItem();
return ((IItemTool) tool).getHarvestLevel();
private static int getMaterialCost(ItemStack stack) {
if (stack.getItem() instanceof IItemTool) {
return ((IItemTool) stack.getItem()).getHarvestLevel();
} else {
return -1;
}
Expand All @@ -111,51 +115,36 @@ private static int getMaterialCost(ItemStack itemStack) {
*
* @param state the blockstate to be mined
* @param preferSilkTouch whether to prefer silk touch tools
* @param pathingCalculation whether the call to this method is for pathing calculation
* @return An int containing the index in the tools array that worked best
*/
public int getBestSlot(IBlockState state, boolean preferSilkTouch, boolean pathingCalculation) {
public InventorySlot getBestSlot(IBlockState state, boolean preferSilkTouch) {
final Comparator<ItemStack> compare = Comparator
// Prioritize mining speed over everything
.<ItemStack>comparingDouble(stack -> calculateSpeedVsBlock(stack, state))
// Prioritize silk touch tools, if preferSilkTouch is true, over reduced material cost
.thenComparing(ToolSet::hasSilkTouch, (a, b) -> preferSilkTouch ? Boolean.compare(a, b) : 0)
// Minimize material cost
.thenComparing(Comparator.comparingInt(ToolSet::getMaterialCost).reversed());

/*
If we actually want know what efficiency our held item has instead of the best one
possible, this lets us make pathing depend on the actual tool to be used (if auto tool is disabled)
*/
if (!Baritone.settings().autoTool.value && pathingCalculation) {
return ctx.player().inventory.currentItem;
}

int best = 0;
double highestSpeed = Double.NEGATIVE_INFINITY;
int lowestCost = Integer.MIN_VALUE;
boolean bestSilkTouch = false;
for (int i = 0; i < 9; i++) {
ItemStack itemStack = ctx.player().inventory.getStackInSlot(i);
if (!Baritone.settings().useSwordToMine.value && itemStack.getItem() instanceof ItemSword) {
continue;
}

if (Baritone.settings().itemSaver.value && (itemStack.getItemDamage() + Baritone.settings().itemSaverThreshold.value) >= itemStack.getMaxDamage() && itemStack.getMaxDamage() > 1) {
continue;
}
double speed = calculateSpeedVsBlock(itemStack, state);
boolean silkTouch = hasSilkTouch(itemStack);
if (speed > highestSpeed) {
highestSpeed = speed;
best = i;
lowestCost = getMaterialCost(itemStack);
bestSilkTouch = silkTouch;
} else if (speed == highestSpeed) {
int cost = getMaterialCost(itemStack);
if ((cost < lowestCost && (silkTouch || !bestSilkTouch)) ||
(preferSilkTouch && !bestSilkTouch && silkTouch)) {
highestSpeed = speed;
best = i;
lowestCost = cost;
bestSilkTouch = silkTouch;
return ((Baritone) ctx.baritone()).getInventoryBehavior().findBestAccessibleMatching(
compare,
stack -> {
if (!Baritone.settings().useSwordToMine.value && stack.getItem() instanceof ItemSword) {
return false;
}
if (Baritone.settings().itemSaver.value
&& stack.getItemDamage() + Baritone.settings().itemSaverThreshold.value >= stack.getMaxDamage()
&& stack.getMaxDamage() > 1
) {
return false;
}
return true;
}
}
}
return best;
);
}

public static boolean isAutoTool() {
return Baritone.settings().autoTool.value && !Baritone.settings().assumeExternalAutoTool.value;
}

/**
Expand Down

0 comments on commit bc18f0e

Please sign in to comment.