Skip to content

Commit

Permalink
- Improved fluid container support. Bottles and other containers like…
Browse files Browse the repository at this point in the history
… IC2 cells can now be filled or emptied into the tank.

- Reduced texture z-fighting.
  • Loading branch information
zarathul committed Jul 24, 2014
1 parent dc359b6 commit 86a8c0e
Show file tree
Hide file tree
Showing 7 changed files with 369 additions and 168 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ buildscript

apply plugin: 'forge'

version = "1.7.2-1.1.1.3"
version = "1.7.2-1.1.1.4"
group= "net.zarathul.simplefluidtanks" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "simplefluidtanks"

Expand Down
167 changes: 119 additions & 48 deletions src/main/java/net/zarathul/simplefluidtanks/blocks/ValveBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
Expand All @@ -16,6 +15,7 @@
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import net.zarathul.simplefluidtanks.SimpleFluidTanks;
import net.zarathul.simplefluidtanks.common.Direction;
import net.zarathul.simplefluidtanks.common.Utils;
Expand Down Expand Up @@ -229,7 +229,7 @@ else if (valveEntity != null)
}

/**
* Handles fluid containers used on the {@link ValveBlock}. Currently only buckets (empty and filled) are supported,
* Handles fluid containers used on the {@link ValveBlock}.
*
* @param world
* The world.
Expand All @@ -250,23 +250,21 @@ private void handleContainerClick(World world, int x, int y, int z, EntityPlayer

if (valveEntity != null)
{
// only deal with buckets, all other fluid containers need to use pipes
if (FluidContainerRegistry.isBucket(equippedItemStack))
if (FluidContainerRegistry.isEmptyContainer(equippedItemStack) ||
Utils.isEmptyComplexContainer(equippedItemStack) ||
(equippedItemStack.getItem() instanceof IFluidContainerItem && player.isSneaking()))
{
if (FluidContainerRegistry.isEmptyContainer(equippedItemStack))
{
fillBucketFromTank(world, x, y, z, player, equippedItemStack, valveEntity);
}
else
{
drainBucketIntoTank(valveEntity, player, equippedItemStack);
}
fillContainerFromTank(world, x, y, z, player, equippedItemStack, valveEntity);
}
else
{
drainContainerIntoTank(world, x, y, z, player, equippedItemStack, valveEntity);
}
}
}

/**
* Fills an empty bucket with the liquid contained in the multiblock tank.
* Fills an empty container with the liquid contained in the multiblock tank.
*
* @param world
* The world.
Expand All @@ -277,64 +275,137 @@ private void handleContainerClick(World world, int x, int y, int z, EntityPlayer
* @param z
* The {@link ValveBlock}s z-coordinate.
* @param player
* The player using the bucket.
* The player holding the container.
* @param equippedItemStack
* The {@link ItemStack} that contains the bucket.
* The container {@link ItemStack}.
* @param valveEntity
* The affected {@link ValveBlock}s {@link TileEntity} ({@link ValveBlockEntity}).
*/
private void fillBucketFromTank(World world, int x, int y, int z, EntityPlayer player, ItemStack equippedItemStack, ValveBlockEntity valveEntity)
private void fillContainerFromTank(World world, int x, int y, int z, EntityPlayer player, ItemStack equippedItemStack, ValveBlockEntity valveEntity)
{
// fill empty bucket with liquid from the tank if it has stored enough
if (valveEntity.getFluidAmount() >= FluidContainerRegistry.BUCKET_VOLUME)
if (valveEntity.getFluid() == null) return;

int containerCapacity = 0;
IFluidContainerItem containerItem = null;

// determine the containers capacity
if (equippedItemStack.getItem() instanceof IFluidContainerItem)
{
FluidStack oneBucketOfFluid = new FluidStack(valveEntity.getFluid(), FluidContainerRegistry.BUCKET_VOLUME);
ItemStack filledBucket = FluidContainerRegistry.fillFluidContainer(oneBucketOfFluid, FluidContainerRegistry.EMPTY_BUCKET);
containerItem = (IFluidContainerItem) equippedItemStack.getItem();
}
else
{
containerCapacity = Utils.getFluidContainerCapacity(valveEntity.getFluid(), equippedItemStack);
}

if (filledBucket != null && valveEntity.drain(null, oneBucketOfFluid, true).amount == FluidContainerRegistry.BUCKET_VOLUME)
if (containerItem != null)
{
// handle IFluidContainerItem items

int fillFluidAmount = containerItem.fill(equippedItemStack, valveEntity.getFluid(), true);
valveEntity.drain(null, fillFluidAmount, true);
}
else if (containerCapacity > 0)
{
// handle drain/fill by exchange items

ItemStack filledContainer = FluidContainerRegistry.fillFluidContainer(valveEntity.getFluid(), equippedItemStack);

if (filledContainer != null)
{
// add filled bucket to player inventory or drop it to the ground if the inventory is full
if (!player.inventory.addItemStackToInventory(filledBucket))
{
world.spawnEntityInWorld(new EntityItem(world, x + 0.5D, y + 1.5D, z + 0.5D, filledBucket));
}
else if (player instanceof EntityPlayerMP)
FluidStack drainedFluid = valveEntity.drain(null, containerCapacity, true);

if (drainedFluid != null && drainedFluid.amount == containerCapacity)
{
((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer);
if (--equippedItemStack.stackSize <= 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, null);
}

// add filled container to player inventory or drop it to the ground if the inventory is full

if (!player.inventory.addItemStackToInventory(filledContainer))
{
world.spawnEntityInWorld(new EntityItem(world, x + 0.5D, y + 1.5D, z + 0.5D, filledContainer));
}
else if (player instanceof EntityPlayerMP)
{
((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer);
}
}
}

if (--equippedItemStack.stackSize <= 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack) null);
}
}
}

