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.
|
|
|
|
*
|
2018-08-08 04:15:22 +00:00
|
|
|
* 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
|
|
|
|
2018-08-21 01:32:18 +00:00
|
|
|
import baritone.bot.Baritone;
|
|
|
|
import baritone.bot.event.events.ItemSlotEvent;
|
|
|
|
import baritone.bot.event.listener.AbstractGameEventListener;
|
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;
|
|
|
|
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
|
|
|
*
|
2018-08-21 01:32:18 +00:00
|
|
|
* @author avecowa, Brady
|
2018-08-01 15:34:35 +00:00
|
|
|
*/
|
2018-08-10 05:08:29 +00:00
|
|
|
public class ToolSet implements Helper {
|
2018-08-07 00:43:20 +00:00
|
|
|
|
2018-08-21 01:32:18 +00:00
|
|
|
/**
|
|
|
|
* Instance of the internal event listener used to hook into Baritone's event bus
|
|
|
|
*/
|
|
|
|
private static final InternalEventListener INTERNAL_EVENT_LISTENER = new InternalEventListener();
|
|
|
|
|
|
|
|
static {
|
|
|
|
Baritone.INSTANCE.getGameEventHandler().registerEventListener(INTERNAL_EVENT_LISTENER);
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
*/
|
2018-08-10 05:08:29 +00:00
|
|
|
private List<ItemTool> tools;
|
|
|
|
|
2018-08-02 17:49:31 +00:00
|
|
|
/**
|
|
|
|
* 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)
|
|
|
|
*/
|
2018-08-10 05:08:29 +00:00
|
|
|
private List<Byte> slots;
|
|
|
|
|
2018-08-02 17:49:31 +00:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2018-08-10 05:08:29 +00:00
|
|
|
private 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
|
|
|
|
*
|
2018-08-10 05:08:29 +00:00
|
|
|
* @param state the blockstate to be mined
|
2018-08-02 17:49:31 +00:00
|
|
|
* @return get which tool on the hotbar is best for mining it
|
|
|
|
*/
|
2018-08-10 05:08:29 +00:00
|
|
|
public Item getBestTool(IBlockState state) {
|
|
|
|
return tools.get(cache.computeIfAbsent(state.getBlock(), block -> getBestToolIndex(state)));
|
2018-08-01 18:05:35 +00:00
|
|
|
}
|
|
|
|
|
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);
|
2018-08-10 05:08:29 +00:00
|
|
|
if (item == null)
|
|
|
|
continue;
|
|
|
|
|
2018-08-01 18:05:35 +00:00
|
|
|
float v = item.getDestroySpeed(new ItemStack(item), b);
|
2018-08-13 14:14:11 +00:00
|
|
|
if (v > value || value == -1) {
|
2018-08-01 15:34:35 +00:00
|
|
|
value = v;
|
|
|
|
best = i;
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
*
|
2018-08-10 05:08:29 +00:00
|
|
|
* @param state the blockstate to be mined
|
2018-08-02 17:49:31 +00:00
|
|
|
* @return a byte indicating which hotbar slot worked best
|
|
|
|
*/
|
2018-08-10 05:08:29 +00:00
|
|
|
public byte getBestSlot(IBlockState state) {
|
|
|
|
return slots.get(cache.computeIfAbsent(state.getBlock(), block -> getBestToolIndex(state)));
|
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
|
|
|
|
*
|
2018-08-10 05:08:29 +00:00
|
|
|
* @param state the blockstate to be mined
|
2018-08-14 18:25:30 +00:00
|
|
|
* @param pos the blockpos to be mined
|
2018-08-02 17:49:31 +00:00
|
|
|
* @return how long it would take in ticks
|
|
|
|
*/
|
2018-08-10 05:08:29 +00:00
|
|
|
public double getStrVsBlock(IBlockState state, BlockPos pos) {
|
|
|
|
// Calculate the slot with the best item
|
|
|
|
byte slot = this.getBestSlot(state);
|
2018-08-01 15:42:42 +00:00
|
|
|
|
2018-08-21 01:32:18 +00:00
|
|
|
INTERNAL_EVENT_LISTENER.setOverrideSlot(slot);
|
2018-08-10 05:08:29 +00:00
|
|
|
|
|
|
|
// Calculate the relative hardness of the block to the player
|
|
|
|
float hardness = state.getPlayerRelativeBlockHardness(player(), world(), pos);
|
|
|
|
|
|
|
|
// Restore the old slot
|
2018-08-21 01:32:18 +00:00
|
|
|
INTERNAL_EVENT_LISTENER.setOverrideSlot(-1);
|
2018-08-10 05:08:29 +00:00
|
|
|
|
|
|
|
return hardness;
|
2018-08-01 15:34:35 +00:00
|
|
|
}
|
2018-08-21 01:32:18 +00:00
|
|
|
|
|
|
|
private static final class InternalEventListener implements AbstractGameEventListener {
|
|
|
|
|
|
|
|
private int overrideSlot;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onQueryItemSlotForBlocks(ItemSlotEvent event) {
|
|
|
|
if (this.overrideSlot >= 0)
|
|
|
|
event.setSlot(this.overrideSlot);
|
|
|
|
}
|
|
|
|
|
2018-08-21 22:52:09 +00:00
|
|
|
final void setOverrideSlot(int overrideSlot) {
|
2018-08-21 01:32:18 +00:00
|
|
|
this.overrideSlot = overrideSlot;
|
|
|
|
}
|
|
|
|
}
|
2018-08-01 15:34:35 +00:00
|
|
|
}
|