package blusunrize.immersiveengineering.common.blocks.wooden; import blusunrize.immersiveengineering.api.Lib; import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IGuiTile; import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.FluidTankProperties; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; import java.util.ArrayList; /** * @author BluSunrize - 02.03.2017 */ public class TileEntityFluidSorter extends TileEntityIEBase implements IGuiTile { public byte[] sortWithNBT = {1,1,1,1,1,1}; // public static final int filterSlotsPerSide = 8; public FluidStack[][] filters = new FluidStack[6][8]; public int routeFluid(EnumFacing inputSide, FluidStack stack, boolean doFill) { if(!worldObj.isRemote) { IFluidHandler[][] validOutputs = getValidOutputs(inputSide, stack, true); if(validOutputs[0].length>0) { int rand = worldObj.rand.nextInt(validOutputs[0].length); int accepted = validOutputs[0][rand].fill(stack.copy(), doFill); if(accepted>0) return accepted; } if(validOutputs[1].length>0) { int rand = worldObj.rand.nextInt(validOutputs[1].length); int accepted = validOutputs[1][rand].fill(stack.copy(), doFill); if(accepted>0) return accepted; } } return 0; } public boolean doNBT(int side) { if(side>=0 && side<this.sortWithNBT.length) return this.sortWithNBT[side]==1; return false; } @Override public boolean canOpenGui() { return true; } @Override public int getGuiID() { return Lib.GUIID_FluidSorter; } @Override public TileEntity getGuiMaster() { return this; } @Override public void receiveMessageFromClient(NBTTagCompound message) { if(message.hasKey("sideConfig")) this.sortWithNBT = message.getByteArray("sideConfig"); if(message.hasKey("filter_side")) { int side = message.getInteger("filter_side"); int slot = message.getInteger("filter_slot"); this.filters[side][slot] = FluidStack.loadFluidStackFromNBT(message.getCompoundTag("filter")); } this.markDirty(); } public IFluidHandler[][] getValidOutputs(EnumFacing inputSide, FluidStack fluidStack, boolean allowUnmapped) { if(fluidStack==null) return new IFluidHandler[2][0]; ArrayList<IFluidHandler> validFilteredInvOuts = new ArrayList<IFluidHandler>(6); ArrayList<IFluidHandler> validUnfilteredInvOuts = new ArrayList<IFluidHandler>(6); for(EnumFacing side : EnumFacing.values()) if(side!=inputSide && worldObj.isBlockLoaded(getPos().offset(side))) { boolean unmapped = true; boolean allowed = false; filterIteration: { for(FluidStack filterStack : filters[side.ordinal()]) if(filterStack!=null) { unmapped = false; boolean b = filterStack.getFluid()==fluidStack.getFluid(); if(doNBT(side.ordinal())) b &= FluidStack.areFluidStackTagsEqual(filterStack, fluidStack); if(b) { allowed=true; break filterIteration; } } } if(allowed || (allowUnmapped&&unmapped)) { TileEntity tile = worldObj.getTileEntity(getPos().offset(side)); if(tile!=null && tile.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side.getOpposite())) { IFluidHandler handler = tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side.getOpposite()); if(handler.fill(fluidStack.copy(), false) > 0) if(allowed) validFilteredInvOuts.add(handler); else validUnfilteredInvOuts.add(handler); } } } return new IFluidHandler[][]{ validFilteredInvOuts.toArray(new IFluidHandler[validFilteredInvOuts.size()]), validUnfilteredInvOuts.toArray(new IFluidHandler[validUnfilteredInvOuts.size()]), }; } @Override public void readCustomNBT(NBTTagCompound nbt, boolean descPacket) { sortWithNBT = nbt.getByteArray("sortWithNBT"); for(int side=0; side<6; side++) { NBTTagList filterList = nbt.getTagList("filter_"+side, 10); for(int i=0; i<filterList.tagCount(); i++) filters[side][i] = FluidStack.loadFluidStackFromNBT(filterList.getCompoundTagAt(i)); } } @Override public void writeCustomNBT(NBTTagCompound nbt, boolean descPacket) { nbt.setByteArray("sortWithNBT", sortWithNBT); for(int side=0; side<6; side++) { NBTTagList filterList = new NBTTagList(); for(int i=0; i<filters[side].length; i++) { NBTTagCompound tag = new NBTTagCompound(); if(filters[side][i]!=null) filters[side][i].writeToNBT(tag); filterList.appendTag(tag); } nbt.setTag("filter_"+side, filterList); } } @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { if(capability==CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) return true; return super.hasCapability(capability, facing); } IFluidHandler[] insertionHandlers = { new SorterFluidHandler(this,EnumFacing.DOWN), new SorterFluidHandler(this,EnumFacing.UP), new SorterFluidHandler(this,EnumFacing.NORTH), new SorterFluidHandler(this,EnumFacing.SOUTH), new SorterFluidHandler(this,EnumFacing.WEST), new SorterFluidHandler(this,EnumFacing.EAST)}; @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if(capability==CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY && facing!=null) return (T)insertionHandlers[facing.ordinal()]; return super.getCapability(capability, facing); } static class SorterFluidHandler implements IFluidHandler { TileEntityFluidSorter tile; EnumFacing facing; SorterFluidHandler(TileEntityFluidSorter tile, EnumFacing facing) { this.tile = tile; this.facing = facing; } @Override public int fill(FluidStack resource, boolean doFill) { if(resource == null) return 0; return tile.routeFluid(facing, resource, doFill); } @Override public FluidStack drain(FluidStack resource, boolean doDrain) { return null; } @Override public FluidStack drain(int maxDrain, boolean doDrain) { return null; } @Override public IFluidTankProperties[] getTankProperties() { return new IFluidTankProperties[]{new FluidTankProperties(null,0)}; } } }