fix tool set once and for all, fixes #136
This commit is contained in:
@@ -17,55 +17,24 @@
|
||||
|
||||
package baritone.utils;
|
||||
|
||||
import baritone.api.event.events.ItemSlotEvent;
|
||||
import baritone.api.event.listener.AbstractGameEventListener;
|
||||
import baritone.Baritone;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemAir;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.init.Enchantments;
|
||||
import net.minecraft.init.MobEffects;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemTool;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A cached list of the best tools on the hotbar for any block
|
||||
*
|
||||
* @author avecowa, Brady
|
||||
* @author avecowa, Brady, leijurv
|
||||
*/
|
||||
public class ToolSet implements Helper {
|
||||
|
||||
/**
|
||||
* Instance of the internal event listener used to hook into Baritone's event bus
|
||||
*/
|
||||
public static final InternalEventListener INTERNAL_EVENT_LISTENER = new InternalEventListener();
|
||||
|
||||
/**
|
||||
* A list of tools on the hotbar that should be considered.
|
||||
* Note that if there are no tools on the hotbar this list will still have one (null) entry.
|
||||
*/
|
||||
private List<ItemTool> tools;
|
||||
|
||||
/**
|
||||
* A mapping from the tools array to what hotbar slots the tool is actually in.
|
||||
* tools.get(i) will be on your hotbar in slot slots.get(i)
|
||||
*/
|
||||
private List<Byte> slots;
|
||||
|
||||
/**
|
||||
* A mapping from a block to which tool index is best for it.
|
||||
* The values in this map are *not* hotbar slots indexes, they need to be looked up in slots
|
||||
* in order to be converted into hotbar slots.
|
||||
*/
|
||||
private Map<Block, Byte> slotCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* A cache mapping a {@link Block} to how long it will take to break
|
||||
* with this toolset, given the optimum tool is used.
|
||||
@@ -75,30 +44,7 @@ public class ToolSet implements Helper {
|
||||
/**
|
||||
* Create a toolset from the current player's inventory (but don't calculate any hardness values just yet)
|
||||
*/
|
||||
public ToolSet() {
|
||||
EntityPlayerSP p = Minecraft.getMinecraft().player;
|
||||
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||
tools = new ArrayList<>();
|
||||
slots = new ArrayList<>();
|
||||
boolean fnull = false;
|
||||
for (byte i = 0; i < 9; i++) {
|
||||
if (!fnull || ((!(inv.get(i).getItem() instanceof ItemAir)) && inv.get(i).getItem() instanceof ItemTool)) {
|
||||
tools.add(inv.get(i).getItem() instanceof ItemTool ? (ItemTool) inv.get(i).getItem() : null);
|
||||
slots.add(i);
|
||||
fnull |= (inv.get(i).getItem() instanceof ItemAir) || (!inv.get(i).getItem().isDamageable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A caching wrapper around getBestToolIndex
|
||||
*
|
||||
* @param state the blockstate to be mined
|
||||
* @return get which tool on the hotbar is best for mining it
|
||||
*/
|
||||
public Item getBestTool(IBlockState state) {
|
||||
return tools.get(slotCache.computeIfAbsent(state.getBlock(), block -> getBestToolIndex(state)));
|
||||
}
|
||||
public ToolSet() {}
|
||||
|
||||
/**
|
||||
* Calculate which tool on the hotbar is best for mining
|
||||
@@ -106,15 +52,11 @@ public class ToolSet implements Helper {
|
||||
* @param b the blockstate to be mined
|
||||
* @return a byte indicating the index in the tools array that worked best
|
||||
*/
|
||||
private byte getBestToolIndex(IBlockState b) {
|
||||
public byte getBestSlot(IBlockState b) {
|
||||
byte best = 0;
|
||||
float value = -1;
|
||||
for (byte i = 0; i < tools.size(); i++) {
|
||||
Item item = tools.get(i);
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
float v = item.getDestroySpeed(new ItemStack(item), b);
|
||||
double value = -1;
|
||||
for (byte i = 0; i < 9; i++) {
|
||||
double v = calculateStrVsBlock(i, b);
|
||||
if (v > value || value == -1) {
|
||||
value = v;
|
||||
best = i;
|
||||
@@ -123,25 +65,14 @@ public class ToolSet implements Helper {
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get which hotbar slot should be selected for fastest mining
|
||||
*
|
||||
* @param state the blockstate to be mined
|
||||
* @return a byte indicating which hotbar slot worked best
|
||||
*/
|
||||
public byte getBestSlot(IBlockState state) {
|
||||
return slots.get(slotCache.computeIfAbsent(state.getBlock(), block -> getBestToolIndex(state)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the best tool on the hotbar, how long would it take to mine this block
|
||||
*
|
||||
* @param state the blockstate to be mined
|
||||
* @param pos the blockpos to be mined
|
||||
* @return how long it would take in ticks
|
||||
*/
|
||||
public double getStrVsBlock(IBlockState state, BlockPos pos) {
|
||||
return this.breakStrengthCache.computeIfAbsent(state.getBlock(), b -> calculateStrVsBlock(state, pos));
|
||||
public double getStrVsBlock(IBlockState state) {
|
||||
return this.breakStrengthCache.computeIfAbsent(state.getBlock(), b -> calculateStrVsBlock(getBestSlot(state), state));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,36 +80,51 @@ public class ToolSet implements Helper {
|
||||
* in this toolset is used.
|
||||
*
|
||||
* @param state the blockstate to be mined
|
||||
* @param pos the blockpos to be mined
|
||||
* @return how long it would take in ticks
|
||||
*/
|
||||
private double calculateStrVsBlock(IBlockState state, BlockPos pos) {
|
||||
private double calculateStrVsBlock(byte slot, IBlockState state) {
|
||||
// Calculate the slot with the best item
|
||||
byte slot = this.getBestSlot(state);
|
||||
ItemStack contents = player().inventory.getStackInSlot(slot);
|
||||
|
||||
INTERNAL_EVENT_LISTENER.setOverrideSlot(slot);
|
||||
|
||||
// Calculate the relative hardness of the block to the player
|
||||
float hardness = state.getPlayerRelativeBlockHardness(player(), world(), pos);
|
||||
|
||||
// Restore the old slot
|
||||
INTERNAL_EVENT_LISTENER.setOverrideSlot(-1);
|
||||
|
||||
return hardness;
|
||||
}
|
||||
|
||||
private static final class InternalEventListener implements AbstractGameEventListener {
|
||||
|
||||
private int overrideSlot;
|
||||
|
||||
@Override
|
||||
public void onQueryItemSlotForBlocks(ItemSlotEvent event) {
|
||||
if (this.overrideSlot >= 0)
|
||||
event.setSlot(this.overrideSlot);
|
||||
float blockHard = state.getBlockHardness(null, null);
|
||||
if (blockHard < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final void setOverrideSlot(int overrideSlot) {
|
||||
this.overrideSlot = overrideSlot;
|
||||
float speed = contents.getDestroySpeed(state);
|
||||
if (speed > 1) {
|
||||
int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, contents);
|
||||
if (effLevel > 0 && !contents.isEmpty()) {
|
||||
speed += effLevel * effLevel + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Baritone.settings().considerPotionEffects.get()) {
|
||||
if (player().isPotionActive(MobEffects.HASTE)) {
|
||||
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
|
||||
}
|
||||
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
|
||||
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
|
||||
case 0:
|
||||
speed *= 0.3;
|
||||
break;
|
||||
case 1:
|
||||
speed *= 0.09;
|
||||
break;
|
||||
case 2:
|
||||
speed *= 0.0027;
|
||||
break;
|
||||
default:
|
||||
speed *= 0.00081;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
speed /= blockHard;
|
||||
if (state.getMaterial().isToolNotRequired() || (!contents.isEmpty() && contents.canHarvestBlock(state))) {
|
||||
return speed / 30;
|
||||
} else {
|
||||
return speed / 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user