/**
* Drains the contents of a bucket into the multiblock tank.
* Drains the contents of a container into the multiblock tank.
*
* @param valveEntity
* The affected {@link ValveBlock}s {@link TileEntity} ({@link ValveBlockEntity}).
* @param world
* The world.
* @param x
* The {@link ValveBlock}s x-coordinate.
* @param y
* The {@link ValveBlock}s y-coordinate.
* @param z
* The {@link ValveBlock}s z-coordinate.
* @param player
* The player using the bucket.
* The player holding the container.
* @param equippedItemStack
* The {@link ItemStack} that contains the bucket.
* The container {@link ItemStack}.
* @param valveEntity
* The affected {@link ValveBlock}s {@link TileEntity} ({@link ValveBlockEntity}).
*/
private void drainBucketIntoTank(ValveBlockEntity valveEntity, EntityPlayer player, ItemStack equippedItemStack)
private void drainContainerIntoTank(World world, int x, int y, int z, EntityPlayer player, ItemStack equippedItemStack, ValveBlockEntity valveEntity)
{
// fill the liquid from the bucket into the tank
if ((valveEntity.getFluidAmount() == 0 || valveEntity.getFluid().isFluidEqual(equippedItemStack)) && valveEntity.getCapacity() - valveEntity.getFluidAmount() >= FluidContainerRegistry.BUCKET_VOLUME)
IFluidContainerItem containerItem = null;
FluidStack containerFluid = null;

// determine the amount of fluid in the container
if (equippedItemStack.getItem() instanceof IFluidContainerItem)
{
FluidStack fluidFromBucket = FluidContainerRegistry.getFluidForFilledItem(equippedItemStack);
containerItem = (IFluidContainerItem) equippedItemStack.getItem();
containerFluid = containerItem.getFluid(equippedItemStack);
}
else
{
containerFluid = FluidContainerRegistry.getFluidForFilledItem(equippedItemStack);
}

if (valveEntity.fill(null, fluidFromBucket, true) == FluidContainerRegistry.BUCKET_VOLUME)
// fill the liquid from the container into the tank
if (containerItem != null)
{
// handle IFluidContainerItem items

FluidStack tankFluid = valveEntity.getFluid();

if (tankFluid == null || tankFluid.isFluidEqual(containerFluid))
{
// don't consume the filled bucket in creative mode
if (!player.capabilities.isCreativeMode)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, new ItemStack(Items.bucket));
}
int drainAmount = Math.min(valveEntity.getCapacity() - valveEntity.getFluidAmount(), containerFluid.amount);
// drain the fluid from the container first because the amount per drain could be limited
FluidStack drainFluid = containerItem.drain(equippedItemStack, drainAmount, true);
valveEntity.fill(null, drainFluid, true);
}
}
else if (valveEntity.fill(null, containerFluid, true) > 0 && !player.capabilities.isCreativeMode) // don't consume the container contents in creative mode
{
// handle drain/fill by exchange items

ItemStack emptyContainer = Utils.getEmptyFluidContainer(equippedItemStack);

if (--equippedItemStack.stackSize <= 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, null);
}

