567 lines
26 KiB
Java
567 lines
26 KiB
Java
package com.songoda.epichoppers.tasks;
|
|
|
|
import com.songoda.epichoppers.EpicHoppers;
|
|
import com.songoda.epichoppers.boost.BoostData;
|
|
import com.songoda.epichoppers.containers.CustomContainer;
|
|
import com.songoda.epichoppers.hopper.levels.modules.Module;
|
|
import com.songoda.epichoppers.hopper.levels.modules.ModuleAutoCrafting;
|
|
import com.songoda.epichoppers.settings.Settings;
|
|
import com.songoda.epichoppers.utils.HopperDirection;
|
|
import com.songoda.epichoppers.utils.Methods;
|
|
import com.songoda.epichoppers.utils.StorageContainerCache;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.OfflinePlayer;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockFace;
|
|
import org.bukkit.block.Hopper;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.Minecart;
|
|
import org.bukkit.entity.minecart.StorageMinecart;
|
|
import org.bukkit.inventory.Inventory;
|
|
import org.bukkit.inventory.InventoryHolder;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.IntStream;
|
|
|
|
public class HopTask extends BukkitRunnable {
|
|
private final EpicHoppers plugin;
|
|
private final int hopTicks;
|
|
|
|
public HopTask(EpicHoppers plugin) {
|
|
this.plugin = plugin;
|
|
this.hopTicks = Math.max(1, Settings.HOP_TICKS.getInt() / 2); // Purposeful integer division. Don't go below 1.
|
|
this.runTaskTimer(plugin, 0, 2);
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
for (final com.songoda.epichoppers.hopper.Hopper hopper : this.plugin.getHopperManager().getHoppers().values()) {
|
|
|
|
try {
|
|
// Get this hopper's location.
|
|
Location location = hopper.getLocation();
|
|
|
|
// Skip if chunk is not loaded.
|
|
if (location.getWorld() == null || !location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) {
|
|
continue;
|
|
}
|
|
|
|
// Get Hopper Block.
|
|
Block block = location.getBlock();
|
|
|
|
// If block is not a hopper continue.
|
|
if (block.getType() != Material.HOPPER) {
|
|
continue;
|
|
}
|
|
|
|
// If hopper block is powered, update its redstone state and continue.
|
|
if (block.getBlockPower() > 0) {
|
|
hopper.tryTick(this.hopTicks, false);
|
|
continue;
|
|
}
|
|
|
|
if (!hopper.tryTick(this.hopTicks, true)) {
|
|
continue;
|
|
}
|
|
|
|
// Amount to be moved.
|
|
BoostData boostData = this.plugin.getBoostManager().getBoost(hopper.getPlacedBy());
|
|
int maxToMove = hopper.getLevel().getAmount() * (boostData == null ? 1 : boostData.getMultiplier());
|
|
|
|
// Get hopper state data.
|
|
Hopper hopperState = (Hopper) block.getState();
|
|
HopperDirection hopperDirection = HopperDirection.getDirection(hopperState.getRawData());
|
|
Location pointingLocation = hopperDirection.getLocation(location);
|
|
final StorageContainerCache.Cache hopperCache = StorageContainerCache.getCachedInventory(block);
|
|
|
|
// Create list to hold blocked materials.
|
|
List<Material> blockedMaterials = new ArrayList<>();
|
|
|
|
// Cycle through modules.
|
|
hopper.getLevel().getRegisteredModules().stream()
|
|
.filter(Objects::nonNull)
|
|
.forEach(module -> {
|
|
try {
|
|
// Run Module
|
|
module.run(hopper, hopperCache);
|
|
|
|
// Add banned materials to list.
|
|
List<Material> materials = module.getBlockedItems(hopper);
|
|
if (materials != null && !materials.isEmpty()) {
|
|
blockedMaterials.addAll(materials);
|
|
}
|
|
} catch (Exception ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
});
|
|
|
|
// Process extra hopper pull
|
|
pullItemsFromContainers(hopper, hopperCache, maxToMove);
|
|
|
|
// Void out items
|
|
processVoidFilter(hopper, hopperCache, maxToMove);
|
|
|
|
// don't proccess any further if the hopper is empty or if all items are blocked
|
|
boolean doProcess = false;
|
|
for (int i = 0; i < hopperCache.cachedInventory.length; i++) {
|
|
final ItemStack item = hopperCache.cachedInventory[i];
|
|
|
|
// Can we check this item?
|
|
if ( // Ignore this one if the slot is empty
|
|
item == null
|
|
// Don't try to move items that we've added this round
|
|
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
|
|
// skip if blocked or voidlisted
|
|
|| blockedMaterials.contains(item.getType())
|
|
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
|
|
continue;
|
|
}
|
|
|
|
doProcess = true;
|
|
break;
|
|
}
|
|
if (!doProcess) {
|
|
continue;
|
|
}
|
|
|
|
CustomContainer container = this.plugin.getContainerManager().getCustomContainer(pointingLocation.getBlock());
|
|
if (container != null) {
|
|
for (int i = 0; i < 5; i++) {
|
|
final ItemStack item = hopperCache.cachedInventory[i];
|
|
if (item == null) {
|
|
continue;
|
|
}
|
|
|
|
if (container.addToContainer(item)) {
|
|
if (item.getAmount() == 1) {
|
|
hopperCache.removeItem(i);
|
|
} else {
|
|
item.setAmount(item.getAmount() - 1);
|
|
hopperCache.dirty = hopperCache.cacheChanged[i] = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Move items into destination containers
|
|
pushItemsIntoContainers(hopper, hopperCache, maxToMove, blockedMaterials, hopperDirection);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
// push out inventory changes
|
|
StorageContainerCache.update();
|
|
}
|
|
|
|
private void debt(ItemStack item, int amountToMove, InventoryHolder currentHolder) {
|
|
if (item.getAmount() - amountToMove > 0) {
|
|
item.setAmount(item.getAmount() - amountToMove);
|
|
} else {
|
|
currentHolder.getInventory().removeItem(item);
|
|
}
|
|
}
|
|
|
|
private StorageContainerCache.Cache getFilterEndpoint(com.songoda.epichoppers.hopper.Hopper hopper) {
|
|
// Get endpoint location.
|
|
Location endPoint = hopper.getFilter().getEndPoint();
|
|
|
|
// Check for null.
|
|
if (endPoint == null) {
|
|
return null;
|
|
}
|
|
|
|
// Make sure chunk is loaded.
|
|
if (!endPoint.getWorld().isChunkLoaded(endPoint.getBlockX() >> 4, endPoint.getBlockZ() >> 4)) {
|
|
return null;
|
|
}
|
|
|
|
// Fetch Cache
|
|
StorageContainerCache.Cache cache = StorageContainerCache.getCachedInventory(endPoint.getBlock());
|
|
|
|
// Remove if not a container.
|
|
if (cache == null) {
|
|
hopper.getFilter().setEndPoint(null);
|
|
return null;
|
|
}
|
|
|
|
return cache;
|
|
}
|
|
|
|
private void pullItemsFromContainers(com.songoda.epichoppers.hopper.Hopper toHopper, StorageContainerCache.Cache hopperCache, int maxToMove) {
|
|
// Grab items from the container above (includes storage/hopper minecarts, EpicFarming farm items and AdvancedChests chest)
|
|
// If the container above is a hopper, ignore it if it's pointing down
|
|
Block above = toHopper.getBlock().getRelative(BlockFace.UP);
|
|
|
|
Collection<Entity> nearbyEntities = null;
|
|
StorageContainerCache.Cache aboveCache = null;
|
|
|
|
CustomContainer container = this.plugin.getContainerManager().getCustomContainer(above);
|
|
if ((container != null)
|
|
|| (above.getType() != Material.AIR)
|
|
&& (above.getType() != Material.HOPPER || HopperDirection.getDirection(above.getState().getRawData()) != HopperDirection.DOWN)
|
|
&& (aboveCache = StorageContainerCache.getCachedInventory(above)) != null
|
|
|| !(nearbyEntities = above.getWorld().getNearbyEntities(above.getLocation().clone(), 0.5, 0.5, 0.5)).isEmpty()) {
|
|
// Get the inventory holder. Special check for EpicFarming.
|
|
// Get the slots that we can pull items from.
|
|
InventoryHolder aboveInvHolder;
|
|
final int[] pullableSlots;
|
|
final ItemStack[] contents;
|
|
if (aboveCache != null) {
|
|
pullableSlots = this.getPullableSlots(above.getType(), aboveCache.cachedInventory.length - 1);
|
|
contents = aboveCache.cachedInventory;
|
|
aboveInvHolder = null;
|
|
} else if (container != null) {
|
|
aboveInvHolder = null;
|
|
contents = container.getItems();
|
|
pullableSlots = IntStream.rangeClosed(0, contents.length - 1).toArray();
|
|
} else {
|
|
if ((aboveInvHolder = this.getRandomInventoryHolderFromEntities(nearbyEntities)) == null
|
|
|| ((Minecart) aboveInvHolder).getLocation().getBlockY() + 1 == above.getY()) {
|
|
return;
|
|
}
|
|
if (aboveInvHolder instanceof StorageMinecart) {
|
|
pullableSlots = IntStream.rangeClosed(0, 26).toArray();
|
|
} else {
|
|
pullableSlots = IntStream.rangeClosed(0, 4).toArray();
|
|
}
|
|
contents = aboveInvHolder.getInventory().getContents();
|
|
}
|
|
|
|
// Don't fill the last inventory slot on crafting hoppers (fixes crafters getting stuck)
|
|
Module crafting = toHopper.getLevel().getModule("AutoCrafting");
|
|
ItemStack toCraft = crafting instanceof ModuleAutoCrafting ? ((ModuleAutoCrafting) crafting).getAutoCrafting(toHopper) : null;
|
|
|
|
// Loop over the pullable slots and try to pull something.
|
|
for (int i : pullableSlots) {
|
|
// Get the item
|
|
final ItemStack toMove = contents[i];
|
|
|
|
// If item is invalid, try the next slot.
|
|
if (toMove == null || toMove.getAmount() == 0) {
|
|
continue;
|
|
}
|
|
|
|
// if we're not moving the item that we're trying to craft, we need to verify that we're not trying to fill the last slot
|
|
// (filling every slot leaves no room for the crafter to function)
|
|
if (toCraft != null && !Methods.isSimilarMaterial(toMove, toCraft) && !Methods.canMoveReserved(hopperCache.cachedInventory, toMove)) {
|
|
continue;
|
|
}
|
|
|
|
// respect whitelist/blacklist filters
|
|
if (toHopper.getFilter().getEndPoint() == null
|
|
&& !(toHopper.getFilter().getWhiteList().isEmpty() && toHopper.getFilter().getBlackList().isEmpty())) {
|
|
// this hopper has a filter with no rejection endpoint, so don't absorb disalowed items
|
|
// whitelist has priority
|
|
if (!toHopper.getFilter().getWhiteList().isEmpty()) {
|
|
// is this item on the whitelist?
|
|
if (toHopper.getFilter().getWhiteList().stream().noneMatch(item -> Methods.isSimilarMaterial(toMove, item))) {
|
|
// nope!
|
|
continue;
|
|
}
|
|
} else {
|
|
// check the blacklist
|
|
if (toHopper.getFilter().getBlackList().stream().anyMatch(item -> Methods.isSimilarMaterial(toMove, item))) {
|
|
// don't grab this, then
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get amount to move.
|
|
int amountToMove = Math.min(toMove.getAmount(), maxToMove);
|
|
|
|
// Create item that will be moved.
|
|
ItemStack itemToMove = toMove.clone();
|
|
itemToMove.setAmount(amountToMove);
|
|
|
|
// Add item to container and break on success.
|
|
//if (this.addItem(toHopper, aboveInvHolder, hopperState, hopperState.getBlock().getType(), toMove, itemToMove, amountToMove))
|
|
if (hopperCache.addItem(itemToMove)) {
|
|
// remove item from the container
|
|
if (aboveCache != null) {
|
|
aboveCache.removeItems(itemToMove);
|
|
} else {
|
|
if (container != null) {
|
|
container.removeFromContainer(itemToMove, amountToMove);
|
|
} else {
|
|
this.debt(itemToMove, amountToMove, aboveInvHolder);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void pushItemsIntoContainers(com.songoda.epichoppers.hopper.Hopper hopper, StorageContainerCache.Cache hopperCache, int maxToMove, Collection<Material> blockedMaterials, HopperDirection hopperDirection) {
|
|
|
|
// Filter target, if any
|
|
StorageContainerCache.Cache filterCache = getFilterEndpoint(hopper);
|
|
|
|
// Get remote linked containers.
|
|
List<Location> linkedContainers = hopper.getLinkedBlocks();
|
|
boolean checkForMinecarts = false;
|
|
|
|
// Add container that the hopper is attached to physically.
|
|
final Location pointingLocation = hopper.getLocation().add(hopperDirection.getX(), hopperDirection.getY(), hopperDirection.getZ());
|
|
if (!linkedContainers.contains(pointingLocation)
|
|
&& pointingLocation.getWorld().isChunkLoaded(pointingLocation.getBlockX() >> 4, pointingLocation.getBlockZ() >> 4)) {
|
|
switch (pointingLocation.getBlock().getType().name()) {
|
|
case "AIR":
|
|
case "RAILS":
|
|
case "RAIL":
|
|
case "POWERED_RAIL":
|
|
case "DETECTOR_RAIL":
|
|
// Add storage/hopper minecarts the hopper is pointing into if there aren't any destinations
|
|
checkForMinecarts = linkedContainers.size() < 2;
|
|
break;
|
|
default:
|
|
linkedContainers.add(pointingLocation);
|
|
}
|
|
}
|
|
|
|
// Loop through targets until we can move stuff into one of them
|
|
for (Location targetLocation : linkedContainers) {
|
|
|
|
// Don't check if it's not in a loaded chunk
|
|
if (!targetLocation.getWorld().isChunkLoaded(targetLocation.getBlockX() >> 4, targetLocation.getBlockZ() >> 4)) {
|
|
continue;
|
|
}
|
|
|
|
// special case for ender chests
|
|
final Block targetBlock = targetLocation.getBlock();
|
|
if (targetBlock.getType() == Material.ENDER_CHEST) {
|
|
// Use the ender storage of whoever owns the hopper if they're online
|
|
OfflinePlayer op = Bukkit.getOfflinePlayer(hopper.getPlacedBy());
|
|
if (op.isOnline()) {
|
|
Inventory destinationInventory = op.getPlayer().getEnderChest();
|
|
StorageContainerCache.Cache cache = new StorageContainerCache.Cache(targetBlock.getType(), destinationInventory.getContents());
|
|
if (tryPush(hopper, hopperCache, cache, filterCache, maxToMove, blockedMaterials)) {
|
|
// update inventory and exit
|
|
if (cache.isDirty()) {
|
|
destinationInventory.setContents(cache.cachedInventory);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
// Can't put anything in there, so keep looking for targets
|
|
continue;
|
|
}
|
|
|
|
CustomContainer container = this.plugin.getContainerManager().getCustomContainer(targetLocation.getBlock());
|
|
if (container != null && tryPushCustomContainer(hopper, hopperCache, container, filterCache, maxToMove, blockedMaterials)) {
|
|
return;
|
|
}
|
|
|
|
// Is this a storage container?
|
|
StorageContainerCache.Cache targetCache = StorageContainerCache.getCachedInventory(targetBlock);
|
|
if (targetCache == null) {
|
|
// if it's not, we need to unlink it
|
|
hopper.removeLinkedBlock(targetLocation);
|
|
continue;
|
|
}
|
|
|
|
// Now attempt to push items into this container and exit on success
|
|
if (tryPush(hopper, hopperCache, targetCache, filterCache, maxToMove, blockedMaterials)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// if we've gotten this far, check if we can push into a minecart
|
|
if (checkForMinecarts) {
|
|
for (InventoryHolder minecartInventory : hopper.getWorld().getNearbyEntities(pointingLocation.clone().add(0.5, 0.5, 0.5), 0.5, 0.5, 0.5)
|
|
.stream().filter(e -> e.getType() == EntityType.MINECART_CHEST || e.getType() == EntityType.MINECART_HOPPER)
|
|
.map(InventoryHolder.class::cast).collect(Collectors.toSet())) {
|
|
StorageContainerCache.Cache cache = new StorageContainerCache.Cache(Material.CHEST, minecartInventory.getInventory().getContents());
|
|
if (tryPush(hopper, hopperCache, cache, filterCache, maxToMove, blockedMaterials)) {
|
|
if (cache.isDirty()) {
|
|
minecartInventory.getInventory().setContents(cache.cachedInventory);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean tryPushCustomContainer(com.songoda.epichoppers.hopper.Hopper hopper,
|
|
StorageContainerCache.Cache hopperCache,
|
|
CustomContainer container,
|
|
StorageContainerCache.Cache filterCache,
|
|
int maxToMove, Collection<Material> blockedMaterials) {
|
|
for (int i = 0; i < 5; i++) {
|
|
// Get potential item to move.
|
|
ItemStack item = hopperCache.cachedInventory[i];
|
|
|
|
// Can we check this item?
|
|
if ( // Ignore this one if the slot is empty
|
|
item == null
|
|
// Don't try to move items that we've added this round
|
|
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
|
|
// skip if blocked or voidlisted
|
|
|| blockedMaterials.contains(item.getType())
|
|
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
|
|
continue;
|
|
}
|
|
|
|
// Create item that will be moved.
|
|
ItemStack itemToMove = item.clone();
|
|
itemToMove.setAmount(Math.min(item.getAmount(), maxToMove));
|
|
|
|
// Process whitelist and blacklist.
|
|
boolean blocked = (!hopper.getFilter().getWhiteList().isEmpty() && hopper.getFilter().getWhiteList().stream().noneMatch(itemStack -> itemStack.isSimilar(item))
|
|
|| hopper.getFilter().getBlackList().stream().anyMatch(itemStack -> itemStack.isSimilar(item)));
|
|
|
|
// If blocked check to see if a movement can be made
|
|
if (blocked) {
|
|
if (filterCache != null && filterCache.addItem(itemToMove)) {
|
|
hopperCache.removeItems(itemToMove);
|
|
return true;
|
|
}
|
|
// can't move into a filter chest, so keep looking for something else to move
|
|
continue;
|
|
}
|
|
|
|
// Add item to container and return on success.
|
|
if (container.addToContainer(itemToMove)) {
|
|
hopperCache.removeItems(itemToMove);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private boolean tryPush(com.songoda.epichoppers.hopper.Hopper hopper,
|
|
StorageContainerCache.Cache hopperCache,
|
|
StorageContainerCache.Cache targetCache,
|
|
StorageContainerCache.Cache filterCache,
|
|
int maxToMove, Collection<Material> blockedMaterials) {
|
|
|
|
// Loop through all of our hopper's item slots.
|
|
for (int i = 0; i < 5; i++) {
|
|
// Get potential item to move.
|
|
ItemStack item = hopperCache.cachedInventory[i];
|
|
|
|
// Can we check this item?
|
|
if ( // Ignore this one if the slot is empty
|
|
item == null
|
|
// Don't try to move items that we've added this round
|
|
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
|
|
// skip if blocked or voidlisted
|
|
|| blockedMaterials.contains(item.getType())
|
|
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
|
|
continue;
|
|
}
|
|
|
|
// Create item that will be moved.
|
|
ItemStack itemToMove = item.clone();
|
|
itemToMove.setAmount(Math.min(item.getAmount(), maxToMove));
|
|
|
|
// Process whitelist and blacklist.
|
|
boolean blocked = (!hopper.getFilter().getWhiteList().isEmpty() && hopper.getFilter().getWhiteList().stream().noneMatch(itemStack -> itemStack.isSimilar(item))
|
|
|| hopper.getFilter().getBlackList().stream().anyMatch(itemStack -> itemStack.isSimilar(item)));
|
|
|
|
// If blocked check to see if a movement can be made
|
|
if (blocked) {
|
|
if (filterCache != null && filterCache.addItem(itemToMove)) {
|
|
hopperCache.removeItems(itemToMove);
|
|
return true;
|
|
}
|
|
// can't move into a filter chest, so keep looking for something else to move
|
|
continue;
|
|
}
|
|
|
|
// Add item to container and return on success.
|
|
if (targetCache.addItem(itemToMove)) {
|
|
hopperCache.removeItems(itemToMove);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void processVoidFilter(com.songoda.epichoppers.hopper.Hopper hopper, StorageContainerCache.Cache hopperCache, int maxToMove) {
|
|
// Loop over hopper inventory to process void filtering.
|
|
if (!hopper.getFilter().getVoidList().isEmpty()) {
|
|
ItemStack[] hopperContents = hopperCache.cachedInventory;
|
|
for (int i = 0; i < hopperContents.length; i++) {
|
|
final ItemStack item = hopperContents[i];
|
|
if (item != null && hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
|
|
int amt = Math.max(0, item.getAmount() - maxToMove);
|
|
if (amt == 0) {
|
|
hopperCache.removeItem(i);
|
|
} else {
|
|
item.setAmount(amt);
|
|
}
|
|
hopperCache.setDirty(hopperCache.cacheChanged[i] = true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets a set of slots that can be pulled from based on the given material
|
|
*
|
|
* @param material The material to get pullable slots for
|
|
* @return A set of valid pullable slots
|
|
*/
|
|
private int[] getPullableSlots(Material material, int contentsLength) {
|
|
if (material.name().contains("SHULKER_BOX")) {
|
|
return IntStream.rangeClosed(0, 26).toArray();
|
|
}
|
|
|
|
switch (material.name()) {
|
|
case "BARREL":
|
|
case "CHEST":
|
|
case "TRAPPED_CHEST":
|
|
return IntStream.rangeClosed(0, contentsLength).toArray();
|
|
case "BREWING_STAND":
|
|
return IntStream.rangeClosed(0, 2).toArray();
|
|
case "HOPPER":
|
|
return IntStream.rangeClosed(0, 4).toArray();
|
|
case "DISPENSER":
|
|
case "DROPPER":
|
|
return IntStream.rangeClosed(0, 8).toArray();
|
|
case "SMOKER":
|
|
case "BLAST_FURNACE":
|
|
case "BURNING_FURNACE":
|
|
case "FURNACE":
|
|
return IntStream.of(2).toArray();
|
|
default:
|
|
return IntStream.empty().toArray();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets a random InventoryHolder from a collection of entities
|
|
* Only grabs InventoryHolders from StorageMinecarts and HopperMinecarts
|
|
*
|
|
* @param entities The collection of entities
|
|
* @return A random InventoryHolder if one exists, otherwise null
|
|
*/
|
|
private InventoryHolder getRandomInventoryHolderFromEntities(Collection<Entity> entities) {
|
|
List<InventoryHolder> inventoryHolders = new ArrayList<>();
|
|
entities.stream().filter(e -> e.getType() == EntityType.MINECART_CHEST || e.getType() == EntityType.MINECART_HOPPER)
|
|
.forEach(e -> inventoryHolders.add((InventoryHolder) e));
|
|
if (inventoryHolders.isEmpty()) {
|
|
return null;
|
|
}
|
|
if (inventoryHolders.size() == 1) {
|
|
return inventoryHolders.get(0);
|
|
}
|
|
return inventoryHolders.get(ThreadLocalRandom.current().nextInt(inventoryHolders.size()));
|
|
}
|
|
}
|