@Override public void render(TileEntityKeroseneLamp te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { FluidTank tank = te.getTank(); if (tank.getFluidAmount() == 0) return; GlStateManager.pushMatrix(); GlStateManager.translate(x, y, z); GlStateManager.enableBlend(); GlStateManager.disableAlpha(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); AxisAlignedBB bounds = getRenderBounds(tank); PneumaticCraftUtils.renderFluid(tank.getFluid().getFluid(), bounds); GlStateManager.disableBlend(); GlStateManager.enableAlpha(); GlStateManager.popMatrix(); }
@Override public void render(TileEntityLiquidHopper te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { FluidTank tank = te.getTank(); if (tank.getFluidAmount() == 0) return; GlStateManager.pushMatrix(); GlStateManager.translate(x, y, z); GlStateManager.enableBlend(); GlStateManager.disableAlpha(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); doRotate(te.getInputDirection()); AxisAlignedBB bounds = getRenderBounds(te.getInputDirection(), tank); PneumaticCraftUtils.renderFluid(tank.getFluid().getFluid(), bounds); GlStateManager.disableBlend(); GlStateManager.enableAlpha(); GlStateManager.popMatrix(); }
/** * Serialize some tank data onto an ItemStack. Useful to preserve tile entity tank data when breaking * the block. * * @param tank the fluid tank * @param stack the itemstack to save to * @param tagName name of the tag in the itemstack's NBT to store the tank data */ public static void serializeTank(FluidTank tank, ItemStack stack, String tagName) { if (tank.getFluidAmount() > 0) { if (!stack.hasTagCompound()) { stack.setTagCompound(new NBTTagCompound()); } NBTTagCompound tag = stack.getTagCompound(); if (!tag.hasKey(SAVED_TANKS, Constants.NBT.TAG_COMPOUND)) { tag.setTag(SAVED_TANKS, new NBTTagCompound()); } NBTTagCompound subTag = tag.getCompoundTag(SAVED_TANKS); NBTTagCompound tankTag = new NBTTagCompound(); tank.writeToNBT(tankTag); subTag.setTag(tagName, tankTag); } }
@Override public void writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); tag.setTag("filters", filters.serializeNBT()); NBTTagList tagList = new NBTTagList(); for (int i = 0; i < fluidFilters.length; i++) { FluidTank filter = fluidFilters[i]; if (filter.getFluid() != null) { NBTTagCompound t = new NBTTagCompound(); t.setInteger("index", i); filter.writeToNBT(t); tagList.appendTag(t); } } tag.setTag("fluidFilters", tagList); tag.setBoolean("invisible", invisible); }
@Test public void test_extractFluidsFromTanks() { FluidTank tank1 = new FluidTank(FluidRegistry.WATER, 1000, 10000); FluidTank tank2 = new FluidTank(FluidRegistry.LAVA, 1000, 10000); ItemHelper.extractFluidsFromTanks(Lists.newArrayList(tank1, tank2), Lists.newArrayList(FluidRegistry.getFluidStack("water", 400), FluidRegistry.getFluidStack("lava", 300))); assertEquals(600, tank1.getFluidAmount()); assertEquals(700, tank2.getFluidAmount()); ItemHelper.extractFluidsFromTanks(Lists.newArrayList(tank1, tank2), Lists.newArrayList(FluidRegistry.getFluidStack("lava", 400), FluidRegistry.getFluidStack("water", 300))); assertEquals(300, tank1.getFluidAmount()); assertEquals(300, tank2.getFluidAmount()); }
/** Applies the recipe to the storage provided, determining whether or not the output should be produced. Optionally * consumes the items. */ public boolean apply(FluidTank tank, IItemHandler inventory, boolean consume) { if (consume && !apply(tank, inventory, false)) return false; //Always dry-run before destructive ops if (tank.getFluid()==null) return false; //Next line shouldn't happen but it pays to plan for the impossible if (tank.getFluid().getFluid() != FluidRegistry.WATER) return false; if (tank.getFluidAmount()<water) return false; FluidStack fluidExtracted = tank.drainInternal(water, consume); if (fluidExtracted.amount<water) return false; int remaining = count; for(int i=0; i<inventory.getSlots(); i++) { ItemStack stack = inventory.getStackInSlot(i); if (stack.isEmpty()) continue; if (item.apply(stack)) { ItemStack extracted = inventory.extractItem(i, remaining, !consume); if (extracted.isEmpty()) continue; remaining -= extracted.getCount(); } } return remaining<=0; }
@Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if(!worldIn.isRemote) { TileEntity te = worldIn.getTileEntity(pos); if(te != null && te instanceof TileFluidTank) { ItemStack activeHand = playerIn.getHeldItem(hand); if(!activeHand.isEmpty() && FluidUtil.getFluidHandler(activeHand) != null) { FluidTank ft = ((TileFluidTank) te).getTank(); boolean canFillPrev = ft.canFill(); boolean canDrainPrev = ft.canDrain(); ft.setCanFill(true); ft.setCanDrain(true); try { FluidUtil.interactWithFluidHandler(playerIn, hand, ft); } finally { ft.setCanFill(canFillPrev); ft.setCanDrain(canDrainPrev); } return true; } playerIn.openGui(ModularMachinery.MODID, CommonProxy.GuiType.TANK_INVENTORY.ordinal(), worldIn, pos.getX(), pos.getY(), pos.getZ()); } } return true; }
public static FluidTank readFluidTank(ByteBuf buffer) throws IOException { int capacity = buffer.readInt(); int fluidID = buffer.readInt(); FluidTank fluidTank = new FluidTank(capacity); int amount = buffer.readInt(); if (fluidID == -1) { fluidTank.setFluid(null); } else { Fluid fluid = FluidRegistry.getFluid(fluidID); fluidTank.setFluid(new FluidStack(fluid, amount)); } return fluidTank; }
@Override public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase entity, ItemStack stack) { super.onBlockPlacedBy(world, pos, state, entity, stack); TileEntity tile = world.getTileEntity(pos); if(tile !=null && tile instanceof TileEntityTank){ TileEntityTank tank = (TileEntityTank) tile; FluidTank tankSaved = null; if(stack.hasTagCompound()){ NBTTagCompound nbt = stack.getTagCompound().copy(); tankSaved = ItemBlockTank.loadTank(nbt); } if(tankSaved !=null){ tank.tank.setFluid(tankSaved.getFluid()); BlockUtil.markBlockForUpdate(world, pos); } if(tank.creative){ BlockUtil.markBlockForUpdate(world, pos); } } }
@Override public int fill(FluidStack resource, boolean doFill) { if (ItemStackTools.getStackSize(container) != 1) { return 0; } FluidTank tank = loadTank(container); if(tank == null)return 0; boolean infi = container.getMetadata() == TankType.CREATIVE.getMeta(); if(infi){ FluidStack resourceCreative = resource.copy(); resourceCreative.amount = tank.getCapacity(); tank.fill(resourceCreative, doFill); saveTank(container, tank); return 1; } int ret = tank.fill(resource, doFill); saveTank(container, tank); return ret; }
@Override @Nullable public FluidStack drain(FluidStack resource, boolean doDrain) { if (ItemStackTools.getStackSize(container) != 1) { return null; } FluidTank tank = loadTank(container); if(tank == null)return null; boolean infi = container.getMetadata() == TankType.CREATIVE.getMeta(); if(infi){ return resource.copy(); } FluidStack ret = tank.drain(resource, doDrain); saveTank(container, tank); return ret; }
@Override @Nullable public FluidStack drain(int maxDrain, boolean doDrain) { if (ItemStackTools.getStackSize(container) != 1) { return null; } FluidTank tank = loadTank(container); if(tank == null)return null; boolean infi = container.getMetadata() == TankType.CREATIVE.getMeta(); if(infi){ if(tank.getFluid() == null)return null; FluidStack fluid = tank.getFluid().copy(); fluid.amount = maxDrain; return fluid; } FluidStack ret = tank.drain(maxDrain, doDrain); saveTank(container, tank); return ret; }
private AxisAlignedBB getRenderBounds(EnumFacing rotation, FluidTank tank) { switch (rotation) { case UP: return TankRenderHelper.getRenderBounds(tank, TANK_BOUNDS_UP); case DOWN: return TankRenderHelper.getRenderBounds(tank, TANK_BOUNDS_DOWN); default: return TankRenderHelper.getRenderBounds(tank, TANK_BOUNDS_HORIZ); } }
private static SyncedField getSyncedFieldForField(Field field, Object te) { if (int.class.isAssignableFrom(field.getType())) return new SyncedInt(te, field); if (float.class.isAssignableFrom(field.getType())) return new SyncedFloat(te, field); if (double.class.isAssignableFrom(field.getType())) return new SyncedDouble(te, field); if (boolean.class.isAssignableFrom(field.getType())) return new SyncedBoolean(te, field); if (String.class.isAssignableFrom(field.getType())) return new SyncedString(te, field); if (field.getType().isEnum()) return new SyncedEnum(te, field); if (ItemStack.class.isAssignableFrom(field.getType())) return new SyncedItemStack(te, field); if (FluidTank.class.isAssignableFrom(field.getType())) return new SyncedFluidTank(te, field); if (ItemStackHandler.class.isAssignableFrom(field.getType())) return new SyncedItemStackHandler(te, field); return null; }
@SideOnly(Side.CLIENT) @Override public void addInformation(ItemStack stack, World world, List<String> curInfo, ITooltipFlag flag) { if (stack.hasTagCompound() && stack.getTagCompound().hasKey(PneumaticCraftUtils.SAVED_TANKS, Constants.NBT.TAG_COMPOUND)) { NBTTagCompound tag = stack.getTagCompound().getCompoundTag(PneumaticCraftUtils.SAVED_TANKS); for (String s : tag.getKeySet()) { NBTTagCompound tankTag = tag.getCompoundTag(s); FluidTank tank = new FluidTank(tankTag.getInteger("Amount")); tank.readFromNBT(tankTag); FluidStack fluidStack = tank.getFluid(); if (fluidStack != null && fluidStack.amount > 0) { curInfo.add(fluidStack.getFluid().getLocalizedName(fluidStack) + ": " + fluidStack.amount + "mB"); } } } if (PneumaticCraftRepressurized.proxy.isSneakingInGui()) { TileEntity te = createTileEntity(world, getDefaultState()); if (te instanceof TileEntityPneumaticBase) { float pressure = ((TileEntityPneumaticBase) te).dangerPressure; curInfo.add(TextFormatting.YELLOW + I18n.format("gui.tooltip.maxPressure", pressure)); } } String info = "gui.tab.info." + stack.getUnlocalizedName(); String translatedInfo = I18n.format(info); if (!translatedInfo.equals(info)) { if (PneumaticCraftRepressurized.proxy.isSneakingInGui()) { translatedInfo = TextFormatting.AQUA + translatedInfo.substring(2); if (!Loader.isModLoaded(ModIds.IGWMOD)) translatedInfo += " \\n \\n" + I18n.format("gui.tab.info.assistIGW"); curInfo.addAll(PneumaticCraftUtils.convertStringIntoList(translatedInfo, 40)); } else { curInfo.add(TextFormatting.AQUA + I18n.format("gui.tooltip.sneakForInfo")); } } }
@Nonnull default ItemStack getDroppedStack(Block b) { ItemStack stack = new ItemStack(Item.getItemFromBlock(b)); for (Map.Entry<String,FluidTank> entry : getSerializableTanks().entrySet()) { PneumaticCraftUtils.serializeTank(entry.getValue(), stack, entry.getKey()); } return stack; }
@Override public void addDrops(NonNullList<ItemStack> drops) { super.addDrops(drops); boolean shouldAddTag = false; for (int i = 0; i < filters.getSlots(); i++) { if (!filters.getStackInSlot(i).isEmpty()) { //Only set a tag when there are requests. shouldAddTag = true; break; } } for (FluidTank fluidFilter : fluidFilters) { if (fluidFilter.getFluidAmount() > 0) { shouldAddTag = true; break; } } if (invisible) shouldAddTag = true; if (shouldAddTag) { ItemStack drop = drops.get(0); NBTTagCompound tag = new NBTTagCompound(); writeToNBT(tag); drop.setTagCompound(tag); } }
protected boolean passesFilter(Fluid fluid) { boolean hasFilter = false; for (FluidTank filter : fluidFilters) { if (filter.getFluidAmount() > 0) { if (filter.getFluid().getFluid() == fluid) return true; hasFilter = true; } } return !hasFilter; }
public TileEntityMixerBottomImproved() { super(); mixerOutput = new CapabilityMixerOutput(this); //north = new ResettingFluidTank(8000); //east = new ResettingFluidTank(8000); //south = new ResettingFluidTank(8000); //west = new ResettingFluidTank(8000); tanks = new FluidTank[] {north,east,south,west}; }
public void consumeFluids(ArrayList<FluidStack> fluids, FluidMixingRecipe recipe) { for (FluidTank tank : tanks) { FluidStack tankFluid = tank.getFluid(); boolean doContinue = true; for (int j = 0; j < recipe.inputs.size() && doContinue; j++) { FluidStack recipeFluid = recipe.inputs.get(j); if (recipeFluid != null && tankFluid != null && recipeFluid.getFluid() == tankFluid.getFluid()) { doContinue = false; tank.drain(recipeFluid.amount,true); } } } }
public TileActivePile(boolean coal) { invalidTicks=0; burnTime=isCoke?Config.CokeTime/10:Config.CharcoalTime/10; itemsLeft=9; isValid=false; isCoke=coal; creosote=new FluidTank(1000); }
@Nullable public static PotStillRecipe getPotStill(FluidTank tank) { for(PotStillRecipe recipe : potStill) { if (recipe.matches(tank)) return recipe; } return null; }
@Nullable public static MashTunRecipe getMashTun(FluidTank tank, IItemHandler inv) { for(MashTunRecipe recipe : mashTun) { if (recipe.matches(tank, inv)) return recipe; } return null; }
private static boolean validateFill(FluidTank tank, FluidStack stack) { if (tank instanceof ConcreteFluidTank) { return tank.canFill() && tank.canFillFluidType(stack) && ((ConcreteFluidTank)tank).getFillValidator().test(stack); } else { return tank.canFill() && tank.canFillFluidType(stack); } }
public static boolean matchesFilterBuffer(final INodeBuffer item, final ItemStack filter) { if (item == null) { return false; } final Object buffer = item.getBuffer(); if (buffer == null) { return false; } if (buffer instanceof ItemStack) { return matchesFilterItem((ItemStack)buffer, filter); } return !(buffer instanceof FluidTank) || matchesFilterLiquid(((FluidTank)buffer).getFluid(), filter); }
public TileEntityDrum() { this.tank = new FluidTank(256000); this.recentlyDrained = false; this.recentlyFilled = false; this.prevFluid = null; this.sided = false; }
public void loadTank() { final int dir = this.getBlockMetadata() % 6; if (this.worldObj.getTileEntity(this.xCoord + Facing.offsetsXForSide[dir], this.yCoord + Facing.offsetsYForSide[dir], this.zCoord + Facing.offsetsZForSide[dir]) instanceof IFluidHandler) { final IFluidHandler source = (IFluidHandler)this.worldObj.getTileEntity(this.xCoord + Facing.offsetsXForSide[dir], this.yCoord + Facing.offsetsYForSide[dir], this.zCoord + Facing.offsetsZForSide[dir]); final FluidStack liquid = source.drain(ForgeDirection.getOrientation(dir).getOpposite(), (this.upgradeNo(3) == 0) ? 200 : ((FluidTank)this.buffer.getBuffer()).getCapacity(), false); final int k = this.fill(this.getNodeDir(), liquid, false); if (k > 0) { this.fill(this.getNodeDir(), source.drain(ForgeDirection.getOrientation(dir).getOpposite(), k, true), true); } } else if (!ExtraUtils.disableInfiniteWater && this.upgradeNo(2) > 0) { if (this.worldObj.getTotalWorldTime() - this.checkTimer > 20L) { this.checkTimer = this.worldObj.getTotalWorldTime(); this.nearSource = false; if (this.isWaterSource(this.xCoord + Facing.offsetsXForSide[dir], this.yCoord + Facing.offsetsYForSide[dir], this.zCoord + Facing.offsetsZForSide[dir])) { int n = 0; for (int i = 2; i < 6; ++i) { if (this.isWaterSource(this.xCoord + Facing.offsetsXForSide[dir] + Facing.offsetsXForSide[i], this.yCoord + Facing.offsetsYForSide[dir], this.zCoord + Facing.offsetsZForSide[dir] + Facing.offsetsZForSide[i])) { ++n; } } if (n >= 2) { this.nearSource = true; } } } if (this.nearSource) { final long t = this.worldObj.getTotalWorldTime() / TileEntityTransferNode.baseMaxCoolDown * TileEntityTransferNode.baseMaxCoolDown; int a = 1000 * TileEntityTransferNode.baseMaxCoolDown / (20 * this.stepCoolDown); final float b = 1000.0f * TileEntityTransferNode.baseMaxCoolDown / (20 * this.stepCoolDown); if (a != b && b - a > this.worldObj.rand.nextFloat()) { ++a; } if (a > 0) { this.fill(this.getNodeDir(), new FluidStack(FluidRegistry.WATER, a * (1 + this.upgradeNo(2))), true); } } } }
public int fill(final ForgeDirection from, final FluidStack resource, final boolean doFill) { if (from != this.getNodeDir()) { return 0; } if (resource == null) { return 0; } for (int j = 0; j < this.upgrades.getSizeInventory(); ++j) { if (this.upgrades.getStackInSlot(j) != null && this.upgrades.getStackInSlot(j).getItemDamage() == 1 && this.upgrades.getStackInSlot(j).getTagCompound() != null && !ItemNodeUpgrade.matchesFilterLiquid(resource, this.upgrades.getStackInSlot(j))) { return 0; } } return ((FluidTank)this.buffer.getBuffer()).fill(resource, doFill); }
@Override public void readFromNBT(final NBTTagCompound tags) { if (tags.hasKey("buffer")) { this.tank.readFromNBT(tags.getCompoundTag("buffer")); } else { this.tank = new FluidTank(6400); } }
public void unloadTank() { if (this.buffer.isEmpty()) { return; } final int dir = this.getBlockMetadata() % 6; final ForgeDirection side = ForgeDirection.getOrientation(dir).getOpposite(); if (this.worldObj.getTileEntity(this.xCoord + Facing.offsetsXForSide[dir], this.yCoord + Facing.offsetsYForSide[dir], this.zCoord + Facing.offsetsZForSide[dir]) instanceof IFluidHandler) { final IFluidHandler dest = (IFluidHandler)this.worldObj.getTileEntity(this.xCoord + Facing.offsetsXForSide[dir], this.yCoord + Facing.offsetsYForSide[dir], this.zCoord + Facing.offsetsZForSide[dir]); final FluidTank tank = (FluidTank)this.buffer.getBuffer(); final int a = dest.fill(side, tank.getFluid(), this.initDirection()); if (a > 0) { dest.fill(side, tank.drain(a, true), true); } } }
public int fill(final ForgeDirection from, final FluidStack resource, final boolean doFill) { int c = 0; for (final FluidTank tank : this.getTanks()) { c += tank.fill(resource, doFill); } return c; }
public static void writeFluidTank(FluidTank fluidTank, ByteBuf buffer) throws IOException { if (fluidTank == null) { buffer.writeInt(0); buffer.writeInt(-1); buffer.writeInt(0); } else { buffer.writeInt(fluidTank.getCapacity()); buffer.writeInt(fluidTank.getFluid() == null ? -1 : FluidUtil.getFluidID(fluidTank.getFluid())); buffer.writeInt(fluidTank.getFluidAmount()); } }
/** * This tries to fill the given container (at inventory[slot]) with fluid from the specified tank * If successful, it places the resulting filled container in inventory[slot] * * Note: this deals with the issue where FluidContainerRegistry.fillFluidContainer() returns null for failed fills * * @param tank The tank to take the fluid from * @param liquid The type of liquid in that tank (the calling method will normally have checked this already) * @param inventory * @param slot * @param canisterType The type of canister to return, if it's a canister being filled (pre-matched with the liquid type) * */ public static void tryFillContainer(FluidTank tank, FluidStack liquid, ItemStack[] inventory, int slot, Item canisterType) { ItemStack slotItem = inventory[slot]; boolean isCanister = slotItem.getItem() instanceof ItemCanisterGeneric; final int amountToFill = Math.min(liquid.amount, isCanister ? slotItem.getItemDamage() - 1 : FluidContainerRegistry.BUCKET_VOLUME); if (amountToFill <= 0 || (isCanister && slotItem.getItem() != canisterType && slotItem.getItemDamage() != ItemCanisterGeneric.EMPTY)) return; if (isCanister) { inventory[slot] = new ItemStack(canisterType, 1, slotItem.getItemDamage() - amountToFill); tank.drain(amountToFill, true); } else if (amountToFill == FluidContainerRegistry.BUCKET_VOLUME) { inventory[slot] = FluidContainerRegistry.fillFluidContainer(liquid, inventory[slot]); if (inventory[slot] == null) { //Failed to fill container: restore item that was there before inventory[slot] = slotItem; } else { tank.drain(amountToFill, true); } } }
@Override public final FluidTank readFromNBT(NBTTagCompound nbt) { if (nbt.hasKey(name)) { // allow to read empty tanks setFluid(null); NBTTagCompound tankData = nbt.getCompoundTag(name); super.readFromNBT(tankData); readTankFromNBT(tankData); } return this; }
private FluidTank loadTank(ItemStack stack) { int tankType = stack.getMetadata(); tankType = MathHelper.clamp(tankType, 0, BlockTank.tankCaps.length); int cap = BlockTank.tankCaps[tankType]*Fluid.BUCKET_VOLUME; if (stack.hasTagCompound()) { FluidTank tank = loadTank(stack.getTagCompound()); if(tank !=null){ tank.setCapacity(cap); return tank; } } return new FluidTank(cap); }
public static FluidTank loadTank(NBTTagCompound nbtRoot) { int tankType = nbtRoot.hasKey("tankType") ? nbtRoot.getInteger("tankType") : 0; tankType = MathHelper.clamp(tankType, 0, BlockTank.tankCaps.length); int cap = BlockTank.tankCaps[tankType]*Fluid.BUCKET_VOLUME; FluidTank ret = new FluidTank(cap); if(nbtRoot.hasKey(FluidHandlerItemStack.FLUID_NBT_KEY)) { FluidStack fl = FluidStack.loadFluidStackFromNBT((NBTTagCompound) nbtRoot.getTag(FluidHandlerItemStack.FLUID_NBT_KEY)); ret.setFluid(fl); } else { ret.setFluid(null); } return ret; }
public TileEntityPlasticProcessor() { tankKerosene = new FluidTank(10000); tankLPG = new FluidTank(10000); tankCreosote = new FluidTank(10000); tankWater = new FluidTank(20000); handlers = new IFluidHandler[]{Helper.getFluidHandlerFromTanks(new FluidTank[]{tankKerosene, tankWater}, new Fluid[]{CoreInit.kerosene.get(), FluidRegistry.WATER}, new boolean[]{true, true}, new boolean[]{false, false}), Helper.getFluidHandlerFromTanks(new FluidTank[]{tankLPG, tankCreosote}, new Fluid[]{CoreInit.lpg.get(), CoreInit.creosoteOil.get()}, new boolean[]{true, true}, new boolean[]{false, false})}; }
public static void saveTank(NBTTagCompound nbtRoot, FluidTank tank) { if(tank.getFluidAmount() > 0) { NBTTagCompound fluidRoot = new NBTTagCompound(); tank.getFluid().writeToNBT(fluidRoot); nbtRoot.setTag(FluidHandlerItemStack.FLUID_NBT_KEY, fluidRoot); } else { nbtRoot.removeTag(FluidHandlerItemStack.FLUID_NBT_KEY); } }
@Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip, boolean advanced) { super.addInformation(stack, playerIn, tooltip, advanced); FluidTank tank = loadTank(stack); if(tank !=null){ FluidStack fluid = tank.getFluid(); if(fluid != null)tooltip.add(fluid.getLocalizedName()+" "+fluid.amount+" mB / "+tank.getCapacity()+" mB"); } }