Added Fluid routing to the routing nodes - this is done by using the Fluid Filter and placing a fluid container as the filter.

(cherry picked from commit a5a17f6)
This commit is contained in:
WayofTime 2016-12-14 11:48:39 -08:00 committed by Nicholas Ignoffo
parent a628adfde8
commit 65104db564
24 changed files with 725 additions and 53 deletions

View file

@ -0,0 +1,36 @@
package WayofTime.bloodmagic.routing;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
public interface IFluidFilter extends IRoutingFilter
{
void initializeFilter(List<ItemStack> filteredList, TileEntity tile, IFluidHandler fluidHandler, boolean isFilterOutput);
/**
* This method is only called when the output tank this filter is managing
* receives an ItemStack. Should only really be called by the Input filter
* via it's transfer method.
*
* @param fluidStack
* - The stack to filter
*
* @return - The remainder of the stack after it has been absorbed into the
* tank.
*/
FluidStack transferStackThroughOutputFilter(FluidStack fluidStack);
/**
* This method is only called on an input filter to transfer FluidStacks
* from the input tank to the output tank.
*/
int transferThroughInputFilter(IFluidFilter outputFilter, int maxTransfer);
boolean doesStackMatchFilter(FluidStack testStack);
boolean doStacksMatch(FluidStack filterStack, FluidStack testStack);
}

View file

@ -0,0 +1,10 @@
package WayofTime.bloodmagic.routing;
import net.minecraft.util.EnumFacing;
public interface IFluidRoutingNode extends IRoutingNode
{
boolean isTankConnectedToSide(EnumFacing side);
int getPriority(EnumFacing side);
}

View file

@ -0,0 +1,10 @@
package WayofTime.bloodmagic.routing;
import net.minecraft.util.EnumFacing;
public interface IInputFluidRoutingNode extends IFluidRoutingNode
{
boolean isFluidInput(EnumFacing side);
IFluidFilter getInputFluidFilterForSide(EnumFacing side);
}

View file

