baritone/src/main/java/baritone/bot/utils/ToolSet.java

162 lines
5.4 KiB
Java
Raw Normal View History

2018-08-08 03:16:53 +00:00
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone is distributed in the hope that it will be useful,
2018-08-08 03:16:53 +00:00
* 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
2018-08-02 17:49:31 +00:00
package baritone.bot.utils;
2018-08-01 15:34:35 +00:00
import net.minecraft.block.Block;
2018-08-01 15:42:42 +00:00
import net.minecraft.block.state.IBlockState;
2018-08-01 15:34:35 +00:00
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
2018-08-07 00:43:20 +00:00
import net.minecraft.init.Items;
2018-08-01 15:34:35 +00:00
import net.minecraft.item.Item;
2018-08-01 18:32:21 +00:00
import net.minecraft.item.ItemAir;
2018-08-01 15:34:35 +00:00
import net.minecraft.item.ItemStack;
2018-08-01 18:05:35 +00:00
import net.minecraft.item.ItemTool;
2018-08-01 15:42:42 +00:00
import net.minecraft.util.NonNullList;
2018-08-01 15:34:35 +00:00
import net.minecraft.util.math.BlockPos;
2018-08-02 17:49:31 +00:00
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
2018-08-01 15:34:35 +00:00
/**
2018-08-02 17:49:31 +00:00
* A cached list of the best tools on the hotbar for any block
2018-08-01 15:34:35 +00:00
*
* @author avecowa
*/
public class ToolSet {
2018-08-01 15:42:42 +00:00
2018-08-07 00:43:20 +00:00
private static final Item FALLBACK_ITEM = Items.APPLE;
2018-08-02 17:49:31 +00:00
/**
* 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.
*/
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)
*/
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.
*/
Map<Block, Byte> cache = new HashMap<>();
2018-08-01 15:42:42 +00:00
2018-08-02 17:49:31 +00:00
/**
* Create a toolset from the current player's inventory (but don't calculate any hardness values just yet)
*/
2018-08-01 15:34:35 +00:00
public ToolSet() {
EntityPlayerSP p = Minecraft.getMinecraft().player;
2018-08-01 15:42:42 +00:00
NonNullList<ItemStack> inv = p.inventory.mainInventory;
2018-08-02 17:49:31 +00:00
tools = new ArrayList<>();
slots = new ArrayList<>();
2018-08-01 15:34:35 +00:00
boolean fnull = false;
for (byte i = 0; i < 9; i++) {
2018-08-01 18:32:21 +00:00
if (!fnull || ((!(inv.get(i).getItem() instanceof ItemAir)) && inv.get(i).getItem() instanceof ItemTool)) {
2018-08-02 17:49:31 +00:00
tools.add(inv.get(i).getItem() instanceof ItemTool ? (ItemTool) inv.get(i).getItem() : null);
2018-08-01 15:34:35 +00:00
slots.add(i);
2018-08-01 18:32:21 +00:00
fnull |= (inv.get(i).getItem() instanceof ItemAir) || (!inv.get(i).getItem().isDamageable());
2018-08-01 15:34:35 +00:00
}
}
}
2018-08-01 15:42:42 +00:00
2018-08-02 17:49:31 +00:00
/**
* A caching wrapper around getBestToolIndex
*
* @param b the blockstate to be mined
* @return get which tool on the hotbar is best for mining it
*/
2018-08-01 15:42:42 +00:00
public Item getBestTool(IBlockState b) {
if (cache.get(b.getBlock()) != null) {
return tools.get(cache.get(b.getBlock()));
2018-08-01 15:34:35 +00:00
}
2018-08-01 18:05:35 +00:00
return tools.get(getBestToolIndex(b));
}
2018-08-02 17:49:31 +00:00
/**
* Calculate which tool on the hotbar is best for mining
*
* @param b the blockstate to be mined
* @return a byte indicating the index in the tools array that worked best
*/
2018-08-01 18:05:35 +00:00
private byte getBestToolIndex(IBlockState b) {
2018-08-01 15:34:35 +00:00
byte best = 0;
2018-08-01 18:05:35 +00:00
float value = -1;
2018-08-01 15:34:35 +00:00
for (byte i = 0; i < tools.size(); i++) {
Item item = tools.get(i);
if (item == null) {
2018-08-07 00:43:20 +00:00
item = FALLBACK_ITEM;
2018-08-01 15:34:35 +00:00
}
2018-08-01 18:05:35 +00:00
float v = item.getDestroySpeed(new ItemStack(item), b);
if (v < value || value == -1) {
2018-08-01 15:34:35 +00:00
value = v;
best = i;
}
}
2018-08-01 15:42:42 +00:00
cache.put(b.getBlock(), best);
2018-08-01 18:05:35 +00:00
return best;
2018-08-01 15:34:35 +00:00
}
2018-08-01 15:42:42 +00:00
2018-08-02 17:49:31 +00:00
/**
* Get which hotbar slot should be selected for fastest mining
*
* @param b the blockstate to be mined
* @return a byte indicating which hotbar slot worked best
*/
2018-08-01 15:42:42 +00:00
public byte getBestSlot(IBlockState b) {
if (cache.get(b.getBlock()) != null) {
return slots.get(cache.get(b.getBlock()));
2018-08-01 15:34:35 +00:00
}
2018-08-01 18:05:35 +00:00
return slots.get(getBestToolIndex(b));
2018-08-01 15:34:35 +00:00
}
2018-08-01 15:42:42 +00:00
2018-08-02 17:49:31 +00:00
/**
* Using the best tool on the hotbar, how long would it take to mine this block
*
* @param b the blockstate to be mined
* @param pos the blockpos to be mined
* @return how long it would take in ticks
*/
2018-08-01 15:42:42 +00:00
public double getStrVsBlock(IBlockState b, BlockPos pos) {
2018-08-01 15:34:35 +00:00
Item item = this.getBestTool(b);
if (item == null) {
2018-08-07 00:43:20 +00:00
item = FALLBACK_ITEM;
2018-08-01 15:34:35 +00:00
}
float f = b.getBlockHardness(Minecraft.getMinecraft().world, pos);
2018-08-01 18:05:35 +00:00
return f < 0.0F ? 0.0F : (!canHarvest(b, item) ? item.getDestroySpeed(new ItemStack(item), b) / f / 100.0F : item.getDestroySpeed(new ItemStack(item), b) / f / 30.0F);
2018-08-01 15:34:35 +00:00
}
2018-08-01 15:42:42 +00:00
2018-08-02 17:49:31 +00:00
/**
* Whether a tool can be efficiently used against a block
*
* @param blockIn the blockstate to be mined
* @param item the tool to be used
* @return whether or not this tool would help
*/
2018-08-01 15:42:42 +00:00
public boolean canHarvest(IBlockState blockIn, Item item) {
2018-08-01 15:34:35 +00:00
if (blockIn.getMaterial().isToolNotRequired()) {
return true;
} else {
return new ItemStack(item).canHarvestBlock(blockIn);
}
}
}