package crazypants.enderio.conduit.item.filter; import crazypants.enderio.conduit.gui.GuiExternalConnection; import crazypants.enderio.conduit.gui.item.ExistingItemFilterGui; import crazypants.enderio.conduit.gui.item.IItemFilterGui; import crazypants.enderio.conduit.item.IItemConduit; import io.netty.buffer.ByteBuf; import java.util.ArrayList; import java.util.List; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraftforge.oredict.OreDictionary; import com.enderio.core.client.gui.widget.GhostSlot; import com.enderio.core.common.network.NetworkUtil; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import crazypants.enderio.conduit.item.NetworkedInventory; public class ExistingItemFilter implements IItemFilter { boolean matchMeta = true; boolean useOreDict = false; boolean convertOreDict = false; boolean matchNBT = false; boolean sticky = false; private boolean blacklist = false; List<ItemStack> snapshot = null; @Override public boolean doesItemPassFilter(NetworkedInventory ni, ItemStack item) { if(item == null) { return false; } if(snapshot != null) { return isStackInSnapshot(item) == !blacklist; } else if(ni != null) { return isStackInInventory(ni, item) == !blacklist; } return false; } private boolean isStackInInventory(NetworkedInventory ni, ItemStack item) { int[] slots = ni.getInventory().getAccessibleSlotsFromSide(ni.getInventorySide()); for (int i = 0; i < slots.length; i++) { ItemStack stack = ni.getInventory().getStackInSlot(i); if (stackEqual(item, stack)) { return true; } } return false; } boolean isStackInSnapshot(ItemStack item) { for(ItemStack stack : snapshot) { if(stackEqual(item, stack)) { return true; } } return false; } boolean stackEqual(ItemStack toInsert, ItemStack existing) { if(toInsert == null || existing == null) { return false; } boolean matched = false; if(useOreDict) { int existingId = OreDictionary.getOreID(existing); matched = existingId != -1 && existingId == OreDictionary.getOreID(toInsert); } if(!matched) { matched = Item.getIdFromItem(toInsert.getItem()) == Item.getIdFromItem(existing.getItem()); if(matched && matchMeta) { matched = toInsert.getItemDamage() == existing.getItemDamage(); } if(matched && matchNBT) { matched = ItemStack.areItemStackTagsEqual(toInsert, existing); } } return matched; } @Override public boolean doesFilterCaptureStack(NetworkedInventory inv, ItemStack item) { boolean res = sticky && doesItemPassFilter(inv, item); return res; } @Override public boolean isValid() { return true; } @Override public void createGhostSlots(List<GhostSlot> slots, int xOffset, int yOffset, Runnable cb) { } @Override public int getSlotCount() { return 0; } public void setSnapshot(NetworkedInventory ni) { snapshot = new ArrayList<ItemStack>(); mergeSnapshot(ni); } public void mergeSnapshot(NetworkedInventory ni) { if(snapshot == null) { snapshot = new ArrayList<ItemStack>(); } int[] slots = ni.getInventory().getAccessibleSlotsFromSide(ni.getInventorySide()); for (int i = 0; i < slots.length; i++) { ItemStack stack = ni.getInventory().getStackInSlot(i); if(stack != null && !isStackInSnapshot(stack)) { snapshot.add(stack); } } } public boolean mergeSnapshot(IInventory inventory) { if(snapshot == null) { snapshot = new ArrayList<ItemStack>(); } int size = inventory.getSizeInventory(); boolean added = false; for (int i = 0; i < size; i++) { ItemStack stack = inventory.getStackInSlot(i); if(stack != null && !isStackInSnapshot(stack)) { snapshot.add(stack); added = true; } } return added; } public List<ItemStack> getSnapshot() { return snapshot; } public void setSnapshot(List<ItemStack> snapshot) { this.snapshot = snapshot; } public boolean isMatchMeta() { return matchMeta; } public void setMatchMeta(boolean matchMeta) { this.matchMeta = matchMeta; } public boolean isMatchNBT() { return matchNBT; } public void setMatchNBT(boolean matchNbt) { matchNBT = matchNbt; } public boolean isUseOreDict() { return useOreDict; } public void setUseOreDict(boolean useOreDict) { this.useOreDict = useOreDict; } @Override public boolean isSticky() { return sticky; } public void setSticky(boolean sticky) { this.sticky = sticky; } public void setBlacklist(boolean value) { blacklist = value; } public boolean isBlacklist() { return blacklist; } @Override @SideOnly(Side.CLIENT) public IItemFilterGui getGui(GuiExternalConnection gui, IItemConduit itemConduit, boolean isInput) { return new ExistingItemFilterGui(gui, itemConduit, isInput); } @Override public void readFromNBT(NBTTagCompound nbtRoot) { readSettingsFromNBT(nbtRoot); if(nbtRoot.hasKey("snapshot")) { snapshot = new ArrayList<ItemStack>(); NBTTagList itemList = (NBTTagList)nbtRoot.getTag("snapshot"); for(int i=0;i<itemList.tagCount();i++) { NBTTagCompound itemTag = itemList.getCompoundTagAt(i); ItemStack itemStack = ItemStack.loadItemStackFromNBT(itemTag); if(itemStack != null) { snapshot.add(itemStack); } } } else { snapshot = null; } } protected void readSettingsFromNBT(NBTTagCompound nbtRoot) { matchMeta = nbtRoot.getBoolean("matchMeta"); matchNBT = nbtRoot.getBoolean("matchNBT"); useOreDict = nbtRoot.getBoolean("useOreDict"); sticky = nbtRoot.getBoolean("sticky"); blacklist = nbtRoot.getBoolean("blacklist"); } @Override public void writeToNBT(NBTTagCompound nbtRoot) { writeSettingToNBT(nbtRoot); if(snapshot != null) { NBTTagList itemList = new NBTTagList(); for (ItemStack item : snapshot) { if(item != null) { NBTTagCompound itemTag = new NBTTagCompound(); item.writeToNBT(itemTag); itemList.appendTag(itemTag); } } nbtRoot.setTag("snapshot", itemList); } } protected void writeSettingToNBT(NBTTagCompound nbtRoot) { nbtRoot.setBoolean("matchMeta", matchMeta); nbtRoot.setBoolean("matchNBT", matchNBT); nbtRoot.setBoolean("useOreDict", useOreDict); nbtRoot.setBoolean("sticky", sticky); nbtRoot.setBoolean("blacklist", blacklist); } @Override public void writeToByteBuf(ByteBuf buf) { NBTTagCompound settingsTag = new NBTTagCompound(); writeSettingToNBT(settingsTag); NetworkUtil.writeNBTTagCompound(settingsTag, buf); buf.writeInt(snapshot == null ? 0 : snapshot.size()); if(snapshot == null) { return; } for (ItemStack item : snapshot) { NBTTagCompound itemRoot = new NBTTagCompound(); item.writeToNBT(itemRoot); NetworkUtil.writeNBTTagCompound(itemRoot, buf); } } @Override public void readFromByteBuf(ByteBuf buf) { NBTTagCompound settingsTag = NetworkUtil.readNBTTagCompound(buf); readSettingsFromNBT(settingsTag); int numItems = buf.readInt(); if(numItems == 0) { snapshot = null; return; } snapshot = new ArrayList<ItemStack>(numItems); for (int i = 0; i < numItems; i++) { NBTTagCompound itemTag = NetworkUtil.readNBTTagCompound(buf); ItemStack item = ItemStack.loadItemStackFromNBT(itemTag); if(item != null) { snapshot.add(item); } } } }