diff --git a/build.gradle b/build.gradle index caa86a3d6..7def66913 100755 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: 'net.minecraftforge.gradle.forge' -version = "1.6.5" +version = "1.6.6" def env = System.getenv() if (env.BUILD_NUMBER) { version = version + "-" + "${env.BUILD_NUMBER}" diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java index e54bab1d4..ca58dec09 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -88,4 +88,17 @@ public interface ICraftingPatternContainer { * @return the UUID of this container */ UUID getUuid(); + + /** + * @return true if the connected inventory is locked for processing patterns, false otherwise + */ + default boolean isLocked() { + return false; + } + + /** + * Called when this container is used by a processing pattern to insert items or fluids in the connected inventory. + */ + default void onUsedForProcessing() { + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java index 9368a2558..a375a2c0d 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java @@ -641,72 +641,78 @@ public class CraftingTask implements ICraftingTask { if (ticks % getTickInterval(p.getPattern().getContainer().getSpeedUpgradeCount()) == 0) { ProcessingState originalState = p.getState(); - boolean hasAll = true; + if (p.getPattern().getContainer().isLocked()) { + p.setState(ProcessingState.LOCKED); + } else { + boolean hasAll = true; - for (ItemStack need : p.getItemsToPut()) { - if (p.getPattern().getContainer().getConnectedInventory() == null) { - p.setState(ProcessingState.MACHINE_NONE); - } else { - ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.SIMULATE); - - if (result == null || result.getCount() != need.getCount()) { - hasAll = false; - - break; - } else if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, true).isEmpty()) { - p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT); - - break; - } else { - p.setState(ProcessingState.READY); - } - } - } - - for (FluidStack need : p.getFluidsToPut()) { - if (p.getPattern().getContainer().getConnectedFluidInventory() == null) { - p.setState(ProcessingState.MACHINE_NONE); - } else { - FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.SIMULATE); - - if (result == null || result.amount != need.amount) { - hasAll = false; - - break; - } else if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, false) != result.amount) { - p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT); - - break; - } else if (p.getState() == ProcessingState.READY) { // If the items were ok. - p.setState(ProcessingState.READY); - } - } - } - - if (p.getState() == ProcessingState.READY && hasAll) { for (ItemStack need : p.getItemsToPut()) { - ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.PERFORM); - if (result == null || result.getCount() != need.getCount()) { - throw new IllegalStateException("Could not extract from the internal inventory even though we could"); - } + if (p.getPattern().getContainer().getConnectedInventory() == null) { + p.setState(ProcessingState.MACHINE_NONE); + } else { + ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.SIMULATE); - if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, false).isEmpty()) { - throw new IllegalStateException("Can't fill up inventory even though we could"); + if (result == null || result.getCount() != need.getCount()) { + hasAll = false; + + break; + } else if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, true).isEmpty()) { + p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT); + + break; + } else { + p.setState(ProcessingState.READY); + } } } for (FluidStack need : p.getFluidsToPut()) { - FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.PERFORM); - if (result == null || result.amount != need.amount) { - throw new IllegalStateException("Could not extract from the internal inventory even though we could"); - } + if (p.getPattern().getContainer().getConnectedFluidInventory() == null) { + p.setState(ProcessingState.MACHINE_NONE); + } else { + FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.SIMULATE); - if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, true) != result.amount) { - throw new IllegalStateException("Can't fill up inventory even though we could"); + if (result == null || result.amount != need.amount) { + hasAll = false; + + break; + } else if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, false) != result.amount) { + p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT); + + break; + } else if (p.getState() == ProcessingState.READY) { // If the items were ok. + p.setState(ProcessingState.READY); + } } } - p.setState(ProcessingState.EXTRACTED_ALL); + if (p.getState() == ProcessingState.READY && hasAll) { + for (ItemStack need : p.getItemsToPut()) { + ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.PERFORM); + if (result == null || result.getCount() != need.getCount()) { + throw new IllegalStateException("Could not extract from the internal inventory even though we could"); + } + + if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, false).isEmpty()) { + throw new IllegalStateException("Can't fill up inventory even though we could"); + } + } + + for (FluidStack need : p.getFluidsToPut()) { + FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.PERFORM); + if (result == null || result.amount != need.amount) { + throw new IllegalStateException("Could not extract from the internal inventory even though we could"); + } + + if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, true) != result.amount) { + throw new IllegalStateException("Can't fill up inventory even though we could"); + } + } + + p.setState(ProcessingState.EXTRACTED_ALL); + + p.getPattern().getContainer().onUsedForProcessing(); + } } if (originalState != p.getState()) { @@ -959,7 +965,7 @@ public class CraftingTask implements ICraftingTask { for (ItemStack put : processing.getItemsToPut()) { elements.add(new CraftingMonitorElementItemRender(put, 0, 0, put.getCount(), 0, 0)); } - } else if (processing.getState() == ProcessingState.READY || processing.getState() == ProcessingState.MACHINE_DOES_NOT_ACCEPT || processing.getState() == ProcessingState.MACHINE_NONE) { + } else if (processing.getState() == ProcessingState.READY || processing.getState() == ProcessingState.MACHINE_DOES_NOT_ACCEPT || processing.getState() == ProcessingState.MACHINE_NONE || processing.getState() == ProcessingState.LOCKED) { for (ItemStack receive : processing.getItemsToReceive().getStacks()) { ICraftingMonitorElement element = new CraftingMonitorElementItemRender(receive, 0, 0, 0, receive.getCount(), 0); @@ -967,6 +973,8 @@ public class CraftingTask implements ICraftingTask { element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.machine_does_not_accept_item"); } else if (processing.getState() == ProcessingState.MACHINE_NONE) { element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.machine_none"); + } else if (processing.getState() == ProcessingState.LOCKED) { + element = new CraftingMonitorElementError(element, "gui.refinedstorage:crafting_monitor.crafter_is_locked"); } elements.add(element); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java index 023938a42..bec94ee3c 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java @@ -5,5 +5,6 @@ enum ProcessingState { EXTRACTED_ALL, MACHINE_NONE, MACHINE_DOES_NOT_ACCEPT, - PROCESSED + PROCESSED, + LOCKED } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java index 673568a3f..6245413ba 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java @@ -30,20 +30,38 @@ import java.util.List; import java.util.UUID; public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternContainer { + public enum CrafterMode { + IGNORE, + SIGNAL_UNLOCKS_AUTOCRAFTING, + SIGNAL_LOCKS_AUTOCRAFTING, + PULSE_INSERTS_NEXT_SET; + + public static CrafterMode getById(int id) { + if (id >= 0 && id < values().length) { + return values()[id]; + } + + return IGNORE; + } + } + public static final String ID = "crafter"; public static final String DEFAULT_NAME = "gui.refinedstorage:crafter"; private static final String NBT_DISPLAY_NAME = "DisplayName"; private static final String NBT_UUID = "CrafterUuid"; + private static final String NBT_MODE = "Mode"; + private static final String NBT_LOCKED = "Locked"; + private static final String NBT_WAS_POWERED = "WasPowered"; - private ItemHandlerBase patterns = new ItemHandlerBase(9, new ListenerNetworkNode(this), s -> isValidPatternInSlot(world, s)) { + private ItemHandlerBase patternsInventory = new ItemHandlerBase(9, new ListenerNetworkNode(this), s -> isValidPatternInSlot(world, s)) { @Override protected void onContentsChanged(int slot) { super.onContentsChanged(slot); if (!world.isRemote) { - rebuildPatterns(); + invalidate(); } if (network != null) { @@ -61,13 +79,17 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC return stack.getItem() instanceof ICraftingPatternProvider && ((ICraftingPatternProvider) stack.getItem()).create(world, stack, null).isValid(); } - private List actualPatterns = new ArrayList<>(); + private List patterns = new ArrayList<>(); private ItemHandlerUpgrade upgrades = new ItemHandlerUpgrade(4, new ListenerNetworkNode(this), ItemUpgrade.TYPE_SPEED); // Used to prevent infinite recursion on getRootContainer() when there's e.g. two crafters facing each other. private boolean visited = false; + private CrafterMode mode = CrafterMode.IGNORE; + private boolean locked = false; + private boolean wasPowered; + @Nullable private String displayName; @@ -78,17 +100,17 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC super(world, pos); } - private void rebuildPatterns() { - actualPatterns.clear(); + private void invalidate() { + patterns.clear(); - for (int i = 0; i < patterns.getSlots(); ++i) { - ItemStack patternStack = patterns.getStackInSlot(i); + for (int i = 0; i < patternsInventory.getSlots(); ++i) { + ItemStack patternStack = patternsInventory.getStackInSlot(i); if (!patternStack.isEmpty()) { ICraftingPattern pattern = ((ICraftingPatternProvider) patternStack.getItem()).create(world, patternStack, this); if (pattern.isValid()) { - actualPatterns.add(pattern); + patterns.add(pattern); } } } @@ -96,7 +118,7 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC @Override public int getEnergyUsage() { - return RS.INSTANCE.config.crafterUsage + upgrades.getEnergyUsage() + (RS.INSTANCE.config.crafterPerPatternUsage * actualPatterns.size()); + return RS.INSTANCE.config.crafterUsage + upgrades.getEnergyUsage() + (RS.INSTANCE.config.crafterPerPatternUsage * patterns.size()); } @Override @@ -104,7 +126,20 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC super.update(); if (ticks == 1) { - rebuildPatterns(); + invalidate(); + } + + if (mode == CrafterMode.PULSE_INSERTS_NEXT_SET) { + if (world.isBlockPowered(pos)) { + this.wasPowered = true; + + markDirty(); + } else if (wasPowered) { + this.wasPowered = false; + this.locked = false; + + markDirty(); + } } } @@ -132,9 +167,9 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC public void read(NBTTagCompound tag) { super.read(tag); - StackUtils.readItems(patterns, 0, tag); + StackUtils.readItems(patternsInventory, 0, tag); - if (API.instance().getOneSixMigrationHelper().migratePatternInventory(patterns)) { + if (API.instance().getOneSixMigrationHelper().migratePatternInventory(patternsInventory)) { markDirty(); } @@ -147,6 +182,18 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC if (tag.hasUniqueId(NBT_UUID)) { uuid = tag.getUniqueId(NBT_UUID); } + + if (tag.hasKey(NBT_MODE)) { + mode = CrafterMode.getById(tag.getInteger(NBT_MODE)); + } + + if (tag.hasKey(NBT_LOCKED)) { + locked = tag.getBoolean(NBT_LOCKED); + } + + if (tag.hasKey(NBT_WAS_POWERED)) { + wasPowered = tag.getBoolean(NBT_WAS_POWERED); + } } @Override @@ -158,7 +205,7 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC public NBTTagCompound write(NBTTagCompound tag) { super.write(tag); - StackUtils.writeItems(patterns, 0, tag); + StackUtils.writeItems(patternsInventory, 0, tag); StackUtils.writeItems(upgrades, 1, tag); if (displayName != null) { @@ -169,6 +216,10 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC tag.setUniqueId(NBT_UUID, uuid); } + tag.setInteger(NBT_MODE, mode.ordinal()); + tag.setBoolean(NBT_LOCKED, locked); + tag.setBoolean(NBT_WAS_POWERED, wasPowered); + return tag; } @@ -212,13 +263,13 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC @Override public List getPatterns() { - return actualPatterns; + return patterns; } @Override @Nullable public IItemHandlerModifiable getPatternInventory() { - return patterns; + return patternsInventory; } @Override @@ -254,8 +305,20 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC return pos; } + public CrafterMode getMode() { + return mode; + } + + public void setMode(CrafterMode mode) { + this.mode = mode; + this.wasPowered = false; + this.locked = false; + + this.markDirty(); + } + public IItemHandler getPatternItems() { - return patterns; + return patternsInventory; } public IItemHandler getUpgrades() { @@ -264,7 +327,7 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC @Override public IItemHandler getDrops() { - return new CombinedInvWrapper(patterns, upgrades); + return new CombinedInvWrapper(patternsInventory, upgrades); } @Override @@ -293,11 +356,37 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC @Override public UUID getUuid() { - if (uuid == null) { - uuid = UUID.randomUUID(); + if (this.uuid == null) { + this.uuid = UUID.randomUUID(); + markDirty(); } return uuid; } + + @Override + public boolean isLocked() { + switch (mode) { + case IGNORE: + return false; + case SIGNAL_LOCKS_AUTOCRAFTING: + return world.isBlockPowered(pos); + case SIGNAL_UNLOCKS_AUTOCRAFTING: + return !world.isBlockPowered(pos); + case PULSE_INSERTS_NEXT_SET: + return locked; + default: + return false; + } + } + + @Override + public void onUsedForProcessing() { + if (mode == CrafterMode.PULSE_INSERTS_NEXT_SET) { + this.locked = true; + + markDirty(); + } + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCrafter.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCrafter.java index 57b65bca2..21e41c181 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCrafter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCrafter.java @@ -1,7 +1,7 @@ package com.raoulvdberge.refinedstorage.gui; import com.raoulvdberge.refinedstorage.container.ContainerCrafter; -import com.raoulvdberge.refinedstorage.gui.control.SideButtonRedstoneMode; +import com.raoulvdberge.refinedstorage.gui.control.SideButtonCrafterMode; import com.raoulvdberge.refinedstorage.tile.TileCrafter; import com.raoulvdberge.refinedstorage.util.RenderUtils; @@ -12,7 +12,7 @@ public class GuiCrafter extends GuiBase { @Override public void init(int x, int y) { - addSideButton(new SideButtonRedstoneMode(this, TileCrafter.REDSTONE_MODE)); + addSideButton(new SideButtonCrafterMode(this)); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/control/SideButtonCrafterMode.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/control/SideButtonCrafterMode.java new file mode 100644 index 000000000..a56289070 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/control/SideButtonCrafterMode.java @@ -0,0 +1,27 @@ +package com.raoulvdberge.refinedstorage.gui.control; + +import com.raoulvdberge.refinedstorage.gui.GuiBase; +import com.raoulvdberge.refinedstorage.tile.TileCrafter; +import com.raoulvdberge.refinedstorage.tile.data.TileDataManager; +import net.minecraft.util.text.TextFormatting; + +public class SideButtonCrafterMode extends SideButton { + public SideButtonCrafterMode(GuiBase gui) { + super(gui); + } + + @Override + public String getTooltip() { + return GuiBase.t("sidebutton.refinedstorage:crafter_mode") + "\n" + TextFormatting.GRAY + GuiBase.t("sidebutton.refinedstorage:crafter_mode." + TileCrafter.MODE.getValue()); + } + + @Override + protected void drawButtonIcon(int x, int y) { + gui.drawTexture(x, y, TileCrafter.MODE.getValue() * 16, 0, 16, 16); + } + + @Override + public void actionPerformed() { + TileDataManager.setParameter(TileCrafter.MODE, TileCrafter.MODE.getValue() + 1); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileCrafter.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileCrafter.java index 84ed7ae59..1b0526f79 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileCrafter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileCrafter.java @@ -14,9 +14,11 @@ import javax.annotation.Nullable; public class TileCrafter extends TileNode { public static final TileDataParameter NAME = new TileDataParameter<>(DataSerializers.STRING, NetworkNodeCrafter.DEFAULT_NAME, t -> t.getNode().getName()); + public static final TileDataParameter MODE = new TileDataParameter<>(DataSerializers.VARINT, NetworkNodeCrafter.CrafterMode.IGNORE.ordinal(), t -> t.getNode().getMode().ordinal(), (t, v) -> t.getNode().setMode(NetworkNodeCrafter.CrafterMode.getById(v))); public TileCrafter() { dataManager.addWatchedParameter(NAME); + dataManager.addWatchedParameter(MODE); } @Override diff --git a/src/main/resources/assets/refinedstorage/lang/en_us.lang b/src/main/resources/assets/refinedstorage/lang/en_us.lang index c8397754a..b5006f071 100644 --- a/src/main/resources/assets/refinedstorage/lang/en_us.lang +++ b/src/main/resources/assets/refinedstorage/lang/en_us.lang @@ -36,6 +36,7 @@ gui.refinedstorage:crafting_monitor.crafting=Crafting: %d gui.refinedstorage:crafting_monitor.machine_does_not_accept_item=Machine doesn't accept item gui.refinedstorage:crafting_monitor.machine_does_not_accept_fluid=Machine doesn't accept fluid gui.refinedstorage:crafting_monitor.machine_none=No machine found +gui.refinedstorage:crafting_monitor.crafter_is_locked=Crafter is locked gui.refinedstorage:wireless_transmitter=Wireless Transmitter gui.refinedstorage:wireless_transmitter.distance=%d block(s) gui.refinedstorage:crafter=Crafter @@ -141,6 +142,12 @@ sidebutton.refinedstorage:redstone_mode.0=Ignore redstone signal sidebutton.refinedstorage:redstone_mode.1=Only work with redstone signal sidebutton.refinedstorage:redstone_mode.2=Only work without redstone signal +sidebutton.refinedstorage:crafter_mode=Crafter mode +sidebutton.refinedstorage:crafter_mode.0=Ignore redstone signal +sidebutton.refinedstorage:crafter_mode.1=Redstone signal unlocks autocrafting +sidebutton.refinedstorage:crafter_mode.2=Redstone signal locks autocrafting +sidebutton.refinedstorage:crafter_mode.3=Redstone pulse inserts next set + sidebutton.refinedstorage:grid.view_type=Display sidebutton.refinedstorage:grid.view_type.0=Normal sidebutton.refinedstorage:grid.view_type.1=No craftables diff --git a/src/main/resources/assets/refinedstorage/textures/icons.png b/src/main/resources/assets/refinedstorage/textures/icons.png index 87b468253..f20aee70c 100755 Binary files a/src/main/resources/assets/refinedstorage/textures/icons.png and b/src/main/resources/assets/refinedstorage/textures/icons.png differ