From 9aac50542bf7f43d7ac4431209e3fc52e9f24a21 Mon Sep 17 00:00:00 2001 From: WayofTime Date: Tue, 12 Jan 2016 21:17:26 -0500 Subject: [PATCH] Implemented a test filter - hasn't been tested! :D --- .../bloodmagic/routing/IItemFilter.java | 34 ++ .../bloodmagic/routing/IItemRoutingNode.java | 10 + .../bloodmagic/routing/TestItemFilter.java | 299 ++++++++++++++++++ .../routing/TileMasterRoutingNode.java | 31 ++ .../tile/routing/TileRoutingNode.java | 18 +- 5 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 src/main/java/WayofTime/bloodmagic/routing/IItemFilter.java create mode 100644 src/main/java/WayofTime/bloodmagic/routing/IItemRoutingNode.java create mode 100644 src/main/java/WayofTime/bloodmagic/routing/TestItemFilter.java diff --git a/src/main/java/WayofTime/bloodmagic/routing/IItemFilter.java b/src/main/java/WayofTime/bloodmagic/routing/IItemFilter.java new file mode 100644 index 00000000..6ab2bbdf --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/routing/IItemFilter.java @@ -0,0 +1,34 @@ +package WayofTime.bloodmagic.routing; + +import java.util.List; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; + +public interface IItemFilter +{ + public void initializeFilter(List filteredList, IInventory inventory, EnumFacing side, boolean isFilterOutput); + + /** + * This method is only called when the output inventory this filter is + * managing receives an ItemStack. Should only really be called by the Input + * filter via it's transfer method. + * + * @param stack + * - + * @return - The remainder of the stack after it has been absorbed into the + * inventory. + */ + public ItemStack transferStackThroughOutputFilter(ItemStack inputStack); + + /** + * This method is only called on an input filter to transfer ItemStacks from + * the input inventory to the output inventory. + */ + public void transferThroughInputFilter(TestItemFilter outputFilter); + + public boolean doesStackMatchFilter(ItemStack testStack); + + public boolean doStacksMatch(ItemStack filterStack, ItemStack testStack); +} diff --git a/src/main/java/WayofTime/bloodmagic/routing/IItemRoutingNode.java b/src/main/java/WayofTime/bloodmagic/routing/IItemRoutingNode.java new file mode 100644 index 00000000..04855fc5 --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/routing/IItemRoutingNode.java @@ -0,0 +1,10 @@ +package WayofTime.bloodmagic.routing; + +import net.minecraft.util.EnumFacing; + +public interface IItemRoutingNode extends IRoutingNode +{ + IItemFilter generateFilterForSide(EnumFacing side); //Will later return an IItemFilter once fully implemented. + + boolean isInventoryConnectedToSide(EnumFacing side); +} diff --git a/src/main/java/WayofTime/bloodmagic/routing/TestItemFilter.java b/src/main/java/WayofTime/bloodmagic/routing/TestItemFilter.java new file mode 100644 index 00000000..54056b7b --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/routing/TestItemFilter.java @@ -0,0 +1,299 @@ +package WayofTime.bloodmagic.routing; + +import java.util.List; + +import WayofTime.bloodmagic.util.Utils; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; + +/** + * This particular implementation of IItemFilter checks to make sure that a) as + * an output filter it will fill until the requested amount and b) as an input + * filter it will only syphon until the requested amount. + * + * @author WayofTime + * + */ +public class TestItemFilter implements IItemFilter +{ + /* + * This list acts as the way the filter keeps track of its contents. For the + * case of an output filter, it holds a list of ItemStacks that needs to be + * inserted in the inventory to finish its request. For the case of an input + * filter, it keeps track of how many can be removed. + */ + private List requestList; + private IInventory accessedInventory; + private EnumFacing accessedSide; + + /** + * Initializes the filter so that it knows what it wants to fulfill. + * + * @param filteredList + * - The list of ItemStacks that the filter is set to. + * @param inventory + * - The inventory that is being accessed. This inventory is either + * being pulled from or pushed to. + * @param side + * - The side that the inventory is being accessed from. Used for + * pulling/pushing from/to the inventory. + * @param isFilterOutput + * - Tells the filter what actions to expect. If true, it should be + * initialized as an output filter. If false, it should be + * initialized as an input filter. + */ + public void initializeFilter(List filteredList, IInventory inventory, EnumFacing side, boolean isFilterOutput) + { + this.accessedInventory = inventory; + this.accessedSide = side; + if (isFilterOutput) + { + requestList = filteredList; + boolean[] canAccessSlot = new boolean[inventory.getSizeInventory()]; + if (inventory instanceof ISidedInventory) + { + int[] slots = ((ISidedInventory) inventory).getSlotsForFace(side); + for (int slot : slots) + { + canAccessSlot[slot] = true; + } + } else + { + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) + { + canAccessSlot[slot] = true; + } + } + + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) + { + if (!canAccessSlot[slot]) + { + continue; + } + + ItemStack checkedStack = inventory.getStackInSlot(slot); + if (checkedStack == null) + { + continue; + } + + int stackSize = checkedStack.stackSize; + + for (ItemStack filterStack : requestList) + { + if (filterStack.stackSize == 0) + { + continue; + } + + if (doStacksMatch(filterStack, checkedStack)) + { + filterStack.stackSize = Math.max(filterStack.stackSize - stackSize, 0); + } + } + } + } else + { + requestList = filteredList; + for (ItemStack filterStack : requestList) + { + filterStack.stackSize *= -1; //Invert the stack size so that + } + + boolean[] canAccessSlot = new boolean[inventory.getSizeInventory()]; + if (inventory instanceof ISidedInventory) + { + int[] slots = ((ISidedInventory) inventory).getSlotsForFace(side); + for (int slot : slots) + { + canAccessSlot[slot] = true; + } + } else + { + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) + { + canAccessSlot[slot] = true; + } + } + + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) + { + if (!canAccessSlot[slot]) + { + continue; + } + + ItemStack checkedStack = inventory.getStackInSlot(slot); + if (checkedStack == null) + { + continue; + } + + int stackSize = checkedStack.stackSize; + + for (ItemStack filterStack : filteredList) + { + if (doStacksMatch(filterStack, checkedStack)) + { + filterStack.stackSize += stackSize; + } + } + } + } + + for (ItemStack filterStack : requestList) + { + if (filterStack.stackSize <= 0) + { + requestList.remove(filterStack); + } + } + } + + /** + * This method is only called when the output inventory this filter is + * managing receives an ItemStack. Should only really be called by the Input + * filter via it's transfer method. + * + * @param stack + * - + * @return - The remainder of the stack after it has been absorbed into the + * inventory. + */ + public ItemStack transferStackThroughOutputFilter(ItemStack inputStack) + { + int allowedAmount = 0; + for (ItemStack filterStack : requestList) + { + if (doStacksMatch(filterStack, inputStack)) + { + allowedAmount = Math.min(filterStack.stackSize, inputStack.stackSize); + break; + } + } + + if (allowedAmount <= 0) + { + return inputStack; + } + + ItemStack testStack = inputStack.copy(); + testStack.stackSize = allowedAmount; + ItemStack remainderStack = Utils.insertStackIntoInventory(testStack, accessedInventory, accessedSide, allowedAmount); + + int changeAmount = inputStack.stackSize - (remainderStack == null ? 0 : remainderStack.stackSize); + + for (ItemStack filterStack : requestList) + { + if (doStacksMatch(filterStack, inputStack)) + { + filterStack.stackSize -= changeAmount; + if (filterStack.stackSize <= 0) + { + requestList.remove(filterStack); + } + } + } + + return remainderStack; + } + + /** + * This method is only called on an input filter to transfer ItemStacks from + * the input inventory to the output inventory. + */ + public void transferThroughInputFilter(TestItemFilter outputFilter) + { + boolean[] canAccessSlot = new boolean[accessedInventory.getSizeInventory()]; + if (accessedInventory instanceof ISidedInventory) + { + int[] slots = ((ISidedInventory) accessedInventory).getSlotsForFace(accessedSide); + for (int slot : slots) + { + canAccessSlot[slot] = true; + } + } else + { + for (int slot = 0; slot < accessedInventory.getSizeInventory(); slot++) + { + canAccessSlot[slot] = true; + } + } + + for (int slot = 0; slot < accessedInventory.getSizeInventory(); slot++) + { + if (!canAccessSlot[slot]) + { + continue; + } + + ItemStack inputStack = accessedInventory.getStackInSlot(slot); + if (inputStack == null || (accessedInventory instanceof ISidedInventory && !((ISidedInventory) accessedInventory).canExtractItem(slot, inputStack, accessedSide))) + { + continue; + } + + int allowedAmount = 0; + for (ItemStack filterStack : requestList) + { + if (doStacksMatch(filterStack, inputStack)) + { + allowedAmount = Math.min(filterStack.stackSize, inputStack.stackSize); + break; + } + } + + if (allowedAmount <= 0) + { + continue; + } + + ItemStack testStack = inputStack.copy(); + testStack.stackSize = allowedAmount; + ItemStack remainderStack = outputFilter.transferStackThroughOutputFilter(testStack); + + if (remainderStack != null && remainderStack.stackSize == allowedAmount) + { + //Nothing has changed. Moving on! + continue; + } + + accessedInventory.setInventorySlotContents(slot, remainderStack); //Sets the slot in the inventory + + int changeAmount = inputStack.stackSize - (remainderStack == null ? 0 : remainderStack.stackSize); + + for (ItemStack filterStack : requestList) + { + if (doStacksMatch(filterStack, inputStack)) + { + filterStack.stackSize -= changeAmount; + if (filterStack.stackSize <= 0) + { + requestList.remove(filterStack); + } + } + } + } + } + + public boolean doesStackMatchFilter(ItemStack testStack) + { + for (ItemStack filterStack : requestList) + { + if (doStacksMatch(filterStack, testStack)) + { + return true; + } + } + + return false; + } + + public boolean doStacksMatch(ItemStack filterStack, ItemStack testStack) + { + return Utils.canCombine(filterStack, testStack); + } +} diff --git a/src/main/java/WayofTime/bloodmagic/routing/TileMasterRoutingNode.java b/src/main/java/WayofTime/bloodmagic/routing/TileMasterRoutingNode.java index 3121c314..2b273014 100644 --- a/src/main/java/WayofTime/bloodmagic/routing/TileMasterRoutingNode.java +++ b/src/main/java/WayofTime/bloodmagic/routing/TileMasterRoutingNode.java @@ -4,10 +4,12 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.world.World; import WayofTime.bloodmagic.api.Constants; @@ -22,10 +24,39 @@ public class TileMasterRoutingNode extends TileEntity implements IMasterRoutingN private List outputNodeList = new LinkedList(); private List inputNodeList = new LinkedList(); + public static final int tickRate = 20; + @Override public void update() { + if (worldObj.isRemote || worldObj.getTotalWorldTime() % tickRate != 0) //Temporary tick rate solver + { + return; + } + for (BlockPos outputPos : outputNodeList) + { + TileEntity outputTile = worldObj.getTileEntity(outputPos); + if (outputTile instanceof TileOutputRoutingNode && this.isConnected(new LinkedList(), outputPos)) + { + TileOutputRoutingNode outputNode = (TileOutputRoutingNode) outputTile; + + for (EnumFacing facing : EnumFacing.VALUES) + { + if (!outputNode.isInventoryConnectedToSide(facing)) + { + continue; + } + + TileEntity tile = worldObj.getTileEntity(outputPos.offset(facing)); + if (!(tile instanceof IInventory)) + { + continue; + } + + } + } + } } @Override diff --git a/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java b/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java index e424a1ad..e25fd426 100644 --- a/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java +++ b/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java @@ -7,12 +7,15 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import WayofTime.bloodmagic.api.Constants; +import WayofTime.bloodmagic.routing.IItemFilter; +import WayofTime.bloodmagic.routing.IItemRoutingNode; import WayofTime.bloodmagic.routing.IMasterRoutingNode; import WayofTime.bloodmagic.routing.IRoutingNode; -public class TileRoutingNode extends TileEntity implements IRoutingNode +public class TileRoutingNode extends TileEntity implements IRoutingNode, IItemRoutingNode { private BlockPos masterPos = BlockPos.ORIGIN; private List connectionList = new LinkedList(); @@ -155,4 +158,17 @@ public class TileRoutingNode extends TileEntity implements IRoutingNode connectionList.remove(pos1); } } + + @Override + public boolean isInventoryConnectedToSide(EnumFacing side) + { + //TODO: Implement connections for side + return true; + } + + @Override + public IItemFilter generateFilterForSide(EnumFacing side) + { + return null; + } }