mirror of
https://github.com/cabaletta/baritone
synced 2024-12-17 20:55:09 +00:00
Allow autoTool
to pull tools from the inventory
This commit is contained in:
parent
827ce7e2a8
commit
bc18f0eabd
@ -23,7 +23,8 @@ import baritone.api.utils.Helper;
|
||||
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;
|
||||
@ -140,6 +141,7 @@ public final class InventoryBehavior extends Behavior implements Helper {
|
||||
}
|
||||
|
||||
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 -> {
|
||||
@ -189,11 +191,11 @@ public final class InventoryBehavior extends Behavior implements Helper {
|
||||
}
|
||||
|
||||
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
|
||||
@ -202,8 +204,7 @@ public final class InventoryBehavior extends Behavior implements Helper {
|
||||
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:
|
||||
@ -232,6 +233,7 @@ public final class InventoryBehavior extends Behavior implements Helper {
|
||||
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;
|
||||
});
|
||||
@ -244,6 +246,14 @@ public final class InventoryBehavior extends Behavior implements Helper {
|
||||
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);
|
||||
}
|
||||
@ -320,7 +330,7 @@ public final class InventoryBehavior extends Behavior implements Helper {
|
||||
|
||||
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()) {
|
||||
|
@ -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;
|
||||
@ -592,8 +592,13 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ package baritone.utils;
|
||||
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;
|
||||
@ -27,11 +28,13 @@ 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;
|
||||
|
||||
/**
|
||||
@ -84,7 +87,9 @@ public final class ToolSet {
|
||||
* @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());
|
||||
}
|
||||
|
||||
@ -93,13 +98,12 @@ public final class ToolSet {
|
||||
* 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;
|
||||
}
|
||||
@ -111,51 +115,36 @@ public final class ToolSet {
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user