// add emptied container to player inventory or drop it to the ground if the inventory is full

if (!player.inventory.addItemStackToInventory(emptyContainer))
{
world.spawnEntityInWorld(new EntityItem(world, x + 0.5D, y + 1.5D, z + 0.5D, emptyContainer));
}
else if (player instanceof EntityPlayerMP)
{
((EntityPlayerMP) player).sendContainerToPlayer(player.inventoryContainer);
}
}
}
Expand Down
95 changes: 94 additions & 1 deletion src/main/java/net/zarathul/simplefluidtanks/common/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
import java.util.ArrayList;

import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.StatCollector;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;

import com.google.common.base.Predicate;
import com.google.common.base.Strings;
Expand Down Expand Up @@ -130,7 +136,7 @@ public static final boolean notNullorEmpty(Iterable<String> items)
* Formatting arguments.
* @return
*/
public static ArrayList<String> multiLineTranslateToLocal(String key, Object... args)
public static final ArrayList<String> multiLineTranslateToLocal(String key, Object... args)
{
ArrayList<String> lines = new ArrayList<String>();

Expand All @@ -148,4 +154,91 @@ public static ArrayList<String> multiLineTranslateToLocal(String key, Object...

return lines;
}

/**
* Gets the capacity for a registered fluid container.
*
* @param fluid
* The fluid the container can hold.
* @param container
* The container.
* @return
* The containers capacity or 0 if the container could not be found.
*/
public static final int getFluidContainerCapacity(FluidStack fluid, ItemStack container)
{
if (fluid == null || container == null) return 0;

Item containerItem = container.getItem();

FluidContainerData[] containerData = FluidContainerRegistry.getRegisteredFluidContainerData();

if (containerData != null)
{
for (FluidContainerData data : containerData)
{
if (((data.emptyContainer != null && data.emptyContainer.getItem() == containerItem) || (data.filledContainer != null && data.filledContainer.getItem() == containerItem)) && fluid.isFluidEqual(data.fluid))
{
return data.fluid.amount;
}
}
}

return 0;
}

/**
* Gets the empty container for a filled one.
*
* @param filledContainer
* The filled container.
* @return
* The empty container or null if no empty container could be found.
*/
public static final ItemStack getEmptyFluidContainer(ItemStack filledContainer)
{
if (filledContainer == null) return null;

FluidStack containerFluid = FluidContainerRegistry.getFluidForFilledItem(filledContainer);

Item containerItem = filledContainer.getItem();

FluidContainerData[] containerData = FluidContainerRegistry.getRegisteredFluidContainerData();

if (containerData != null)
{
for (FluidContainerData data : containerData)
{
if ((data.filledContainer != null && data.filledContainer.getItem() == containerItem) && containerFluid.isFluidEqual(data.fluid))
{
return data.emptyContainer.copy();
}
}
}

return null;
}

/**
* Checks if an item is a container that implements {@code IFluidContainerItem} and is empty.
*
* @param item
* The container to check.
* @return
* {@code true} if the container is empty and implements {@code IFluidContainerItem}, otherwise {@code false}.
*/
public static final boolean isEmptyComplexContainer(ItemStack item)
{
if (item == null) return false;

if (item.getItem() instanceof IFluidContainerItem)
{
IFluidContainerItem container = (IFluidContainerItem) item.getItem();
FluidStack containerFluid = container.getFluid(item);

return (containerFluid == null || (containerFluid != null && containerFluid.amount == 0));
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import net.zarathul.simplefluidtanks.items.ValveItem;
import net.zarathul.simplefluidtanks.items.WrenchItem;
import net.zarathul.simplefluidtanks.rendering.TankBlockRenderer;
import net.zarathul.simplefluidtanks.rendering.TankItemRenderer;
import net.zarathul.simplefluidtanks.rendering.ValveItemRenderer;
import net.zarathul.simplefluidtanks.tileentities.TankBlockEntity;
import net.zarathul.simplefluidtanks.tileentities.ValveBlockEntity;
Expand Down Expand Up @@ -79,7 +78,6 @@ public static void registerItems()
public static void registerCustomRenderers()
{
RenderingRegistry.registerBlockHandler(new TankBlockRenderer());
MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(SimpleFluidTanks.tankBlock), new TankItemRenderer());
MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(SimpleFluidTanks.valveBlock), new ValveItemRenderer());
}

Expand Down
Loading

0 comments on commit 86a8c0e

Please sign in to comment.