diff --git a/README.MD b/README.MD index 635f9a92..c3709f96 100644 --- a/README.MD +++ b/README.MD @@ -69,6 +69,6 @@ E. Geng(@phantamanta44) and KilaBash (@Yefancy) - Their amazing origin work in 1 ## To-Do - -[ ] Port to 1.12, with supporting for PAE2 + - [ ] Port to 1.12, with supporting for PAE2 - -[ ] Port to 1.16.5 + - [ ] Port to 1.16.5 diff --git a/src/main/java/com/glodblock/github/FluidCraft.java b/src/main/java/com/glodblock/github/FluidCraft.java index 99a78e43..3f2c51af 100644 --- a/src/main/java/com/glodblock/github/FluidCraft.java +++ b/src/main/java/com/glodblock/github/FluidCraft.java @@ -1,7 +1,10 @@ package com.glodblock.github; +import appeng.api.AEApi; +import com.glodblock.github.common.storage.FluidCellHandler; import com.glodblock.github.inventory.InventoryHandler; import com.glodblock.github.loader.ChannelLoader; +import com.glodblock.github.loader.ItemAndBlockHolder; import com.glodblock.github.loader.ListenerLoader; import com.glodblock.github.loader.RenderLoader; import com.glodblock.github.nei.recipes.DefaultExtractorLoader; @@ -40,6 +43,8 @@ public class FluidCraft { (new RenderLoader()).run(); (new ListenerLoader()).run(); ModAndClassUtil.init(); + AEApi.instance().registries().cell().addCellHandler(new FluidCellHandler()); + ItemAndBlockHolder.loadSetting(); proxy.init(event); } diff --git a/src/main/java/com/glodblock/github/common/item/ItemBasicFluidStorageCell.java b/src/main/java/com/glodblock/github/common/item/ItemBasicFluidStorageCell.java new file mode 100644 index 00000000..fe745218 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/item/ItemBasicFluidStorageCell.java @@ -0,0 +1,326 @@ +package com.glodblock.github.common.item; + +import appeng.api.AEApi; +import appeng.api.config.FuzzyMode; +import appeng.api.config.IncludeExclude; +import appeng.api.exceptions.MissingDefinition; +import appeng.api.implementations.items.IUpgradeModule; +import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import appeng.core.AEConfig; +import appeng.core.features.AEFeature; +import appeng.core.localization.GuiText; +import appeng.items.AEBaseItem; +import appeng.items.contents.CellConfig; +import appeng.items.contents.CellUpgrades; +import appeng.util.InventoryAdaptor; +import appeng.util.Platform; +import com.glodblock.github.FluidCraft; +import com.glodblock.github.common.storage.CellType; +import com.glodblock.github.common.storage.IFluidCellInventory; +import com.glodblock.github.common.storage.IFluidCellInventoryHandler; +import com.glodblock.github.common.storage.IStorageFluidCell; +import com.glodblock.github.util.NameConst; +import com.google.common.base.Optional; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.event.ForgeEventFactory; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; + +public class ItemBasicFluidStorageCell extends AEBaseItem implements IStorageFluidCell +{ + private final CellType component; + private final int totalBytes; + private final int perType; + private final double idleDrain; + @SideOnly(Side.CLIENT) + private final static HashMap icon = new HashMap<>(); + + public ItemBasicFluidStorageCell( final CellType whichCell, final int kilobytes ) + { + super( Optional.of( kilobytes + "k" ) ); + setUnlocalizedName(NameConst.ITEM_FLUID_STORAGE + kilobytes); + this.setFeature( EnumSet.of( AEFeature.StorageCells ) ); + this.setMaxStackSize( 1 ); + this.totalBytes = kilobytes * 1024; + this.component = whichCell; + + switch( this.component ) + { + case Cell1kPart: + this.idleDrain = 0.5; + this.perType = 8; + break; + case Cell4kPart: + this.idleDrain = 1.0; + this.perType = 8; + break; + case Cell16kPart: + this.idleDrain = 1.5; + this.perType = 8; + break; + case Cell64kPart: + this.idleDrain = 2.0; + this.perType = 8; + break; + case Cell256kPart: + this.idleDrain = 2.5; + this.perType = 8; + break; + case Cell1024kPart: + this.idleDrain = 3.0; + this.perType = 8; + break; + case Cell4096kPart: + this.idleDrain = 3.5; + this.perType = 8; + break; + default: + this.idleDrain = 0.0; + this.perType = 8; + } + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return I18n.format("item.fluid_storage." + this.totalBytes / 1024 + ".name"); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister iconRegister) { + icon.put(this.totalBytes / 1024, iconRegister.registerIcon(NameConst.RES_KEY + NameConst.ITEM_FLUID_STORAGE + "." + this.totalBytes / 1024)); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIconFromDamage(int meta) { + int id = this.totalBytes / 1024; + return icon.get(id); + } + + @Override + public void addCheckedInformation(final ItemStack stack, final EntityPlayer player, final List lines, final boolean displayMoreInfo ) + { + final IMEInventoryHandler inventory = AEApi.instance().registries().cell().getCellInventory( stack, null, StorageChannel.FLUIDS ); + + if( inventory instanceof IFluidCellInventoryHandler) + { + final IFluidCellInventoryHandler handler = (IFluidCellInventoryHandler) inventory; + final IFluidCellInventory cellInventory = handler.getCellInv(); + + if( cellInventory != null ) + { + lines.add( cellInventory.getUsedBytes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalBytes() + ' ' + GuiText.BytesUsed.getLocal() ); + + lines.add( cellInventory.getStoredFluidTypes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalFluidTypes() + ' ' + GuiText.Types.getLocal() ); + + if( handler.isPreformatted() ) + { + final String list = (handler.getIncludeExcludeMode() == IncludeExclude.WHITELIST ? GuiText.Included : GuiText.Excluded).getLocal(); + lines.add(GuiText.Partitioned.getLocal() + " - " + list + ' ' + GuiText.Precise.getLocal()); + } + } + } + } + + @Override + public int getBytes( final ItemStack cellItem ) + { + return this.totalBytes; + } + + @Override + public int getBytesPerType( final ItemStack cellItem ) + { + return this.perType; + } + + @Override + public boolean isBlackListed(ItemStack cellItem, IAEFluidStack requestedAddition) { + return false; + } + + @Override + public int getTotalTypes( final ItemStack cellItem ) + { + return 1; + } + + @Override + public boolean storableInStorageCell() + { + return false; + } + + @Override + public boolean isStorageCell( final ItemStack i ) + { + return true; + } + + @Override + public double getIdleDrain() + { + return this.idleDrain; + } + + @Override + public boolean isEditable( final ItemStack is ) + { + return true; + } + + @Override + public IInventory getUpgradesInventory(final ItemStack is ) + { + return new CellUpgrades( is, 0 ); + } + + @Override + public IInventory getConfigInventory( final ItemStack is ) + { + return new CellConfig( is ); + } + + @Override + public FuzzyMode getFuzzyMode(final ItemStack is ) + { + final String fz = Platform.openNbtData( is ).getString( "FuzzyMode" ); + try + { + return FuzzyMode.valueOf( fz ); + } + catch( final Throwable t ) + { + return FuzzyMode.IGNORE_ALL; + } + } + + @Override + public void setFuzzyMode( final ItemStack is, final FuzzyMode fzMode ) + { + Platform.openNbtData( is ).setString( "FuzzyMode", fzMode.name() ); + } + + public String getOreFilter(ItemStack is) { + return Platform.openNbtData( is ).getString( "OreFilter" ); + } + + public void setOreFilter(ItemStack is, String filter) { + Platform.openNbtData( is ).setString("OreFilter", filter); + } + + @Override + public ItemStack onItemRightClick(final ItemStack stack, final World world, final EntityPlayer player ) + { + this.disassembleDrive( stack, world, player ); + return stack; + } + + private boolean disassembleDrive( final ItemStack stack, final World world, final EntityPlayer player ) + { + if( player.isSneaking() ) + { + if( Platform.isClient() ) + { + return false; + } + final InventoryPlayer playerInventory = player.inventory; + final IMEInventoryHandler inv = AEApi.instance().registries().cell().getCellInventory( stack, null, StorageChannel.FLUIDS ); + if( inv != null && playerInventory.getCurrentItem() == stack ) + { + final InventoryAdaptor ia = InventoryAdaptor.getAdaptor( player, ForgeDirection.UNKNOWN ); + final IItemList list = inv.getAvailableItems( StorageChannel.FLUIDS.createList() ); + if( list.isEmpty() && ia != null ) + { + playerInventory.setInventorySlotContents( playerInventory.currentItem, null ); + + // drop core + final ItemStack extraB = ia.addItems( this.component.stack( 1 ) ); + if( extraB != null ) + { + player.dropPlayerItemWithRandomChoice( extraB, false ); + } + + // drop upgrades + final IInventory upgradesInventory = this.getUpgradesInventory( stack ); + for( int upgradeIndex = 0; upgradeIndex < upgradesInventory.getSizeInventory(); upgradeIndex++ ) + { + final ItemStack upgradeStack = upgradesInventory.getStackInSlot( upgradeIndex ); + final ItemStack leftStack = ia.addItems( upgradeStack ); + if( leftStack != null && upgradeStack.getItem() instanceof IUpgradeModule) + { + player.dropPlayerItemWithRandomChoice( upgradeStack, false ); + } + } + + // drop empty storage cell case + for( final ItemStack storageCellStack : AEApi.instance().definitions().materials().emptyStorageCell().maybeStack( 1 ).asSet() ) + { + final ItemStack extraA = ia.addItems( storageCellStack ); + if( extraA != null ) + { + player.dropPlayerItemWithRandomChoice( extraA, false ); + } + } + + if( player.inventoryContainer != null ) + { + player.inventoryContainer.detectAndSendChanges(); + } + + return true; + } + } + } + return false; + } + + @Override + public boolean onItemUseFirst( final ItemStack stack, final EntityPlayer player, final World world, final int x, final int y, final int z, final int side, final float hitX, final float hitY, final float hitZ ) + { + if( ForgeEventFactory.onItemUseStart( player, stack, 1 ) <= 0 ) + return true; + + return this.disassembleDrive( stack, world, player ); + } + + @Override + public ItemStack getContainerItem( final ItemStack itemStack ) + { + for( final ItemStack stack : AEApi.instance().definitions().materials().emptyStorageCell().maybeStack( 1 ).asSet() ) + { + return stack; + } + + throw new MissingDefinition( "Tried to use empty storage cells while basic storage cells are defined." ); + } + + @Override + public boolean hasContainerItem( final ItemStack stack ) + { + return AEConfig.instance.isFeatureEnabled( AEFeature.EnableDisassemblyCrafting ); + } + + public ItemBasicFluidStorageCell register() { + GameRegistry.registerItem(this, NameConst.ITEM_FLUID_STORAGE + this.totalBytes / 1024 , FluidCraft.MODID); + return this; + } + +} diff --git a/src/main/java/com/glodblock/github/common/item/ItemBasicFluidStoragePart.java b/src/main/java/com/glodblock/github/common/item/ItemBasicFluidStoragePart.java new file mode 100644 index 00000000..097ebe53 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/item/ItemBasicFluidStoragePart.java @@ -0,0 +1,64 @@ +package com.glodblock.github.common.item; + +import com.glodblock.github.FluidCraft; +import com.glodblock.github.util.NameConst; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +import java.util.HashMap; +import java.util.List; + +public class ItemBasicFluidStoragePart extends Item { + + public static final int types = 7; + @SideOnly(Side.CLIENT) + private final static HashMap icon = new HashMap<>(); + + public ItemBasicFluidStoragePart() { + super(); + setHasSubtypes(true); + setUnlocalizedName(NameConst.ITEM_FLUID_PART); + } + + @Override + @SideOnly(Side.CLIENT) + @SuppressWarnings("unchecked") + public void getSubItems(Item item, CreativeTabs tab, List list) { + for (int i = 0; i < types; ++i) { + list.add(new ItemStack(item, 1, i)); + } + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + int meta = stack.getItemDamage(); + return I18n.format("item.fluid_part." + meta + ".name"); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister iconRegister) { + for (int i = 0; i < types; i ++) { + icon.put(i, iconRegister.registerIcon(NameConst.RES_KEY + NameConst.ITEM_FLUID_PART + "." + i)); + } + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIconFromDamage(int meta) { + return icon.get(meta); + } + + public ItemBasicFluidStoragePart register() { + GameRegistry.registerItem(this, NameConst.ITEM_FLUID_PART, FluidCraft.MODID); + return this; + } + +} diff --git a/src/main/java/com/glodblock/github/common/storage/CellType.java b/src/main/java/com/glodblock/github/common/storage/CellType.java new file mode 100644 index 00000000..7ca28158 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/storage/CellType.java @@ -0,0 +1,59 @@ +package com.glodblock.github.common.storage; + +import appeng.core.features.AEFeature; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import java.util.EnumSet; + +public enum CellType { + + Cell1kPart( 0, AEFeature.StorageCells ), + Cell4kPart( 1, AEFeature.StorageCells ), + Cell16kPart( 2, AEFeature.StorageCells ), + Cell64kPart( 3, AEFeature.StorageCells ), + Cell256kPart( 4, AEFeature.StorageCells ), + Cell1024kPart( 5, AEFeature.StorageCells ), + Cell4096kPart( 6, AEFeature.StorageCells ); + + private final EnumSet features; + private int damageValue; + private Item itemInstance; + + CellType( final int metaValue, final AEFeature part ) + { + this.setDamageValue( metaValue ); + this.features = EnumSet.of( part ); + } + + void setDamageValue( final int damageValue ) + { + this.damageValue = damageValue; + } + + public int getDamageValue() + { + return this.damageValue; + } + + EnumSet getFeature() + { + return this.features; + } + + public ItemStack stack(final int size ) + { + return new ItemStack( this.getItemInstance(), size, this.getDamageValue() ); + } + + public Item getItemInstance() + { + return this.itemInstance; + } + + public void setItemInstance( final Item itemInstance ) + { + this.itemInstance = itemInstance; + } + +} diff --git a/src/main/java/com/glodblock/github/common/storage/FluidCellHandler.java b/src/main/java/com/glodblock/github/common/storage/FluidCellHandler.java new file mode 100644 index 00000000..240cdeb6 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/storage/FluidCellHandler.java @@ -0,0 +1,69 @@ +package com.glodblock.github.common.storage; + +import appeng.api.implementations.tiles.IChestOrDrive; +import appeng.api.storage.*; +import appeng.client.texture.ExtraBlockTextures; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; + +public class FluidCellHandler implements ICellHandler +{ + + @Override + public boolean isCell( final ItemStack is ) + { + return FluidCellInventory.isCell( is ); + } + + @Override + public IMEInventoryHandler getCellInventory(final ItemStack is, final ISaveProvider container, final StorageChannel channel ) + { + if( channel == StorageChannel.FLUIDS ) + { + return FluidCellInventory.getCell( is, container ); + } + return null; + } + + @Override + public IIcon getTopTexture_Light() + { + return ExtraBlockTextures.BlockMEChestItems_Light.getIcon(); + } + + @Override + public IIcon getTopTexture_Medium() + { + return ExtraBlockTextures.BlockMEChestItems_Medium.getIcon(); + } + + @Override + public IIcon getTopTexture_Dark() + { + return ExtraBlockTextures.BlockMEChestItems_Dark.getIcon(); + } + + @Override + public void openChestGui(final EntityPlayer player, final IChestOrDrive chest, final ICellHandler cellHandler, final IMEInventoryHandler inv, final ItemStack is, final StorageChannel chan ) + { + } + + @Override + public int getStatusForCell( final ItemStack is, final IMEInventory handler ) + { + if( handler instanceof FluidCellInventoryHandler) + { + final FluidCellInventoryHandler ci = (FluidCellInventoryHandler) handler; + return ci.getStatusForCell(); + } + return 0; + } + + @Override + public double cellIdleDrain( final ItemStack is, final IMEInventory handler ) + { + final IFluidCellInventory inv = ( (IFluidCellInventoryHandler) handler ).getCellInv(); + return inv.getIdleDrain(); + } +} diff --git a/src/main/java/com/glodblock/github/common/storage/FluidCellInventory.java b/src/main/java/com/glodblock/github/common/storage/FluidCellInventory.java new file mode 100644 index 00000000..357a40cc --- /dev/null +++ b/src/main/java/com/glodblock/github/common/storage/FluidCellInventory.java @@ -0,0 +1,486 @@ +package com.glodblock.github.common.storage; + +import appeng.api.AEApi; +import appeng.api.config.Actionable; +import appeng.api.exceptions.AppEngException; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.ISaveProvider; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import appeng.util.Platform; +import appeng.util.item.AEFluidStack; +import com.glodblock.github.util.Util; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; + +public class FluidCellInventory implements IFluidCellInventory { + + private static final String FLUID_TYPE_TAG = "ft"; + private static final String FLUID_COUNT_TAG = "fc"; + private static final String FLUID_SLOT = "#"; + private static final String FLUID_SLOT_COUNT = "@"; + private IStorageFluidCell cellType; + private static String[] fluidSlots; + private static String[] fluidSlotCount; + private final ItemStack cellItem; + private final ISaveProvider container; + private final static int MAX_TYPE = 1; + private int storedFluidCount; + private short storedFluids; + private IItemList cellItems; + private final NBTTagCompound tagCompound; + + public FluidCellInventory( final ItemStack o, final ISaveProvider container ) throws AppEngException { + + if( fluidSlots == null ) + { + fluidSlots = new String[MAX_TYPE]; + fluidSlotCount = new String[MAX_TYPE]; + + for( int x = 0; x < MAX_TYPE; x++ ) + { + fluidSlots[x] = FLUID_SLOT + x; + fluidSlotCount[x] = FLUID_SLOT_COUNT + x; + } + } + + if( o == null ) + { + throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" ); + } + + this.cellType = null; + this.cellItem = o; + + final Item type = this.cellItem.getItem(); + + if( type instanceof IStorageFluidCell) + { + this.cellType = (IStorageFluidCell) this.cellItem.getItem(); + } + + if( this.cellType == null ) + { + throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" ); + } + + if( !this.cellType.isStorageCell( this.cellItem ) ) + { + throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" ); + } + + this.container = container; + this.tagCompound = Platform.openNbtData( o ); + this.storedFluids = this.tagCompound.getShort( FLUID_TYPE_TAG ); + this.storedFluidCount = this.tagCompound.getInteger( FLUID_COUNT_TAG ); + this.cellItems = null; + } + + public static IMEInventoryHandler getCell(final ItemStack o, final ISaveProvider container2 ) + { + try + { + return new FluidCellInventoryHandler( new FluidCellInventory( o, container2 ) ); + } + catch( final AppEngException e ) + { + return null; + } + } + + public static boolean isCell( final ItemStack itemStack ) + { + if( itemStack == null ) + { + return false; + } + + final Item type = itemStack.getItem(); + + if( type instanceof IStorageFluidCell) + { + return ( (IStorageFluidCell) type ).isStorageCell( itemStack ); + } + + return false; + } + + @Override + public ItemStack getItemStack() { + return this.cellItem; + } + + @Override + public double getIdleDrain() { + return this.cellType.getIdleDrain(); + } + + @Override + public IInventory getConfigInventory() { + return this.cellType.getConfigInventory( this.cellItem ); + } + + @Override + public int getBytesPerType() { + return this.cellType.getBytesPerType( this.cellItem ); + } + + @Override + public boolean canHoldNewFluid() { + final long bytesFree = this.getFreeBytes(); + + return ( bytesFree > this.getBytesPerType() || ( bytesFree == this.getBytesPerType() && this.getUnusedFluidCount() > 0 ) ) && this.getRemainingFluidTypes() > 0; + } + + @Override + public long getTotalBytes() { + return this.cellType.getBytes( this.cellItem ); + } + + @Override + public long getFreeBytes() { + return this.getTotalBytes() - this.getUsedBytes(); + } + + @Override + public long getUsedBytes() { + final long bytesForItemCount = ( this.getStoredFluidCount() + this.getUnusedFluidCount() ) / 8 / 256; + return this.getStoredFluidTypes() * this.getBytesPerType() + bytesForItemCount; + } + + @Override + public long getTotalFluidTypes() { + return MAX_TYPE; + } + + @Override + public long getStoredFluidCount() { + return this.storedFluidCount; + } + + @Override + public long getStoredFluidTypes() { + return this.storedFluids; + } + + public long getRemainingFluidTypes() { + final long basedOnStorage = this.getFreeBytes() / this.getBytesPerType(); + final long baseOnTotal = this.getTotalFluidTypes() - this.getStoredFluidTypes(); + + return Math.min(basedOnStorage, baseOnTotal); + } + + @Override + public long getRemainingFluidCount() { + final long remaining = this.getFreeBytes() * 8 + this.getUnusedFluidCount(); + + return remaining > 0 ? remaining : 0; + } + + @Override + public int getUnusedFluidCount() { + final int div = (int) ( this.getStoredFluidCount() % 8 ); + + if( div == 0 ) + { + return 0; + } + + return 8 - div; + } + + @Override + public int getStatusForCell() { + if( this.canHoldNewFluid() ) + { + return 1; + } + if( this.getRemainingFluidCount() > 0 ) + { + return 2; + } + return 3; + } + + private void loadCellItems() + { + if( this.cellItems == null ) + { + this.cellItems = AEApi.instance().storage().createFluidList(); + } + + this.cellItems.resetStatus(); // clears totals and stuff. + + final int types = (int) this.getStoredFluidTypes(); + + for( int x = 0; x < types; x++ ) + { + final FluidStack t = FluidStack.loadFluidStackFromNBT( this.tagCompound.getCompoundTag( fluidSlots[x] ) ); + + if( t != null ) + { + t.amount = this.tagCompound.getInteger( fluidSlotCount[x] ); + + if( t.amount > 0 ) + { + this.cellItems.add( AEFluidStack.create( t ) ); + } + } + } + } + + private IItemList getCellItems() + { + if( this.cellItems == null ) + { + this.loadCellItems(); + } + + return this.cellItems; + } + + private void updateFluidCount( final long delta ) + { + this.storedFluidCount += delta; + this.tagCompound.setInteger( FLUID_COUNT_TAG, this.storedFluidCount ); + } + + private void saveChanges() + { + int itemCount = 0; + + int x = 0; + + for( final IAEFluidStack v : this.cellItems ) + { + itemCount += v.getStackSize(); + + final NBTBase c = this.tagCompound.getTag( fluidSlots[x] ); + + if( c instanceof NBTTagCompound ) + { + v.writeToNBT( (NBTTagCompound) c ); + } + else + { + final NBTTagCompound g = new NBTTagCompound(); + v.writeToNBT( g ); + this.tagCompound.setTag( fluidSlots[x], g ); + } + + /* + * NBTBase tagSlotCount = tagCompound.getTag( itemSlotCount[x] ); if ( tagSlotCount instanceof + * NBTTagInt ) ((NBTTagInt) tagSlotCount).data = (int) v.getStackSize(); else + */ + this.tagCompound.setInteger( fluidSlotCount[x], (int) v.getStackSize() ); + + x++; + } + + // NBTBase tagType = tagCompound.getTag( ITEM_TYPE_TAG ); + // NBTBase tagCount = tagCompound.getTag( ITEM_COUNT_TAG ); + final short oldStoredItems = this.storedFluids; + + /* + * if ( tagType instanceof NBTTagShort ) ((NBTTagShort) tagType).data = storedItems = (short) cellItems.size(); + * else + */ + this.storedFluids = (short) this.cellItems.size(); + + if( this.cellItems.isEmpty() ) + { + this.tagCompound.removeTag( FLUID_TYPE_TAG ); + } + else + { + this.tagCompound.setShort( FLUID_TYPE_TAG, this.storedFluids ); + } + + /* + * if ( tagCount instanceof NBTTagInt ) ((NBTTagInt) tagCount).data = storedItemCount = itemCount; else + */ + this.storedFluidCount = itemCount; + + if( itemCount == 0 ) + { + this.tagCompound.removeTag( FLUID_COUNT_TAG ); + } + else + { + this.tagCompound.setInteger( FLUID_COUNT_TAG, itemCount ); + } + + // clean any old crusty stuff... + for( ; x < oldStoredItems && x < MAX_TYPE; x++ ) + { + this.tagCompound.removeTag( fluidSlots[x] ); + this.tagCompound.removeTag( fluidSlotCount[x] ); + } + + if( this.container != null ) + { + this.container.saveChanges( this ); + } + } + + @Override + public IAEFluidStack injectItems(IAEFluidStack input, Actionable mode, BaseActionSource src) { + if( input == null ) + { + return null; + } + + if( input.getStackSize() == 0 ) + { + return null; + } + + if(this.cellType.isBlackListed( this.cellItem, input )) + { + return input; + } + + final FluidStack sharedFluidStack = input.getFluidStack(); + + final IAEFluidStack l = this.getCellItems().findPrecise( input ); + + if( l != null ) + { + final long remainingItemSlots = this.getRemainingFluidCount(); + + if( remainingItemSlots < 0 ) + { + return input; + } + + if( input.getStackSize() > remainingItemSlots ) + { + final IAEFluidStack r = input.copy(); + r.setStackSize( r.getStackSize() - remainingItemSlots ); + + if( mode == Actionable.MODULATE ) + { + l.setStackSize( l.getStackSize() + remainingItemSlots ); + this.updateFluidCount( remainingItemSlots ); + this.saveChanges(); + } + + return r; + } + else + { + if( mode == Actionable.MODULATE ) + { + l.setStackSize( l.getStackSize() + input.getStackSize() ); + this.updateFluidCount( input.getStackSize() ); + this.saveChanges(); + } + + return null; + } + } + + if( this.canHoldNewFluid() ) // room for new type, and for at least one item! + { + final int remainingItemCount = (int) this.getRemainingFluidCount() - this.getBytesPerType() * 8; + + if( remainingItemCount > 0 ) + { + if( input.getStackSize() > remainingItemCount ) + { + final FluidStack toReturn = Util.cloneFluidStack(sharedFluidStack); + toReturn.amount = sharedFluidStack.amount - remainingItemCount; + + if( mode == Actionable.MODULATE ) + { + final FluidStack toWrite = Util.cloneFluidStack( sharedFluidStack ); + toWrite.amount = remainingItemCount; + + this.cellItems.add( AEFluidStack.create( toWrite ) ); + this.updateFluidCount( toWrite.amount ); + + this.saveChanges(); + } + + return AEFluidStack.create( toReturn ); + } + + if( mode == Actionable.MODULATE ) + { + this.updateFluidCount( input.getStackSize() ); + this.cellItems.add( input ); + this.saveChanges(); + } + + return null; + } + } + + return input; + } + + @Override + public IAEFluidStack extractItems(IAEFluidStack request, Actionable mode, BaseActionSource src) { + if( request == null ) + { + return null; + } + + final long size = Math.min( Integer.MAX_VALUE, request.getStackSize() ); + + IAEFluidStack results = null; + + final IAEFluidStack l = this.getCellItems().findPrecise( request ); + + if( l != null ) + { + results = l.copy(); + + if( l.getStackSize() <= size ) + { + results.setStackSize( l.getStackSize() ); + + if( mode == Actionable.MODULATE ) + { + this.updateFluidCount( -l.getStackSize() ); + l.setStackSize( 0 ); + this.saveChanges(); + } + } + else + { + results.setStackSize( size ); + + if( mode == Actionable.MODULATE ) + { + l.setStackSize( l.getStackSize() - size ); + this.updateFluidCount( -size ); + this.saveChanges(); + } + } + } + + return results; + } + + @Override + public IItemList getAvailableItems(IItemList out) { + for( final IAEFluidStack i : this.getCellItems() ) + { + out.add( i ); + } + + return out; + } + + @Override + public StorageChannel getChannel() { + return StorageChannel.FLUIDS; + } +} diff --git a/src/main/java/com/glodblock/github/common/storage/FluidCellInventoryHandler.java b/src/main/java/com/glodblock/github/common/storage/FluidCellInventoryHandler.java new file mode 100644 index 00000000..c1aede92 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/storage/FluidCellInventoryHandler.java @@ -0,0 +1,80 @@ +package com.glodblock.github.common.storage; + +import appeng.api.AEApi; +import appeng.api.config.IncludeExclude; +import appeng.api.storage.IMEInventory; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import appeng.me.storage.MEInventoryHandler; +import appeng.me.storage.MEPassThrough; +import appeng.util.item.AEFluidStack; +import appeng.util.prioitylist.PrecisePriorityList; +import com.glodblock.github.util.Ae2Reflect; +import com.glodblock.github.util.Util; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public class FluidCellInventoryHandler extends MEInventoryHandler implements IFluidCellInventoryHandler { + + FluidCellInventoryHandler( final IMEInventory c ) + { + super( c, StorageChannel.FLUIDS ); + + final IFluidCellInventory ci = this.getCellInv(); + + if( ci != null ) + { + final IInventory config = ci.getConfigInventory(); + + final IItemList priorityList = AEApi.instance().storage().createFluidList(); + for (int x = 0; x < config.getSizeInventory(); x++) { + final ItemStack is = config.getStackInSlot(x); + if (is != null && Util.getFluidFromItem(is) != null) { + priorityList.add(AEFluidStack.create(Util.getFluidFromItem(is))); + break; + } + } + if (!priorityList.isEmpty()) { + this.setPartitionList(new PrecisePriorityList<>(priorityList)); + } + } + } + + @Override + public IFluidCellInventory getCellInv() + { + Object o = this.getInternal(); + + if( o instanceof MEPassThrough) + { + o = Ae2Reflect.getInternal( (MEPassThrough) o ); + } + + return (IFluidCellInventory) ( o instanceof IFluidCellInventory ? o : null ); + } + + @Override + public boolean isPreformatted() + { + return !Ae2Reflect.getPartitionList(this).isEmpty(); + } + + @Override + public IncludeExclude getIncludeExcludeMode() + { + return IncludeExclude.WHITELIST; + } + + public int getStatusForCell() + { + int val = this.getCellInv().getStatusForCell(); + + if( val == 1 && this.isPreformatted() ) + { + val = 2; + } + + return val; + } +} diff --git a/src/main/java/com/glodblock/github/common/storage/IFluidCellInventory.java b/src/main/java/com/glodblock/github/common/storage/IFluidCellInventory.java new file mode 100644 index 00000000..288504ef --- /dev/null +++ b/src/main/java/com/glodblock/github/common/storage/IFluidCellInventory.java @@ -0,0 +1,74 @@ +package com.glodblock.github.common.storage; + +import appeng.api.storage.IMEInventory; +import appeng.api.storage.data.IAEFluidStack; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public interface IFluidCellInventory extends IMEInventory +{ + + /** + * @return the item stack of this storage cell. + */ + ItemStack getItemStack(); + + /** + * @return idle cost for this Storage Cell + */ + double getIdleDrain(); + + /** + * @return access configured list + */ + IInventory getConfigInventory(); + + /** + * @return How many bytes are used for each type? + */ + int getBytesPerType(); + + /** + * @return true if a new item type can be added. + */ + boolean canHoldNewFluid(); + + /** + * @return total byte storage. + */ + long getTotalBytes(); + + /** + * @return how many bytes are free. + */ + long getFreeBytes(); + + /** + * @return how many bytes are in use. + */ + long getUsedBytes(); + + /** + * @return how many items are stored. + */ + long getStoredFluidCount(); + + /** + * @return how many more items can be stored. + */ + long getRemainingFluidCount(); + + /** + * @return how many items can be added without consuming another byte. + */ + int getUnusedFluidCount(); + + /** + * @return the status number for this drive. + */ + int getStatusForCell(); + + long getStoredFluidTypes(); + + long getTotalFluidTypes(); +} diff --git a/src/main/java/com/glodblock/github/common/storage/IFluidCellInventoryHandler.java b/src/main/java/com/glodblock/github/common/storage/IFluidCellInventoryHandler.java new file mode 100644 index 00000000..aedfb3e3 --- /dev/null +++ b/src/main/java/com/glodblock/github/common/storage/IFluidCellInventoryHandler.java @@ -0,0 +1,13 @@ +package com.glodblock.github.common.storage; + +import appeng.api.config.IncludeExclude; + +public interface IFluidCellInventoryHandler { + + IFluidCellInventory getCellInv(); + + boolean isPreformatted(); + + IncludeExclude getIncludeExcludeMode(); + +} diff --git a/src/main/java/com/glodblock/github/common/storage/IStorageFluidCell.java b/src/main/java/com/glodblock/github/common/storage/IStorageFluidCell.java new file mode 100644 index 00000000..314b1c3b --- /dev/null +++ b/src/main/java/com/glodblock/github/common/storage/IStorageFluidCell.java @@ -0,0 +1,23 @@ +package com.glodblock.github.common.storage; + +import appeng.api.storage.ICellWorkbenchItem; +import appeng.api.storage.data.IAEFluidStack; +import net.minecraft.item.ItemStack; + +public interface IStorageFluidCell extends ICellWorkbenchItem { + + int getBytes( ItemStack cellItem ); + + int getBytesPerType( ItemStack cellItem ); + + boolean isBlackListed( ItemStack cellItem, IAEFluidStack requestedAddition ); + + boolean storableInStorageCell(); + + boolean isStorageCell( ItemStack i ); + + double getIdleDrain(); + + int getTotalTypes( ItemStack cellItem ); + +} diff --git a/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java b/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java index 67d1d1ba..2b7dcffe 100644 --- a/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java +++ b/src/main/java/com/glodblock/github/loader/ItemAndBlockHolder.java @@ -4,10 +4,8 @@ import com.glodblock.github.common.block.BlockFluidDiscretizer; import com.glodblock.github.common.block.BlockFluidInterface; import com.glodblock.github.common.block.BlockFluidPacketDecoder; import com.glodblock.github.common.block.BlockFluidPatternEncoder; -import com.glodblock.github.common.item.ItemFluidDrop; -import com.glodblock.github.common.item.ItemFluidEncodedPattern; -import com.glodblock.github.common.item.ItemFluidPacket; -import com.glodblock.github.common.item.ItemPartFluidPatternTerminal; +import com.glodblock.github.common.item.*; +import com.glodblock.github.common.storage.CellType; public class ItemAndBlockHolder { @@ -15,10 +13,28 @@ public class ItemAndBlockHolder { public static ItemFluidEncodedPattern PATTERN = new ItemFluidEncodedPattern().register(); public static ItemPartFluidPatternTerminal FLUID_TERMINAL = new ItemPartFluidPatternTerminal().register(); public static ItemFluidPacket PACKET = new ItemFluidPacket().register(); + public static ItemBasicFluidStorageCell CELL1K = new ItemBasicFluidStorageCell(CellType.Cell1kPart, 1).register(); + public static ItemBasicFluidStorageCell CELL4K = new ItemBasicFluidStorageCell(CellType.Cell4kPart, 4).register(); + public static ItemBasicFluidStorageCell CELL16K = new ItemBasicFluidStorageCell(CellType.Cell16kPart, 16).register(); + public static ItemBasicFluidStorageCell CELL64K = new ItemBasicFluidStorageCell(CellType.Cell64kPart, 64).register(); + public static ItemBasicFluidStorageCell CELL256K = new ItemBasicFluidStorageCell(CellType.Cell256kPart, 256).register(); + public static ItemBasicFluidStorageCell CELL1024K = new ItemBasicFluidStorageCell(CellType.Cell1024kPart, 1024).register(); + public static ItemBasicFluidStorageCell CELL4096K = new ItemBasicFluidStorageCell(CellType.Cell4096kPart, 4096).register(); + public static ItemBasicFluidStoragePart CELL_PART = new ItemBasicFluidStoragePart().register(); public static BlockFluidDiscretizer DISCRETIZER = new BlockFluidDiscretizer().register(); public static BlockFluidPatternEncoder ENCODER = new BlockFluidPatternEncoder().register(); public static BlockFluidPacketDecoder DECODER = new BlockFluidPacketDecoder().register(); public static BlockFluidInterface INTERFACE = new BlockFluidInterface().register(); + public static void loadSetting() { + CellType.Cell1kPart.setItemInstance(CELL_PART); + CellType.Cell4kPart.setItemInstance(CELL_PART); + CellType.Cell16kPart.setItemInstance(CELL_PART); + CellType.Cell64kPart.setItemInstance(CELL_PART); + CellType.Cell256kPart.setItemInstance(CELL_PART); + CellType.Cell1024kPart.setItemInstance(CELL_PART); + CellType.Cell4096kPart.setItemInstance(CELL_PART); + } + } diff --git a/src/main/java/com/glodblock/github/util/Ae2Reflect.java b/src/main/java/com/glodblock/github/util/Ae2Reflect.java index 1f2d623c..e905f178 100644 --- a/src/main/java/com/glodblock/github/util/Ae2Reflect.java +++ b/src/main/java/com/glodblock/github/util/Ae2Reflect.java @@ -2,6 +2,7 @@ package com.glodblock.github.util; import appeng.api.implementations.IUpgradeableHost; import appeng.api.networking.crafting.ICraftingCPU; +import appeng.api.storage.IMEInventory; import appeng.client.gui.AEBaseGui; import appeng.client.gui.implementations.GuiCraftingStatus; import appeng.client.gui.widgets.GuiTabButton; @@ -9,7 +10,10 @@ import appeng.client.render.AppEngRenderItem; import appeng.container.implementations.ContainerUpgradeable; import appeng.container.implementations.CraftingCPURecord; import appeng.helpers.MultiCraftingTracker; +import appeng.me.storage.MEInventoryHandler; +import appeng.me.storage.MEPassThrough; import appeng.util.inv.ItemSlot; +import appeng.util.prioitylist.IPartitionList; import com.glodblock.github.client.gui.GuiBaseFluidPatternTerminal; import com.glodblock.github.client.gui.GuiFCBaseMonitor; import com.glodblock.github.client.gui.container.ContainerFluidPatternTerminal; @@ -31,9 +35,9 @@ public class Ae2Reflect { private static final Field fInventory_width; private static final Field fInventory_stackList; private static final Field fAEContainer_upgradeable; + private static final Field fAEPass_internal; + private static final Field fAEInv_partitionList; private static final Method mItemSlot_setExtractable; - private static final Method mTracker_isBusy; - private static final Method mTracker_cancel; static { try { @@ -41,9 +45,9 @@ public class Ae2Reflect { fInventory_width = reflectField(InventoryCrafting.class, "inventoryWidth", "field_70464_b", "b"); fInventory_stackList = reflectField(InventoryCrafting.class, "stackList", "field_70466_a", "a"); fAEContainer_upgradeable = reflectField(ContainerUpgradeable.class, "upgradeable"); + fAEPass_internal = reflectField(MEPassThrough.class, "internal"); + fAEInv_partitionList = reflectField(MEInventoryHandler.class, "myPartitionList"); mItemSlot_setExtractable = reflectMethod(ItemSlot.class, "setExtractable", boolean.class); - mTracker_isBusy = reflectMethod(MultiCraftingTracker.class, "isBusy", int.class); - mTracker_cancel = reflectMethod(MultiCraftingTracker.class, "cancel"); } catch (Exception e) { throw new IllegalStateException("Failed to initialize AE2 reflection hacks!", e); } @@ -87,20 +91,12 @@ public class Ae2Reflect { } } - public static void doCancel(MultiCraftingTracker mct) { - try { - mTracker_cancel.invoke(mct); - } catch (Exception e) { - throw new IllegalStateException("Failed to invoke method: " + mTracker_cancel, e); - } + public static IPartitionList getPartitionList(MEInventoryHandler me) { + return Ae2Reflect.readField(me, fAEInv_partitionList); } - public static boolean getBusy(MultiCraftingTracker mct, int slot) { - try { - return (boolean) mTracker_isBusy.invoke(mct, slot); - } catch (Exception e) { - throw new IllegalStateException("Failed to invoke method: " + mTracker_isBusy, e); - } + public static IMEInventory getInternal(MEPassThrough me) { + return Ae2Reflect.readField(me, fAEPass_internal); } public static IUpgradeableHost getUpgrade(ContainerUpgradeable container) { diff --git a/src/main/java/com/glodblock/github/util/NameConst.java b/src/main/java/com/glodblock/github/util/NameConst.java index ca588030..f591a9b4 100644 --- a/src/main/java/com/glodblock/github/util/NameConst.java +++ b/src/main/java/com/glodblock/github/util/NameConst.java @@ -13,6 +13,8 @@ public class NameConst { public static final String ITEM_FLUID_ENCODED_PATTERN = "fluid_encoded_pattern"; public static final String ITEM_PART_FLUID_PATTERN_TERMINAL = "part_fluid_pattern_terminal"; public static final String ITEM_FLUID_PACKET = "fluid_packet"; + public static final String ITEM_FLUID_STORAGE = "fluid_storage"; + public static final String ITEM_FLUID_PART = "fluid_part"; public static final String TT_KEY = FluidCraft.MODID + ".tooltip."; public static final String TT_INVALID_FLUID = TT_KEY + "invalid_fluid"; diff --git a/src/main/java/com/glodblock/github/util/Util.java b/src/main/java/com/glodblock/github/util/Util.java index 155f4721..61da63ea 100644 --- a/src/main/java/com/glodblock/github/util/Util.java +++ b/src/main/java/com/glodblock/github/util/Util.java @@ -99,4 +99,9 @@ public final class Util { return stack != null && stack.getItem() instanceof ItemFluidPacket; } + public static FluidStack cloneFluidStack(FluidStack fluidStack) { + if (fluidStack != null) return fluidStack.copy(); + return null; + } + } diff --git a/src/main/resources/assets/ae2fc/lang/en_US.lang b/src/main/resources/assets/ae2fc/lang/en_US.lang index dde8ce6d..17c865f8 100644 --- a/src/main/resources/assets/ae2fc/lang/en_US.lang +++ b/src/main/resources/assets/ae2fc/lang/en_US.lang @@ -2,6 +2,20 @@ item.fluid_drop.name=drop of %s item.fluid_encoded_pattern.name=Encode Pattern item.part_fluid_pattern_terminal.name=ME Fluid Pattern Terminal item.fluid_packet.name=Fluid Packet +item.fluid_storage.1.name=1k ME Fluid Storage Cell +item.fluid_storage.4.name=4k ME Fluid Storage Cell +item.fluid_storage.16.name=16k ME Fluid Storage Cell +item.fluid_storage.64.name=64k ME Fluid Storage Cell +item.fluid_storage.256.name=256k ME Fluid Storage Cell +item.fluid_storage.1024.name=1024k ME Fluid Storage Cell +item.fluid_storage.4096.name=4096k ME Fluid Storage Cell +item.fluid_part.0.name=1k ME Fluid Storage Component +item.fluid_part.1.name=4k ME Fluid Storage Component +item.fluid_part.2.name=16k ME Fluid Storage Component +item.fluid_part.3.name=64k ME Fluid Storage Component +item.fluid_part.4.name=256k ME Fluid Storage Component +item.fluid_part.5.name=1024k ME Fluid Storage Component +item.fluid_part.6.name=4096k ME Fluid Storage Component tile.fluid_discretizer.name=Fluid Discretizer tile.fluid_pattern_encoder.name=Fluid Pattern Encoder diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_part.0.png b/src/main/resources/assets/ae2fc/textures/items/fluid_part.0.png new file mode 100644 index 00000000..ad372d85 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_part.0.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_part.1.png b/src/main/resources/assets/ae2fc/textures/items/fluid_part.1.png new file mode 100644 index 00000000..5a672464 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_part.1.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_part.2.png b/src/main/resources/assets/ae2fc/textures/items/fluid_part.2.png new file mode 100644 index 00000000..2e95d8e9 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_part.2.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_part.3.png b/src/main/resources/assets/ae2fc/textures/items/fluid_part.3.png new file mode 100644 index 00000000..15b2afa2 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_part.3.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_part.4.png b/src/main/resources/assets/ae2fc/textures/items/fluid_part.4.png new file mode 100644 index 00000000..6c23f189 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_part.4.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_part.5.png b/src/main/resources/assets/ae2fc/textures/items/fluid_part.5.png new file mode 100644 index 00000000..a4603ba3 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_part.5.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_part.6.png b/src/main/resources/assets/ae2fc/textures/items/fluid_part.6.png new file mode 100644 index 00000000..f8d153d8 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_part.6.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_storage.1.png b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.1.png new file mode 100644 index 00000000..6d1e2bf1 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.1.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_storage.1024.png b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.1024.png new file mode 100644 index 00000000..dcefd928 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.1024.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_storage.16.png b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.16.png new file mode 100644 index 00000000..d77e78c0 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.16.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_storage.256.png b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.256.png new file mode 100644 index 00000000..cea76064 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.256.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_storage.4.png b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.4.png new file mode 100644 index 00000000..eab1a5ee Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.4.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_storage.4096.png b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.4096.png new file mode 100644 index 00000000..44dbdad8 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.4096.png differ diff --git a/src/main/resources/assets/ae2fc/textures/items/fluid_storage.64.png b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.64.png new file mode 100644 index 00000000..38bd62e9 Binary files /dev/null and b/src/main/resources/assets/ae2fc/textures/items/fluid_storage.64.png differ