package mekanism.common.util; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import mekanism.api.util.CapabilityUtils; import mekanism.common.capabilities.Capabilities; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; public final class PipeUtils { public static final FluidTankInfo[] EMPTY = new FluidTankInfo[] {}; public static boolean isValidAcceptorOnSide(TileEntity tile, EnumFacing side) { if(tile == null || CapabilityUtils.hasCapability(tile, Capabilities.GRID_TRANSMITTER_CAPABILITY, side.getOpposite()) || !CapabilityUtils.hasCapability(tile, CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side.getOpposite())) { return false; } IFluidHandler container = CapabilityUtils.getCapability(tile, CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side.getOpposite()); if(container == null) { return false; } IFluidTankProperties[] infoArray = container.getTankProperties(); if(infoArray != null && infoArray.length > 0) { for(IFluidTankProperties info : infoArray) { if(info != null) { return true; } } } return false; } /** * Gets all the acceptors around a tile entity. * @param tileEntity - center tile entity * @return array of IFluidHandlers */ public static IFluidHandler[] getConnectedAcceptors(TileEntity tileEntity) { return getConnectedAcceptors(tileEntity.getPos(), tileEntity.getWorld()); } public static IFluidHandler[] getConnectedAcceptors(BlockPos pos, World world) { IFluidHandler[] acceptors = new IFluidHandler[] {null, null, null, null, null, null}; for(EnumFacing orientation : EnumFacing.VALUES) { TileEntity acceptor = world.getTileEntity(pos.offset(orientation)); if(acceptor != null && CapabilityUtils.hasCapability(acceptor, CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, orientation.getOpposite())) { IFluidHandler handler = CapabilityUtils.getCapability(acceptor, CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, orientation.getOpposite()); acceptors[orientation.ordinal()] = handler; } } return acceptors; } /** * Emits fluid from a central block by splitting the received stack among the sides given. * @param sides - the list of sides to output from * @param stack - the stack to output * @param from - the TileEntity to output from * @return the amount of gas emitted */ public static int emit(List<EnumFacing> sides, FluidStack stack, TileEntity from) { if(stack == null) { return 0; } List<IFluidHandler> availableAcceptors = new ArrayList<IFluidHandler>(); IFluidHandler[] possibleAcceptors = getConnectedAcceptors(from); for(int i = 0; i < possibleAcceptors.length; i++) { IFluidHandler handler = possibleAcceptors[i]; if(handler != null && canFill(handler, stack)) { availableAcceptors.add(handler); } } Collections.shuffle(availableAcceptors); int toSend = stack.amount; int prevSending = toSend; if(!availableAcceptors.isEmpty()) { int divider = availableAcceptors.size(); int remaining = toSend % divider; int sending = (toSend-remaining)/divider; for(IFluidHandler acceptor : availableAcceptors) { int currentSending = sending; if(remaining > 0) { currentSending++; remaining--; } EnumFacing dir = EnumFacing.getFront(Arrays.asList(possibleAcceptors).indexOf(acceptor)).getOpposite(); toSend -= acceptor.fill(copy(stack, currentSending), true); } } return prevSending-toSend; } public static FluidStack copy(FluidStack fluid, int amount) { FluidStack ret = fluid.copy(); ret.amount = amount; return ret; } public static boolean canFill(IFluidHandler handler, FluidStack stack) { for(IFluidTankProperties props : handler.getTankProperties()) { if(props.canFillFluidType(stack)) { return true; } } return false; } public static boolean canDrain(IFluidHandler handler, FluidStack stack) { for(IFluidTankProperties props : handler.getTankProperties()) { if(props.canDrainFluidType(stack)) { return true; } } return false; } }