From 86b6474f35a7d84606bc79db9c723315eb790631 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Tue, 19 Nov 2013 12:13:37 -0500 Subject: [PATCH] Beginning foundations of Digital Miner. --- .../mekanism/client/gui/GuiDigitalMiner.java | 5 + .../client/gui/GuiDigitalMinerConfig.java | 5 + .../client/gui/GuiItemStackFilter.java | 10 +- .../client/gui/GuiLogisticalSorter.java | 40 +++--- .../mekanism/client/gui/GuiOreDictFilter.java | 12 +- .../common/miner/MItemStackFilter.java | 79 +++++++++++ .../mekanism/common/miner/MOreDictFilter.java | 103 ++++++++++++++ common/mekanism/common/miner/MinerFilter.java | 66 +++++++++ .../common/miner/ThreadMinerSearch.java | 10 ++ .../tileentity/TileEntityDigitalMiner.java | 129 +++++++++++++++++- .../tileentity/TileEntityElectricPump.java | 6 +- ...StackFilter.java => TItemStackFilter.java} | 10 +- ...OreDictFilter.java => TOreDictFilter.java} | 8 +- .../common/transporter/TransporterFilter.java | 8 +- .../assets/mekanism/gui/GuiDigitalMiner.png | Bin 0 -> 5231 bytes .../mekanism/gui/GuiDigitalMinerConfig.png | Bin 0 -> 3888 bytes .../assets/mekanism/gui/GuiElectricChest.png | Bin 5562 -> 5477 bytes 17 files changed, 441 insertions(+), 50 deletions(-) create mode 100644 common/mekanism/client/gui/GuiDigitalMiner.java create mode 100644 common/mekanism/client/gui/GuiDigitalMinerConfig.java create mode 100644 common/mekanism/common/miner/MItemStackFilter.java create mode 100644 common/mekanism/common/miner/MOreDictFilter.java create mode 100644 common/mekanism/common/miner/MinerFilter.java create mode 100644 common/mekanism/common/miner/ThreadMinerSearch.java rename common/mekanism/common/transporter/{ItemStackFilter.java => TItemStackFilter.java} (86%) rename common/mekanism/common/transporter/{OreDictFilter.java => TOreDictFilter.java} (89%) create mode 100644 resources/assets/mekanism/gui/GuiDigitalMiner.png create mode 100644 resources/assets/mekanism/gui/GuiDigitalMinerConfig.png diff --git a/common/mekanism/client/gui/GuiDigitalMiner.java b/common/mekanism/client/gui/GuiDigitalMiner.java new file mode 100644 index 000000000..5fbfe032b --- /dev/null +++ b/common/mekanism/client/gui/GuiDigitalMiner.java @@ -0,0 +1,5 @@ +package mekanism.client.gui; + +public class GuiDigitalMiner { + +} diff --git a/common/mekanism/client/gui/GuiDigitalMinerConfig.java b/common/mekanism/client/gui/GuiDigitalMinerConfig.java new file mode 100644 index 000000000..f3c2a0095 --- /dev/null +++ b/common/mekanism/client/gui/GuiDigitalMinerConfig.java @@ -0,0 +1,5 @@ +package mekanism.client.gui; + +public class GuiDigitalMinerConfig { + +} diff --git a/common/mekanism/client/gui/GuiItemStackFilter.java b/common/mekanism/client/gui/GuiItemStackFilter.java index d28d74a6b..7c75d8d3f 100644 --- a/common/mekanism/client/gui/GuiItemStackFilter.java +++ b/common/mekanism/client/gui/GuiItemStackFilter.java @@ -11,7 +11,7 @@ import mekanism.common.network.PacketLogisticalSorterGui; import mekanism.common.network.PacketLogisticalSorterGui.SorterGuiPacket; import mekanism.common.network.PacketNewFilter; import mekanism.common.tileentity.TileEntityLogisticalSorter; -import mekanism.common.transporter.ItemStackFilter; +import mekanism.common.transporter.TItemStackFilter; import mekanism.common.util.MekanismUtils; import mekanism.common.util.MekanismUtils.ResourceType; import mekanism.common.util.TransporterUtils; @@ -30,9 +30,9 @@ public class GuiItemStackFilter extends GuiMekanism public boolean isNew = false; - public ItemStackFilter origFilter; + public TItemStackFilter origFilter; - public ItemStackFilter filter = new ItemStackFilter(); + public TItemStackFilter filter = new TItemStackFilter(); public String status = EnumColor.DARK_GREEN + "All OK"; @@ -46,8 +46,8 @@ public class GuiItemStackFilter extends GuiMekanism super(new ContainerFilter(player.inventory)); tileEntity = tentity; - origFilter = (ItemStackFilter)tileEntity.filters.get(index); - filter = ((ItemStackFilter)tileEntity.filters.get(index)).clone(); + origFilter = (TItemStackFilter)tileEntity.filters.get(index); + filter = ((TItemStackFilter)tileEntity.filters.get(index)).clone(); } public GuiItemStackFilter(EntityPlayer player, TileEntityLogisticalSorter tentity) diff --git a/common/mekanism/client/gui/GuiLogisticalSorter.java b/common/mekanism/client/gui/GuiLogisticalSorter.java index 355b84a1b..b7b581a6e 100644 --- a/common/mekanism/client/gui/GuiLogisticalSorter.java +++ b/common/mekanism/client/gui/GuiLogisticalSorter.java @@ -16,8 +16,8 @@ import mekanism.common.network.PacketLogisticalSorterGui; import mekanism.common.network.PacketLogisticalSorterGui.SorterGuiPacket; import mekanism.common.network.PacketTileEntity; import mekanism.common.tileentity.TileEntityLogisticalSorter; -import mekanism.common.transporter.ItemStackFilter; -import mekanism.common.transporter.OreDictFilter; +import mekanism.common.transporter.TItemStackFilter; +import mekanism.common.transporter.TOreDictFilter; import mekanism.common.transporter.TransporterFilter; import mekanism.common.util.MekanismUtils; import mekanism.common.util.MekanismUtils.ResourceType; @@ -43,7 +43,7 @@ public class GuiLogisticalSorter extends GuiMekanism public int stackSwitch = 0; - public Map oreDictStacks = new HashMap(); + public Map oreDictStacks = new HashMap(); public float scroll; @@ -81,7 +81,7 @@ public class GuiLogisticalSorter extends GuiMekanism if(stackSwitch == 0) { - for(Map.Entry entry : oreDictStacks.entrySet()) + for(Map.Entry entry : oreDictStacks.entrySet()) { if(entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() > 0) { @@ -101,7 +101,7 @@ public class GuiLogisticalSorter extends GuiMekanism stackSwitch = 20; } else { - for(Map.Entry entry : oreDictStacks.entrySet()) + for(Map.Entry entry : oreDictStacks.entrySet()) { if(entry.getValue().iterStacks != null && entry.getValue().iterStacks.size() == 0) { @@ -110,19 +110,19 @@ public class GuiLogisticalSorter extends GuiMekanism } } - Set filtersVisible = new HashSet(); + Set filtersVisible = new HashSet(); for(int i = 0; i < 4; i++) { - if(tileEntity.filters.get(getFilterIndex()+i) instanceof OreDictFilter) + if(tileEntity.filters.get(getFilterIndex()+i) instanceof TOreDictFilter) { - filtersVisible.add((OreDictFilter)tileEntity.filters.get(getFilterIndex()+i)); + filtersVisible.add((TOreDictFilter)tileEntity.filters.get(getFilterIndex()+i)); } } for(TransporterFilter filter : tileEntity.filters) { - if(filter instanceof OreDictFilter && !filtersVisible.contains(filter)) + if(filter instanceof TOreDictFilter && !filtersVisible.contains(filter)) { if(oreDictStacks.containsKey(filter)) { @@ -158,12 +158,12 @@ public class GuiLogisticalSorter extends GuiMekanism { TransporterFilter filter = tileEntity.filters.get(getFilterIndex()+i); - if(filter instanceof ItemStackFilter) + if(filter instanceof TItemStackFilter) { mc.sndManager.playSoundFX("random.click", 1.0F, 1.0F); PacketHandler.sendPacket(Transmission.SERVER, new PacketLogisticalSorterGui().setParams(SorterGuiPacket.SERVER_INDEX, Object3D.get(tileEntity), 1, getFilterIndex()+i)); } - else if(filter instanceof OreDictFilter) + else if(filter instanceof TOreDictFilter) { mc.sndManager.playSoundFX("random.click", 1.0F, 1.0F); PacketHandler.sendPacket(Transmission.SERVER, new PacketLogisticalSorterGui().setParams(SorterGuiPacket.SERVER_INDEX, Object3D.get(tileEntity), 2, getFilterIndex()+i)); @@ -283,9 +283,9 @@ public class GuiLogisticalSorter extends GuiMekanism TransporterFilter filter = tileEntity.filters.get(getFilterIndex()+i); int yStart = i*29 + 18; - if(filter instanceof ItemStackFilter) + if(filter instanceof TItemStackFilter) { - ItemStackFilter itemFilter = (ItemStackFilter)filter; + TItemStackFilter itemFilter = (TItemStackFilter)filter; if(itemFilter.itemType != null) { @@ -299,9 +299,9 @@ public class GuiLogisticalSorter extends GuiMekanism fontRenderer.drawString("Item Filter", 78, yStart + 2, 0x404040); fontRenderer.drawString(filter.color != null ? filter.color.getName() : "None", 78, yStart + 11, 0x404040); } - else if(filter instanceof OreDictFilter) + else if(filter instanceof TOreDictFilter) { - OreDictFilter oreFilter = (OreDictFilter)filter; + TOreDictFilter oreFilter = (TOreDictFilter)filter; if(!oreDictStacks.containsKey(oreFilter)) { @@ -386,11 +386,11 @@ public class GuiLogisticalSorter extends GuiMekanism boolean mouseOver = xAxis >= 56 && xAxis <= 152 && yAxis >= yStart && yAxis <= yStart+29; - if(filter instanceof ItemStackFilter) + if(filter instanceof TItemStackFilter) { drawTexturedModalRect(guiWidth + 56, guiHeight + yStart, mouseOver ? 0 : 96, 166, 96, 29); } - else if(filter instanceof OreDictFilter) + else if(filter instanceof TOreDictFilter) { drawTexturedModalRect(guiWidth + 56, guiHeight + yStart, mouseOver ? 0 : 96, 195, 96, 29); } @@ -420,7 +420,7 @@ public class GuiLogisticalSorter extends GuiMekanism for(TransporterFilter filter : tileEntity.filters) { - if(filter instanceof ItemStackFilter) + if(filter instanceof TItemStackFilter) { list.add(filter); } @@ -435,7 +435,7 @@ public class GuiLogisticalSorter extends GuiMekanism for(TransporterFilter filter : tileEntity.filters) { - if(filter instanceof OreDictFilter) + if(filter instanceof TOreDictFilter) { list.add(filter); } @@ -444,7 +444,7 @@ public class GuiLogisticalSorter extends GuiMekanism return list; } - private void updateStackList(OreDictFilter filter) + private void updateStackList(TOreDictFilter filter) { if(!oreDictStacks.containsKey(filter)) { diff --git a/common/mekanism/client/gui/GuiOreDictFilter.java b/common/mekanism/client/gui/GuiOreDictFilter.java index 6e19333d1..48b5efcea 100644 --- a/common/mekanism/client/gui/GuiOreDictFilter.java +++ b/common/mekanism/client/gui/GuiOreDictFilter.java @@ -15,8 +15,8 @@ import mekanism.common.network.PacketLogisticalSorterGui; import mekanism.common.network.PacketLogisticalSorterGui.SorterGuiPacket; import mekanism.common.network.PacketNewFilter; import mekanism.common.tileentity.TileEntityLogisticalSorter; -import mekanism.common.transporter.ItemStackFilter; -import mekanism.common.transporter.OreDictFilter; +import mekanism.common.transporter.TItemStackFilter; +import mekanism.common.transporter.TOreDictFilter; import mekanism.common.util.MekanismUtils; import mekanism.common.util.MekanismUtils.ResourceType; import mekanism.common.util.TransporterUtils; @@ -36,9 +36,9 @@ public class GuiOreDictFilter extends GuiMekanism public boolean isNew = false; - public OreDictFilter origFilter; + public TOreDictFilter origFilter; - public OreDictFilter filter = new OreDictFilter(); + public TOreDictFilter filter = new TOreDictFilter(); private GuiTextField oreDictText; @@ -59,8 +59,8 @@ public class GuiOreDictFilter extends GuiMekanism super(new ContainerFilter(player.inventory)); tileEntity = tentity; - origFilter = (OreDictFilter)tileEntity.filters.get(index); - filter = ((OreDictFilter)tentity.filters.get(index)).clone(); + origFilter = (TOreDictFilter)tileEntity.filters.get(index); + filter = ((TOreDictFilter)tentity.filters.get(index)).clone(); updateStackList(filter.oreDictName); } diff --git a/common/mekanism/common/miner/MItemStackFilter.java b/common/mekanism/common/miner/MItemStackFilter.java new file mode 100644 index 000000000..17cebdfd5 --- /dev/null +++ b/common/mekanism/common/miner/MItemStackFilter.java @@ -0,0 +1,79 @@ +package mekanism.common.miner; + +import java.util.ArrayList; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import com.google.common.io.ByteArrayDataInput; + +public class MItemStackFilter extends MinerFilter +{ + public ItemStack itemType; + + @Override + public boolean canFilter(ItemStack itemStack) + { + if(itemStack == null) + { + return false; + } + + return itemType.isItemEqual(itemStack); + } + + @Override + public void write(NBTTagCompound nbtTags) + { + nbtTags.setInteger("type", 0); + itemType.writeToNBT(nbtTags); + } + + @Override + protected void read(NBTTagCompound nbtTags) + { + itemType = ItemStack.loadItemStackFromNBT(nbtTags); + } + + @Override + public void write(ArrayList data) + { + data.add(0); + + data.add(itemType.itemID); + data.add(itemType.stackSize); + data.add(itemType.getItemDamage()); + } + + @Override + protected void read(ByteArrayDataInput dataStream) + { + itemType = new ItemStack(dataStream.readInt(), dataStream.readInt(), dataStream.readInt()); + } + + @Override + public int hashCode() + { + int code = 1; + code = 31 * code + super.hashCode(); + code = 31 * code + itemType.itemID; + code = 31 * code + itemType.stackSize; + code = 31 * code + itemType.getItemDamage(); + return code; + } + + @Override + public boolean equals(Object filter) + { + return super.equals(filter) && filter instanceof MItemStackFilter && ((MItemStackFilter)filter).itemType.isItemEqual(itemType); + } + + @Override + public MItemStackFilter clone() + { + MItemStackFilter filter = new MItemStackFilter(); + filter.itemType = itemType.copy(); + + return filter; + } +} diff --git a/common/mekanism/common/miner/MOreDictFilter.java b/common/mekanism/common/miner/MOreDictFilter.java new file mode 100644 index 000000000..3a7f147f3 --- /dev/null +++ b/common/mekanism/common/miner/MOreDictFilter.java @@ -0,0 +1,103 @@ +package mekanism.common.miner; + +import java.util.ArrayList; + +import mekanism.common.util.MekanismUtils; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import com.google.common.io.ByteArrayDataInput; + +public class MOreDictFilter extends MinerFilter +{ + public String oreDictName; + + @Override + public boolean canFilter(ItemStack itemStack) + { + String oreKey = MekanismUtils.getOreDictName(itemStack); + + if(oreKey == null) + { + return false; + } + + if(oreDictName.equals(oreKey) || oreDictName.equals("*")) + { + return true; + } + else if(oreDictName.endsWith("*") && !oreDictName.startsWith("*")) + { + if(oreKey.startsWith(oreDictName.substring(0, oreDictName.length()-1))) + { + return true; + } + } + else if(oreDictName.startsWith("*") && !oreDictName.endsWith("*")) + { + if(oreKey.endsWith(oreDictName.substring(1))) + { + return true; + } + } + else if(oreDictName.startsWith("*") && oreDictName.endsWith("*")) + { + if(oreKey.contains(oreDictName.substring(1, oreDictName.length()-1))) + { + return true; + } + } + + return false; + } + + @Override + public void write(NBTTagCompound nbtTags) + { + nbtTags.setInteger("type", 1); + nbtTags.setString("oreDictName", oreDictName); + } + + @Override + protected void read(NBTTagCompound nbtTags) + { + oreDictName = nbtTags.getString("oreDictName"); + } + + @Override + public void write(ArrayList data) + { + data.add(1); + data.add(oreDictName); + } + + @Override + protected void read(ByteArrayDataInput dataStream) + { + oreDictName = dataStream.readUTF(); + } + + @Override + public int hashCode() + { + int code = 1; + code = 31 * code + super.hashCode(); + code = 31 * code + oreDictName.hashCode(); + return code; + } + + @Override + public boolean equals(Object filter) + { + return super.equals(filter) && filter instanceof MOreDictFilter && ((MOreDictFilter)filter).oreDictName.equals(oreDictName); + } + + @Override + public MOreDictFilter clone() + { + MOreDictFilter filter = new MOreDictFilter(); + filter.oreDictName = oreDictName; + + return filter; + } +} diff --git a/common/mekanism/common/miner/MinerFilter.java b/common/mekanism/common/miner/MinerFilter.java new file mode 100644 index 000000000..ff4bed622 --- /dev/null +++ b/common/mekanism/common/miner/MinerFilter.java @@ -0,0 +1,66 @@ +package mekanism.common.miner; + +import java.util.ArrayList; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import com.google.common.io.ByteArrayDataInput; + +public abstract class MinerFilter +{ + public abstract boolean canFilter(ItemStack itemStack); + + public abstract void write(NBTTagCompound nbtTags); + + protected abstract void read(NBTTagCompound nbtTags); + + public abstract void write(ArrayList data); + + protected abstract void read(ByteArrayDataInput dataStream); + + public static MinerFilter readFromNBT(NBTTagCompound nbtTags) + { + int type = nbtTags.getInteger("type"); + + MinerFilter filter = null; + + if(type == 0) + { + filter = new MItemStackFilter(); + } + else { + filter = new MOreDictFilter(); + } + + filter.read(nbtTags); + + return filter; + } + + public static MinerFilter readFromPacket(ByteArrayDataInput dataStream) + { + int type = dataStream.readInt(); + + MinerFilter filter = null; + + if(type == 0) + { + filter = new MItemStackFilter(); + } + else if(type == 1) + { + filter = new MOreDictFilter(); + } + + filter.read(dataStream); + + return filter; + } + + @Override + public boolean equals(Object filter) + { + return filter instanceof MinerFilter; + } +} diff --git a/common/mekanism/common/miner/ThreadMinerSearch.java b/common/mekanism/common/miner/ThreadMinerSearch.java new file mode 100644 index 000000000..20707c955 --- /dev/null +++ b/common/mekanism/common/miner/ThreadMinerSearch.java @@ -0,0 +1,10 @@ +package mekanism.common.miner; + +public class ThreadMinerSearch extends Thread +{ + @Override + public void run() + { + + } +} diff --git a/common/mekanism/common/tileentity/TileEntityDigitalMiner.java b/common/mekanism/common/tileentity/TileEntityDigitalMiner.java index a78c70c05..6b173d165 100644 --- a/common/mekanism/common/tileentity/TileEntityDigitalMiner.java +++ b/common/mekanism/common/tileentity/TileEntityDigitalMiner.java @@ -3,18 +3,27 @@ package mekanism.common.tileentity; import ic2.api.energy.tile.IEnergySink; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; import mekanism.api.Object3D; import mekanism.api.energy.IStrictEnergyAcceptor; +import mekanism.common.HashList; import mekanism.common.IRedstoneControl; import mekanism.common.IUpgradeTile; import mekanism.common.Mekanism; +import mekanism.common.PacketHandler; +import mekanism.common.PacketHandler.Transmission; import mekanism.common.TileComponentUpgrade; import mekanism.common.block.BlockMachine.MachineType; +import mekanism.common.miner.MinerFilter; +import mekanism.common.miner.ThreadMinerSearch; +import mekanism.common.network.PacketTileEntity; import mekanism.common.util.ChargeUtils; import mekanism.common.util.MekanismUtils; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.ForgeDirection; @@ -22,8 +31,22 @@ import com.google.common.io.ByteArrayDataInput; public class TileEntityDigitalMiner extends TileEntityElectricBlock implements IEnergySink, IStrictEnergyAcceptor, IUpgradeTile, IRedstoneControl { + public Set oresToMine = new HashSet(); + + public HashList filters = new HashList(); + public int radius; + public int minY; + public int maxY; + + public boolean doEject = false; + public boolean doPull = false; + + public ThreadMinerSearch searcher; + + public int clientToMine; + /** This machine's current RedstoneControl type. */ public RedstoneControl controlType = RedstoneControl.DISABLED; @@ -53,7 +76,21 @@ public class TileEntityDigitalMiner extends TileEntityElectricBlock implements I super.readFromNBT(nbtTags); radius = nbtTags.getInteger("radius"); + minY = nbtTags.getInteger("minY"); + maxY = nbtTags.getInteger("maxY"); + doEject = nbtTags.getBoolean("doEject"); + doPull = nbtTags.getBoolean("doPull"); controlType = RedstoneControl.values()[nbtTags.getInteger("controlType")]; + + if(nbtTags.hasKey("filters")) + { + NBTTagList tagList = nbtTags.getTagList("filters"); + + for(int i = 0; i < tagList.tagCount(); i++) + { + filters.add(MinerFilter.readFromNBT((NBTTagCompound)tagList.tagAt(i))); + } + } } @Override @@ -62,7 +99,37 @@ public class TileEntityDigitalMiner extends TileEntityElectricBlock implements I super.writeToNBT(nbtTags); nbtTags.setInteger("radius", radius); + nbtTags.setInteger("minY", minY); + nbtTags.setInteger("maxY", maxY); + nbtTags.setBoolean("doEject", doEject); + nbtTags.setBoolean("doPull", doPull); nbtTags.setInteger("controlType", controlType.ordinal()); + + NBTTagList filterTags = new NBTTagList(); + + for(MinerFilter filter : filters) + { + NBTTagCompound tagCompound = new NBTTagCompound(); + filter.write(new NBTTagCompound()); + filterTags.appendTag(tagCompound); + } + + if(filterTags.tagCount() != 0) + { + nbtTags.setTag("filters", filterTags); + } + + NBTTagList miningOres = new NBTTagList(); + + for(Object3D obj : oresToMine) + { + miningOres.appendTag(obj.write(new NBTTagCompound())); + } + + if(miningOres.tagCount() != 0) + { + nbtTags.setTag("oresToMine", miningOres); + } } @Override @@ -70,8 +137,29 @@ public class TileEntityDigitalMiner extends TileEntityElectricBlock implements I { super.handlePacketData(dataStream); - radius = dataStream.readInt(); - controlType = RedstoneControl.values()[dataStream.readInt()]; + int type = dataStream.readInt(); + + if(type == 0) + { + radius = dataStream.readInt(); + minY = dataStream.readInt(); + maxY = dataStream.readInt(); + doEject = dataStream.readBoolean(); + doPull = dataStream.readBoolean(); + clientToMine = dataStream.readInt(); + controlType = RedstoneControl.values()[dataStream.readInt()]; + } + else if(type == 1) + { + filters.clear(); + + int amount = dataStream.readInt(); + + for(int i = 0; i < amount; i++) + { + filters.add(MinerFilter.readFromPacket(dataStream)); + } + } } @Override @@ -79,11 +167,42 @@ public class TileEntityDigitalMiner extends TileEntityElectricBlock implements I { super.getNetworkedData(data); + data.add(0); data.add(radius); + data.add(minY); + data.add(maxY); + data.add(doEject); + data.add(doPull); + data.add(oresToMine.size()); data.add(controlType.ordinal()); return data; } + + @Override + public void openChest() + { + if(!worldObj.isRemote) + { + PacketHandler.sendPacket(Transmission.CLIENTS_RANGE, new PacketTileEntity().setParams(Object3D.get(this), getFilterPacket(new ArrayList())), Object3D.get(this), 50D); + } + } + + public ArrayList getFilterPacket(ArrayList data) + { + super.getNetworkedData(data); + + data.add(1); + + data.add(filters.size()); + + for(MinerFilter filter : filters) + { + filter.write(data); + } + + return data; + } @Override public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction) @@ -145,6 +264,12 @@ public class TileEntityDigitalMiner extends TileEntityElectricBlock implements I return rejects; } + @Override + public double getMaxEnergy() + { + return MekanismUtils.getEnergy(getEnergyMultiplier(), MAX_ELECTRICITY); + } + @Override public boolean canReceiveEnergy(ForgeDirection side) { diff --git a/common/mekanism/common/tileentity/TileEntityElectricPump.java b/common/mekanism/common/tileentity/TileEntityElectricPump.java index aa960d7b9..f0666319d 100644 --- a/common/mekanism/common/tileentity/TileEntityElectricPump.java +++ b/common/mekanism/common/tileentity/TileEntityElectricPump.java @@ -342,11 +342,9 @@ public class TileEntityElectricPump extends TileEntityElectricBlock implements I NBTTagList cleaningList = new NBTTagList(); - for(Object3D wrapper : cleaningNodes) + for(Object3D obj : cleaningNodes) { - NBTTagCompound tagCompound = new NBTTagCompound(); - wrapper.write(tagCompound); - cleaningList.appendTag(tagCompound); + cleaningList.appendTag(obj.write(new NBTTagCompound())); } if(cleaningList.tagCount() != 0) diff --git a/common/mekanism/common/transporter/ItemStackFilter.java b/common/mekanism/common/transporter/TItemStackFilter.java similarity index 86% rename from common/mekanism/common/transporter/ItemStackFilter.java rename to common/mekanism/common/transporter/TItemStackFilter.java index 933d1e101..62df4912a 100644 --- a/common/mekanism/common/transporter/ItemStackFilter.java +++ b/common/mekanism/common/transporter/TItemStackFilter.java @@ -10,7 +10,7 @@ import net.minecraftforge.common.ForgeDirection; import com.google.common.io.ByteArrayDataInput; -public class ItemStackFilter extends TransporterFilter +public class TItemStackFilter extends TransporterFilter { public boolean sizeMode; @@ -116,14 +116,14 @@ public class ItemStackFilter extends TransporterFilter @Override public boolean equals(Object filter) { - return super.equals(filter) && filter instanceof ItemStackFilter && ((ItemStackFilter)filter).itemType.isItemEqual(itemType) - && ((ItemStackFilter)filter).sizeMode == sizeMode && ((ItemStackFilter)filter).min == min && ((ItemStackFilter)filter).max == max; + return super.equals(filter) && filter instanceof TItemStackFilter && ((TItemStackFilter)filter).itemType.isItemEqual(itemType) + && ((TItemStackFilter)filter).sizeMode == sizeMode && ((TItemStackFilter)filter).min == min && ((TItemStackFilter)filter).max == max; } @Override - public ItemStackFilter clone() + public TItemStackFilter clone() { - ItemStackFilter filter = new ItemStackFilter(); + TItemStackFilter filter = new TItemStackFilter(); filter.color = color; filter.itemType = itemType.copy(); filter.sizeMode = sizeMode; diff --git a/common/mekanism/common/transporter/OreDictFilter.java b/common/mekanism/common/transporter/TOreDictFilter.java similarity index 89% rename from common/mekanism/common/transporter/OreDictFilter.java rename to common/mekanism/common/transporter/TOreDictFilter.java index db94d25e8..de7553c2f 100644 --- a/common/mekanism/common/transporter/OreDictFilter.java +++ b/common/mekanism/common/transporter/TOreDictFilter.java @@ -11,7 +11,7 @@ import net.minecraftforge.common.ForgeDirection; import com.google.common.io.ByteArrayDataInput; -public class OreDictFilter extends TransporterFilter +public class TOreDictFilter extends TransporterFilter { public String oreDictName; @@ -107,13 +107,13 @@ public class OreDictFilter extends TransporterFilter @Override public boolean equals(Object filter) { - return super.equals(filter) && filter instanceof OreDictFilter && ((OreDictFilter)filter).oreDictName.equals(oreDictName); + return super.equals(filter) && filter instanceof TOreDictFilter && ((TOreDictFilter)filter).oreDictName.equals(oreDictName); } @Override - public OreDictFilter clone() + public TOreDictFilter clone() { - OreDictFilter filter = new OreDictFilter(); + TOreDictFilter filter = new TOreDictFilter(); filter.color = color; filter.oreDictName = oreDictName; diff --git a/common/mekanism/common/transporter/TransporterFilter.java b/common/mekanism/common/transporter/TransporterFilter.java index 083bf2693..b4295abde 100644 --- a/common/mekanism/common/transporter/TransporterFilter.java +++ b/common/mekanism/common/transporter/TransporterFilter.java @@ -67,10 +67,10 @@ public abstract class TransporterFilter if(type == 0) { - filter = new ItemStackFilter(); + filter = new TItemStackFilter(); } else { - filter = new OreDictFilter(); + filter = new TOreDictFilter(); } filter.read(nbtTags); @@ -86,11 +86,11 @@ public abstract class TransporterFilter if(type == 0) { - filter = new ItemStackFilter(); + filter = new TItemStackFilter(); } else if(type == 1) { - filter = new OreDictFilter(); + filter = new TOreDictFilter(); } filter.read(dataStream); diff --git a/resources/assets/mekanism/gui/GuiDigitalMiner.png b/resources/assets/mekanism/gui/GuiDigitalMiner.png new file mode 100644 index 0000000000000000000000000000000000000000..943558d24fb62490450454473237aa6bc9c84851 GIT binary patch literal 5231 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 literal 0 HcmV?d00001 diff --git a/resources/assets/mekanism/gui/GuiDigitalMinerConfig.png b/resources/assets/mekanism/gui/GuiDigitalMinerConfig.png new file mode 100644 index 0000000000000000000000000000000000000000..56efb5e5d19ec83bf8857581bc5608a53b56382c GIT binary patch literal 3888 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