package slimeknights.tconstruct.library.smeltery; import com.google.common.collect.Lists; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.FluidTankProperties; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; import java.util.List; import java.util.ListIterator; import javax.annotation.Nullable; import slimeknights.tconstruct.smeltery.TinkerSmeltery; public class SmelteryTank implements IFluidTank, IFluidHandler { protected final ISmelteryTankHandler parent; protected List<FluidStack> liquids; // currently contained liquids in the smeltery protected int maxCapacity; public SmelteryTank(ISmelteryTankHandler parent) { liquids = Lists.newArrayList(); maxCapacity = 0; this.parent = parent; } public void setCapacity(int maxCapacity) { this.maxCapacity = maxCapacity; } public List<FluidStack> getFluids() { return liquids; } public void setFluids(List<FluidStack> fluids) { this.liquids = fluids; parent.onTankChanged(liquids, null); } @Nullable @Override public FluidStack getFluid() { return liquids.size() > 0 ? liquids.get(0) : null; } @Override public int getFluidAmount() { int cap = 0; for(FluidStack liquid : liquids) { cap += liquid.amount; } return cap; } @Override public int getCapacity() { return maxCapacity; } @Override public FluidTankInfo getInfo() { FluidStack fluid = getFluid(); int capacity = getCapacity() - getFluidAmount(); if(fluid != null) { capacity += fluid.amount; } return new FluidTankInfo(fluid, capacity); } @Override public IFluidTankProperties[] getTankProperties() { // if the size is 0 (no fluids) simply return an empty properties // some other mods expect having at least 1 value here if(liquids.size() == 0) { return new IFluidTankProperties[]{ new FluidTankProperties(null, maxCapacity, true, true) }; } IFluidTankProperties[] properties = new IFluidTankProperties[liquids.size()]; for(int i = 0; i < liquids.size(); i++) { boolean first = i == 0; int capacity = liquids.get(i).amount; if(first) { capacity += getCapacity() - getFluidAmount(); } properties[i] = new FluidTankProperties(liquids.get(i), capacity, first, first); } return properties; } @Override public int fill(FluidStack resource, boolean doFill) { // check how much space is left in the smeltery int used = getFluidAmount(); int usable = Math.min(maxCapacity - used, resource.amount); if(!doFill) { return usable; } // check if we already have the given liquid for(FluidStack liquid : liquids) { if(liquid.isFluidEqual(resource)) { // yup. add it liquid.amount += usable; parent.onTankChanged(liquids, liquid); return usable; } } // not present yet, add it resource = resource.copy(); resource.amount = usable; liquids.add(resource); parent.onTankChanged(liquids, resource); return usable; } @Override public FluidStack drain(int maxDrain, boolean doDrain) { if(liquids.isEmpty()) { return null; } FluidStack liquid = new FluidStack(liquids.get(0), maxDrain); return drain(liquid, doDrain); } @Override public FluidStack drain(FluidStack resource, boolean doDrain) { // search for the resource ListIterator<FluidStack> iter = liquids.listIterator(); while(iter.hasNext()) { FluidStack liquid = iter.next(); if(liquid.isFluidEqual(resource)) { int drainable = Math.min(resource.amount, liquid.amount); if(doDrain) { liquid.amount -= drainable; if(liquid.amount <= 0) { iter.remove(); } parent.onTankChanged(liquids, liquid); } // return drained amount resource = resource.copy(); resource.amount = drainable; return resource; } } // nothing drained return null; } /* Saving and loading */ public void writeToNBT(NBTTagCompound tag) { NBTTagList taglist = new NBTTagList(); for(FluidStack liquid : liquids) { if(FluidRegistry.getFluidName(liquid.getFluid()) == null) { TinkerSmeltery.log.error("Error trying to save fluids inside smeltery! Invalid Liquid found! Smeltery contents:"); for(FluidStack liquid2 : liquids) { TinkerSmeltery.log.error(" " + liquid2.getUnlocalizedName() + "/" + liquid2.amount + "mb"); } continue; } NBTTagCompound fluidTag = new NBTTagCompound(); liquid.writeToNBT(fluidTag); taglist.appendTag(fluidTag); } tag.setTag("Liquids", taglist); tag.setInteger("LiquidCapacity", maxCapacity); } public void readFromNBT(NBTTagCompound tag) { NBTTagList taglist = tag.getTagList("Liquids", 10); liquids.clear(); for(int i = 0; i < taglist.tagCount(); i++) { NBTTagCompound fluidTag = taglist.getCompoundTagAt(i); FluidStack liquid = FluidStack.loadFluidStackFromNBT(fluidTag); if(liquid != null) { liquids.add(liquid); } } maxCapacity = tag.getInteger("LiquidCapacity"); } /** Moves the fluid with the passed index to the beginning/bottom of the fluid tank stack */ public void moveFluidToBottom(int index) { if(index < liquids.size()) { FluidStack fluid = liquids.get(index); liquids.remove(index); liquids.add(0, fluid); } } }