@ -6,7 +6,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.items.IItemHandler;
public interface IItemFilter
public interface IItemFilter extends IRoutingFilter
{
void initializeFilter(List<ItemStack> filteredList, TileEntity tile, IItemHandler itemHandler, boolean isFilterOutput);

View file

@ -0,0 +1,10 @@
package WayofTime.bloodmagic.routing;
import net.minecraft.util.EnumFacing;
public interface IOutputFluidRoutingNode extends IFluidRoutingNode
{
boolean isFluidOutput(EnumFacing side);
IFluidFilter getOutputFluidFilterForSide(EnumFacing side);
}

View file

@ -0,0 +1,6 @@
package WayofTime.bloodmagic.routing;
public interface IRoutingFilter
{
}

View file

@ -0,0 +1,212 @@
package WayofTime.bloodmagic.routing;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
public class RoutingFluidFilter implements IFluidFilter
{
protected List<FluidStack> requestList;
protected TileEntity accessedTile;
protected IFluidHandler fluidHandler;
@Override
public void initializeFilter(List<ItemStack> filteredList, TileEntity tile, IFluidHandler fluidHandler, boolean isFilterOutput)
{
this.accessedTile = tile;
this.fluidHandler = fluidHandler;
if (isFilterOutput)
{
//The requestList contains a list of how much can be extracted.
requestList = new ArrayList<FluidStack>();
for (ItemStack filterStack : filteredList)
{
FluidStack fluidFilterStack = getFluidStackFromItemStack(filterStack);
if (fluidFilterStack != null)
{
requestList.add(fluidFilterStack);
}
}
IFluidTankProperties[] properties = fluidHandler.getTankProperties();
for (IFluidTankProperties property : properties)
{
FluidStack containedStack = property.getContents();
if (containedStack != null)
{
for (FluidStack fluidFilterStack : requestList)
{
if (doStacksMatch(fluidFilterStack, containedStack))
{
fluidFilterStack.amount = Math.max(fluidFilterStack.amount - containedStack.amount, 0);
}
}
}
}
} else
{
requestList = new ArrayList<FluidStack>();
for (ItemStack filterStack : filteredList)
{
FluidStack fluidFilterStack = getFluidStackFromItemStack(filterStack);
if (fluidFilterStack != null)
{
fluidFilterStack.amount *= -1;
requestList.add(fluidFilterStack);
}
}
IFluidTankProperties[] properties = fluidHandler.getTankProperties();
for (IFluidTankProperties property : properties)
{
FluidStack containedStack = property.getContents();
if (containedStack != null)
{
for (FluidStack fluidFilterStack : requestList)
{
if (doStacksMatch(fluidFilterStack, containedStack))
{
fluidFilterStack.amount += containedStack.amount;
}
}
}
}
}
}
public static FluidStack getFluidStackFromItemStack(ItemStack inputStack)
{
FluidStack fluidStack = FluidUtil.getFluidContained(inputStack);
fluidStack.amount = inputStack.stackSize;
return fluidStack;
}
/**
* Gives the remainder~
*/
@Override
public FluidStack transferStackThroughOutputFilter(FluidStack fluidStack)
{
int allowedAmount = 0;
for (FluidStack filterStack : requestList)
{
if (doStacksMatch(filterStack, fluidStack))
{
allowedAmount = Math.min(filterStack.amount, fluidStack.amount);
break;
}
}
if (allowedAmount <= 0)
{
return fluidStack;
}
FluidStack copyStack = fluidStack.copy();
int filledAmount = fluidHandler.fill(fluidStack, true);
copyStack.amount = fluidStack.amount - filledAmount;
Iterator<FluidStack> itr = requestList.iterator();
while (itr.hasNext())
{
FluidStack filterStack = itr.next();
if (doStacksMatch(filterStack, copyStack))
{
filterStack.amount -= filledAmount;
if (filterStack.amount <= 0)
{
itr.remove();
}
}
}
World world = accessedTile.getWorld();
BlockPos pos = accessedTile.getPos();
world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3);
return copyStack.amount <= 0 ? null : copyStack;
}
@Override
public int transferThroughInputFilter(IFluidFilter outputFilter, int maxTransfer)
{
for (FluidStack filterFluidStack : requestList)
{
int allowedAmount = Math.min(filterFluidStack.amount, maxTransfer);
if (allowedAmount <= 0)
{
continue;
}
FluidStack copyStack = filterFluidStack.copy();
copyStack.amount = allowedAmount;
FluidStack drainStack = fluidHandler.drain(copyStack, false);
if (drainStack != null) //Can't pull this liquid out for some reason if it fails this check
{
FluidStack remainderStack = outputFilter.transferStackThroughOutputFilter(drainStack);
int drained = remainderStack == null ? copyStack.amount : (copyStack.amount - remainderStack.amount);
if (drained > 0)
{
drainStack.amount = drained;
fluidHandler.drain(drainStack, true);
maxTransfer -= drained;
}
Iterator<FluidStack> itr = requestList.iterator();
while (itr.hasNext())
{
FluidStack filterStack = itr.next();
if (doStacksMatch(filterStack, copyStack))
{
filterStack.amount -= drained;
if (filterStack.amount <= 0)
{
itr.remove();
}
}
}
World world = accessedTile.getWorld();
BlockPos pos = accessedTile.getPos();
world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3);
return maxTransfer;
}
}
return 0;
}
@Override
public boolean doesStackMatchFilter(FluidStack testStack)
{
for (FluidStack filterStack : requestList)
{
if (doStacksMatch(filterStack, testStack))
{
return true;
}
}
return false;
}
@Override
public boolean doStacksMatch(FluidStack filterStack, FluidStack testStack)
{
return testStack != null && filterStack.getFluid() == testStack.getFluid();
}
}

View file

@ -8,6 +8,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import WayofTime.bloodmagic.util.GhostItemHelper;
import WayofTime.bloodmagic.util.Utils;
/**