diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ffa8e6f4..cf0af4760 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ NOTE: Worlds that used Refined Storage 1.5.x are fully compatible with Refined S - If an Interface is configured to expose the entire network storage (by configuring no export slots), it will no longer expose the entire RS storage, due to performance issues (raoulvdberge) - The Portable Grid no longer exposes a inventory for crossmod interaction, due to performance issues (raoulvdberge) - The Crafting Monitor is now resizable and its size can be configured (stretched, small, medium, large) (raoulvdberge) +- The Crafting Monitor now splits its tasks over tabs (raoulvdberge) - Made all IO blocks have a blacklist instead of a whitelist by default (raoulvdberge) - An empty blacklist now means: accept any item. An empty whitelist now means: don't accept any item (an empty whitelist USED to mean: accept any item) (raoulvdberge) - Any mod can now add JSON Solderer recipes without requiring the API, by putting the JSONs in their assets directory in a "solderer_recipes" directory (raoulvdberge) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java index a45d8a61b..ece082270 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java @@ -8,17 +8,19 @@ import net.minecraftforge.items.IItemHandlerModifiable; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.UUID; /** * The crafting manager handles the storing, updating, adding and deleting of crafting tasks in a network. */ public interface ICraftingManager { /** - * @return the crafting tasks in this network, do NOT modify this list + * @return the crafting tasks in this network, do NOT modify this */ - List getTasks(); + Collection getTasks(); /** * @return named crafting pattern containers @@ -35,9 +37,9 @@ public interface ICraftingManager { /** * Cancels a crafting task. * - * @param task the task to cancel + * @param id the id of the task to cancel, or null to cancel all */ - void cancel(@Nonnull ICraftingTask task); + void cancel(@Nullable UUID id); /** * Creates a crafting task for a given stack. diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/craftingmonitor/ICraftingMonitorElement.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/craftingmonitor/ICraftingMonitorElement.java index adc6d14c3..a41afbc40 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/craftingmonitor/ICraftingMonitorElement.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/craftingmonitor/ICraftingMonitorElement.java @@ -20,14 +20,6 @@ public interface ICraftingMonitorElement { @SideOnly(Side.CLIENT) void draw(int x, int y, IElementDrawers drawers, boolean selected); - /** - * Returns the position of the corresponding task in the crafting task list. - * Used for cancelling tasks. - * - * @return the id, or -1 if no task is associated with this element - */ - int getTaskId(); - /** * Returns the id of this element, used for serialization and deserialization over the network. * diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java index 5aa43aed8..c5e7d8d42 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java @@ -9,6 +9,7 @@ import net.minecraft.nbt.NBTTagCompound; import javax.annotation.Nullable; import java.util.List; +import java.util.UUID; /** * Represents a crafting task. @@ -92,4 +93,9 @@ public interface ICraftingTask { * @return the missing items */ IStackList getMissing(); + + /** + * @return the id of this task + */ + UUID getId(); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/handler/IItemGridHandler.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/handler/IItemGridHandler.java index 0719fac39..2ef5dcc5d 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/handler/IItemGridHandler.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/handler/IItemGridHandler.java @@ -5,6 +5,7 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import javax.annotation.Nullable; +import java.util.UUID; /** * Defines the behavior of item grids. @@ -73,7 +74,7 @@ public interface IItemGridHandler { * Called when a player wants to cancel a crafting task. * * @param player the player that requested the cancel - * @param id the task id, or -1 to cancel all tasks that are in the network currently + * @param id the task id, or null to cancel all tasks that are in the network currently */ - void onCraftingCancelRequested(EntityPlayerMP player, int id); + void onCraftingCancelRequested(EntityPlayerMP player, @Nullable UUID id); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java index 47a74cf83..bf8e02175 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java @@ -26,9 +26,9 @@ public class CraftingManager implements ICraftingManager { private List patterns = new ArrayList<>(); - private List tasks = new ArrayList<>(); + private Map tasks = new LinkedHashMap<>(); private List tasksToAdd = new ArrayList<>(); - private List tasksToCancel = new ArrayList<>(); + private List tasksToCancel = new ArrayList<>(); private Set listeners = new HashSet<>(); @@ -37,8 +37,8 @@ public class CraftingManager implements ICraftingManager { } @Override - public List getTasks() { - return tasks; + public Collection getTasks() { + return tasks.values(); } @Override @@ -54,8 +54,12 @@ public class CraftingManager implements ICraftingManager { } @Override - public void cancel(@Nonnull ICraftingTask task) { - tasksToCancel.add(task); + public void cancel(@Nullable UUID id) { + if (id == null) { + tasksToCancel.addAll(tasks.keySet()); + } else { + tasksToCancel.add(id); + } network.markDirty(); } @@ -86,14 +90,24 @@ public class CraftingManager implements ICraftingManager { if (network.canRun()) { boolean changed = !tasksToCancel.isEmpty() || !tasksToAdd.isEmpty(); - this.tasksToCancel.forEach(ICraftingTask::onCancelled); - this.tasks.removeAll(tasksToCancel); + for (UUID idToCancel : tasksToCancel) { + this.tasks.get(idToCancel).onCancelled(); + this.tasks.remove(idToCancel); + } this.tasksToCancel.clear(); - this.tasksToAdd.stream().filter(ICraftingTask::isValid).forEach(tasks::add); + this.tasksToAdd.stream().filter(ICraftingTask::isValid).forEach(t -> tasks.put(t.getId(), t)); this.tasksToAdd.clear(); - boolean anyFinished = tasks.removeIf(ICraftingTask::update); + boolean anyFinished = false; + + for (ICraftingTask task : tasks.values()) { + if (task.update()) { + anyFinished = true; + + tasks.remove(task.getId()); + } + } if (changed || anyFinished) { onTaskChanged(); @@ -101,13 +115,11 @@ public class CraftingManager implements ICraftingManager { } } - @Override - // TODO + @Override // TODO public void readFromNBT(NBTTagCompound tag) { } - @Override - // TODO + @Override // TODO public NBTTagCompound writeToNBT(NBTTagCompound tag) { return tag; } @@ -161,7 +173,7 @@ public class CraftingManager implements ICraftingManager { public void track(ItemStack stack, int size) { int initialSize = size; - for (ICraftingTask task : tasks) { + for (ICraftingTask task : tasks.values()) { size = task.onTrackedItemInserted(stack, size); if (size == 0) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementColor.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementColor.java index c2735fd0c..cad5a6e26 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementColor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementColor.java @@ -40,11 +40,6 @@ public class CraftingMonitorElementColor implements ICraftingMonitorElement { base.draw(x, y, drawers, false); } - @Override - public int getTaskId() { - return base.getTaskId(); - } - @Override public String getId() { return ID; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementFluidRender.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementFluidRender.java index 22e83ca3b..dead8e498 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementFluidRender.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementFluidRender.java @@ -14,12 +14,10 @@ import net.minecraftforge.fml.relauncher.SideOnly; public class CraftingMonitorElementFluidRender implements ICraftingMonitorElement { public static final String ID = "fluid_render"; - private int taskId; private FluidStack stack; private int offset; - public CraftingMonitorElementFluidRender(int taskId, FluidStack stack, int offset) { - this.taskId = taskId; + public CraftingMonitorElementFluidRender(FluidStack stack, int offset) { this.stack = stack; this.offset = offset; } @@ -43,11 +41,6 @@ public class CraftingMonitorElementFluidRender implements ICraftingMonitorElemen GlStateManager.popMatrix(); } - @Override - public int getTaskId() { - return taskId; - } - @Override public String getId() { return ID; @@ -55,7 +48,6 @@ public class CraftingMonitorElementFluidRender implements ICraftingMonitorElemen @Override public void write(ByteBuf buf) { - buf.writeInt(taskId); StackUtils.writeFluidStack(buf, stack); buf.writeInt(offset); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementItemRender.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementItemRender.java index d9f14f126..e70ab551f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementItemRender.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementItemRender.java @@ -14,13 +14,11 @@ import net.minecraftforge.fml.relauncher.SideOnly; public class CraftingMonitorElementItemRender implements ICraftingMonitorElement { public static final String ID = "item_render"; - private int taskId; private ItemStack stack; private int quantity; private int offset; - public CraftingMonitorElementItemRender(int taskId, ItemStack stack, int quantity, int offset) { - this.taskId = taskId; + public CraftingMonitorElementItemRender(ItemStack stack, int quantity, int offset) { this.stack = stack; this.quantity = quantity; this.offset = offset; @@ -45,11 +43,6 @@ public class CraftingMonitorElementItemRender implements ICraftingMonitorElement GlStateManager.popMatrix(); } - @Override - public int getTaskId() { - return taskId; - } - @Override public String getId() { return ID; @@ -57,7 +50,6 @@ public class CraftingMonitorElementItemRender implements ICraftingMonitorElement @Override public void write(ByteBuf buf) { - buf.writeInt(taskId); ByteBufUtils.writeItemStack(buf, stack); buf.writeInt(quantity); buf.writeInt(offset); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementText.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementText.java index b7edd7c3a..c4042c075 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementText.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementText.java @@ -46,11 +46,6 @@ public class CraftingMonitorElementText implements ICraftingMonitorElement { GlStateManager.popMatrix(); } - @Override - public int getTaskId() { - return -1; - } - @Override public String getId() { return ID; 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 2165bdbd5..9b2b2004c 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 @@ -44,6 +44,7 @@ public class CraftingTask implements ICraftingTask { private Set patternsUsed = new HashSet<>(); private int ticks = 0; private long calculationStarted; + private UUID id = UUID.randomUUID(); private IStackList toTake = API.instance().createItemStackList(); private IStackList missing = API.instance().createItemStackList(); @@ -304,35 +305,26 @@ public class CraftingTask implements ICraftingTask { public List getCraftingMonitorElements() { ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList(); - elements.directAdd(new CraftingMonitorElementItemRender( - network.getCraftingManager().getTasks().indexOf(this), - requested, - quantity, - 0 - )); - if (!missing.isEmpty()) { - elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_missing", 16)); + elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_missing", 5)); missing.getStacks().stream().map(stack -> new CraftingMonitorElementColor(new CraftingMonitorElementItemRender( - -1, stack, stack.getCount(), - 32 + 16 ), "", CraftingMonitorElementColor.COLOR_ERROR)).forEach(elements::add); elements.commit(); } if (!inserter.getItems().isEmpty()) { - elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 16)); + elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 5)); for (CraftingInserterItem item : inserter.getItems()) { ICraftingMonitorElement element = new CraftingMonitorElementItemRender( - -1, item.getStack(), item.getStack().getCount(), - 32 + 16 ); if (item.getStatus() == CraftingInserterItemStatus.FULL) { @@ -345,8 +337,8 @@ public class CraftingTask implements ICraftingTask { elements.commit(); } - if (steps.stream().anyMatch(s -> s instanceof CraftingStepCraft && !s.isCompleted())) { - elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_crafting", 16)); + if (steps.stream().anyMatch(s -> s instanceof CraftingStepCraft && !s.isCompleted() && !((CraftingStepCraft) s).getExtractor().getItems().isEmpty())) { + elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_crafting", 5)); for (CraftingStep step : steps) { if (step instanceof CraftingStepCraft && !step.isCompleted()) { @@ -357,10 +349,9 @@ public class CraftingTask implements ICraftingTask { CraftingExtractorItemStatus status = extractor.getStatus().get(i); ICraftingMonitorElement element = new CraftingMonitorElementItemRender( - -1, item, item.getCount(), - 32 + 16 ); if (status == CraftingExtractorItemStatus.MISSING) { @@ -376,7 +367,7 @@ public class CraftingTask implements ICraftingTask { } if (steps.stream().anyMatch(s -> s instanceof CraftingStepProcess && !s.isCompleted())) { - elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 16)); + elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 5)); for (CraftingStep step : steps) { if (step instanceof CraftingStepProcess && !step.isCompleted()) { @@ -387,10 +378,9 @@ public class CraftingTask implements ICraftingTask { CraftingExtractorItemStatus status = extractor.getStatus().get(i); ICraftingMonitorElement element = new CraftingMonitorElementItemRender( - -1, item, item.getCount(), - 32 + 16 ); if (status == CraftingExtractorItemStatus.MISSING) { @@ -479,6 +469,11 @@ public class CraftingTask implements ICraftingTask { return missing; } + @Override + public UUID getId() { + return id; + } + private int getTickInterval(int speedUpgrades) { switch (speedUpgrades) { case 1: diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java index 887853acf..717bde6ee 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java @@ -1,7 +1,6 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler; import com.raoulvdberge.refinedstorage.RS; -import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError; @@ -23,7 +22,9 @@ import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; +import javax.annotation.Nullable; import java.util.Collections; +import java.util.UUID; public class ItemGridHandler implements IItemGridHandler { private INetwork network; @@ -244,25 +245,17 @@ public class ItemGridHandler implements IItemGridHandler { } @Override - public void onCraftingCancelRequested(EntityPlayerMP player, int id) { + public void onCraftingCancelRequested(EntityPlayerMP player, @Nullable UUID id) { if (!network.getSecurityManager().hasPermission(Permission.AUTOCRAFTING, player)) { return; } - ICraftingManager manager = network.getCraftingManager(); - - if (id >= 0 && id < manager.getTasks().size()) { - manager.cancel(manager.getTasks().get(id)); - } else if (id == -1) { - for (ICraftingTask task : manager.getTasks()) { - manager.cancel(task); - } - } + network.getCraftingManager().cancel(id); INetworkItem networkItem = network.getNetworkItemHandler().getItem(player); if (networkItem != null) { - networkItem.onAction(id == -1 ? NetworkItemAction.CRAFTING_TASK_ALL_CANCELLED : NetworkItemAction.CRAFTING_TASK_CANCELLED); + networkItem.onAction(id == null ? NetworkItemAction.CRAFTING_TASK_ALL_CANCELLED : NetworkItemAction.CRAFTING_TASK_CANCELLED); } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandlerPortable.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandlerPortable.java index 98884ed05..219611a64 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandlerPortable.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandlerPortable.java @@ -15,6 +15,7 @@ import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; import javax.annotation.Nullable; +import java.util.UUID; public class ItemGridHandlerPortable implements IItemGridHandler { private IPortableGrid portableGrid; @@ -165,7 +166,7 @@ public class ItemGridHandlerPortable implements IItemGridHandler { } @Override - public void onCraftingCancelRequested(EntityPlayerMP player, int id) { + public void onCraftingCancelRequested(EntityPlayerMP player, @Nullable UUID id) { // NO OP } } 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 874854605..d79d19831 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 @@ -115,7 +115,7 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC if (!state) { network.getCraftingManager().getTasks().stream() .filter(task -> task.getPattern().getContainer().getPosition().equals(pos)) - .forEach(task -> network.getCraftingManager().cancel(task)); + .forEach(task -> network.getCraftingManager().cancel(task.getId())); } network.getCraftingManager().rebuild(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCraftingMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCraftingMonitor.java index 220ffc2eb..ea5258bd4 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCraftingMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCraftingMonitor.java @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.node; +import com.google.common.base.Optional; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; @@ -15,15 +16,20 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import javax.annotation.Nullable; +import java.util.Collection; import java.util.Collections; -import java.util.List; +import java.util.UUID; public class NetworkNodeCraftingMonitor extends NetworkNode implements ICraftingMonitor { public static final String ID = "crafting_monitor"; private static final String NBT_SIZE = "Size"; + private static final String NBT_TAB_SELECTED = "TabSelected"; + private static final String NBT_TAB_PAGE = "TabPage"; private int size = IGrid.SIZE_STRETCH; + private Optional tabSelected = Optional.absent(); + private int tabPage; public NetworkNodeCraftingMonitor(World world, BlockPos pos) { super(world, pos); @@ -64,7 +70,7 @@ public class NetworkNodeCraftingMonitor extends NetworkNode implements ICrafting } @Override - public void onCancelled(EntityPlayerMP player, int id) { + public void onCancelled(EntityPlayerMP player, UUID id) { if (network != null) { network.getItemGridHandler().onCraftingCancelRequested(player, id); } @@ -76,7 +82,7 @@ public class NetworkNodeCraftingMonitor extends NetworkNode implements ICrafting } @Override - public List getTasks() { + public Collection getTasks() { return network != null ? network.getCraftingManager().getTasks() : Collections.emptyList(); } @@ -104,8 +110,64 @@ public class NetworkNodeCraftingMonitor extends NetworkNode implements ICrafting } } + @Override + public NBTTagCompound write(NBTTagCompound tag) { + super.write(tag); + + tag.setInteger(NBT_TAB_PAGE, tabPage); + + if (tabSelected.isPresent()) { + tag.setUniqueId(NBT_TAB_SELECTED, tabSelected.get()); + } + + return tag; + } + + @Override + public void read(NBTTagCompound tag) { + super.read(tag); + + if (tag.hasKey(NBT_TAB_PAGE)) { + tabPage = tag.getInteger(NBT_TAB_PAGE); + } + + if (tag.hasUniqueId(NBT_TAB_SELECTED)) { + tabSelected = Optional.of(tag.getUniqueId(NBT_TAB_SELECTED)); + } + } + + public void setTabSelected(Optional tabSelected) { + this.tabSelected = tabSelected; + } + + public void setTabPage(int tabPage) { + this.tabPage = tabPage; + } + @Override public void onClosed(EntityPlayer player) { // NO OP } + + @Override + public Optional getTabSelected() { + return world.isRemote ? TileCraftingMonitor.TAB_SELECTED.getValue() : tabSelected; + } + + @Override + public int getTabPage() { + return world.isRemote ? TileCraftingMonitor.TAB_PAGE.getValue() : tabPage; + } + + @Override + public void onTabSelectionChanged(Optional tab) { + TileDataManager.setParameter(TileCraftingMonitor.TAB_SELECTED, tab); + } + + @Override + public void onTabPageChanged(int page) { + if (page >= 0) { + TileDataManager.setParameter(TileCraftingMonitor.TAB_PAGE, page); + } + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java index 7d84849f4..9f70af2e3 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java @@ -1,24 +1,31 @@ package com.raoulvdberge.refinedstorage.gui; +import com.google.common.base.Optional; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; +import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.api.render.IElementDrawer; import com.raoulvdberge.refinedstorage.api.render.IElementDrawers; +import com.raoulvdberge.refinedstorage.api.util.IFilter; import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor; import com.raoulvdberge.refinedstorage.gui.control.Scrollbar; import com.raoulvdberge.refinedstorage.gui.control.SideButtonGridSize; import com.raoulvdberge.refinedstorage.gui.control.SideButtonRedstoneMode; +import com.raoulvdberge.refinedstorage.gui.control.TabList; import com.raoulvdberge.refinedstorage.network.MessageCraftingMonitorCancel; import com.raoulvdberge.refinedstorage.tile.craftingmonitor.ICraftingMonitor; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import javax.annotation.Nullable; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.UUID; public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { public class CraftingMonitorElementDrawers extends ElementDrawers { @@ -34,7 +41,34 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { } } - private static final int VISIBLE_ROWS = 5; + public static class CraftingMonitorTask implements IGridTab { + private UUID id; + private ItemStack requested; + private int qty; + private List elements; + + public CraftingMonitorTask(UUID id, ItemStack requested, int qty, List elements) { + this.id = id; + this.requested = requested; + this.qty = qty; + this.elements = elements; + } + + @Override + public List getFilters() { + return null; + } + + @Override + public String getName() { + return qty + "x " + requested.getDisplayName(); + } + + @Override + public ItemStack getIcon() { + return requested; + } + } private static final int ITEM_WIDTH = 143; private static final int ITEM_HEIGHT = 18; @@ -43,33 +77,63 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { private GuiButton cancelAllButton; private ICraftingMonitor craftingMonitor; - private List elements = Collections.emptyList(); + + private List tasks = Collections.emptyList(); + private TabList tabs; + + private int elementSelected = -1; private IElementDrawers drawers = new CraftingMonitorElementDrawers(); - private int itemSelected = -1; - private int itemSelectedX = -1; - private int itemSelectedY = -1; - public GuiCraftingMonitor(ContainerCraftingMonitor container, ICraftingMonitor craftingMonitor) { super(container, 176, 230); this.craftingMonitor = craftingMonitor; + this.tabs = new TabList(this, () -> tasks, () -> (int) Math.floor((float) Math.max(0, tasks.size() - 1) / (float) ICraftingMonitor.TABS_PER_PAGE), craftingMonitor::getTabPage, () -> { + IGridTab tab = getCurrentTab(); + + if (tab == null) { + return -1; + } + + return tasks.indexOf(tab); + }, ICraftingMonitor.TABS_PER_PAGE); + this.tabs.addListener(new TabList.ITabListListener() { + @Override + public void onSelectionChanged(int tab) { + craftingMonitor.onTabSelectionChanged(Optional.of(((CraftingMonitorTask) tasks.get(tab)).id)); + + scrollbar.setOffset(0); + } + + @Override + public void onPageChanged(int page) { + craftingMonitor.onTabPageChanged(page); + } + }); } - public void setElements(List elements) { - this.elements = elements; + public void setTasks(List tasks) { + this.tasks = tasks; } - private List getElements() { - return craftingMonitor.isActive() ? elements : Collections.emptyList(); + public List getElements() { + IGridTab tab = getCurrentTab(); + + if (tab == null) { + return Collections.emptyList(); + } + + return ((CraftingMonitorTask) tab).elements; } @Override public void init(int x, int y) { ((ContainerCraftingMonitor) this.inventorySlots).initSlots(); - this.scrollbar = new Scrollbar(157, getTopHeight(), 12, (getVisibleRows() * 18) - 1); + this.tabs.init(xSize); + + this.scrollbar = new Scrollbar(157, getTopHeight() + tabs.getHeight(), 12, (getVisibleRows() * 18) - 1); if (craftingMonitor.getRedstoneModeParameter() != null) { addSideButton(new SideButtonRedstoneMode(this, craftingMonitor.getRedstoneModeParameter())); @@ -83,7 +147,7 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { int cancelButtonWidth = 14 + fontRenderer.getStringWidth(cancel); int cancelAllButtonWidth = 14 + fontRenderer.getStringWidth(cancelAll); - int by = y + getTopHeight() + (getVisibleRows() * 18) + 3; + int by = y + getTopHeight() + (getVisibleRows() * 18) + 3 + tabs.getHeight(); this.cancelButton = addButton(x + 7, by, cancelButtonWidth, 20, cancel, false, true); this.cancelAllButton = addButton(x + 7 + cancelButtonWidth + 4, by, cancelAllButtonWidth, 20, cancelAll, false, true); @@ -100,30 +164,54 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { public void update(int x, int y) { updateScrollbar(); - if (itemSelected >= getElements().size()) { - itemSelected = -1; + this.tabs.update(); + + if (elementSelected >= getElements().size()) { + elementSelected = -1; } if (cancelButton != null) { - cancelButton.enabled = itemSelected != -1 && getElements().get(itemSelected).getTaskId() != -1; + cancelButton.enabled = hasValidTabSelected(); } if (cancelAllButton != null) { - cancelAllButton.enabled = getElements().size() > 0; + cancelAllButton.enabled = tasks.size() > 0; } } + private boolean hasValidTabSelected() { + return getCurrentTab() != null; + } + + @Nullable + private IGridTab getCurrentTab() { + Optional currentTab = craftingMonitor.getTabSelected(); + + if (currentTab.isPresent()) { + return getTabById(currentTab.get()); + } + + return null; + } + + @Nullable + private IGridTab getTabById(UUID id) { + return tasks.stream().filter(t -> ((CraftingMonitorTask) t).id.equals(id)).findFirst().orElse(null); + } + @Override protected void calcHeight() { - this.ySize = getTopHeight() + getBottomHeight() + (getVisibleRows() * 18); + this.ySize = getTopHeight() + getBottomHeight() + (getVisibleRows() * 18) + tabs.getHeight(); this.screenHeight = ySize; } @Override public void drawBackground(int x, int y, int mouseX, int mouseY) { + tabs.drawBackground(x, y); + bindTexture("gui/crafting_monitor.png"); - int yy = y; + int yy = y + tabs.getHeight(); drawTexture(x, yy, 0, 0, screenWidth, getTopHeight()); @@ -138,11 +226,13 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { } drawTexture(x, yy, 0, getTopHeight() + (18 * 3), screenWidth, getBottomHeight()); + + tabs.drawForeground(x, y, mouseX, mouseY); } @Override public void drawForeground(int mouseX, int mouseY) { - drawString(7, 7, t(craftingMonitor.getGuiTitle())); + drawString(7, 7 + tabs.getHeight(), t(craftingMonitor.getGuiTitle())); drawString(7, getYPlayerInventory() - 12, t("container.inventory")); int item = scrollbar != null ? scrollbar.getOffset() : 0; @@ -150,26 +240,19 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { RenderHelper.enableGUIStandardItemLighting(); int x = 8; - int y = 20; + int y = 20 + tabs.getHeight(); - this.itemSelectedX = -1; - this.itemSelectedY = -1; String itemSelectedTooltip = null; for (int i = scrollbar.getOffset(); i < scrollbar.getOffset() + getVisibleRows(); ++i) { if (item < getElements().size()) { ICraftingMonitorElement element = getElements().get(item); - if (item == itemSelected) { - this.itemSelectedX = x; - this.itemSelectedY = y; - } - if (inBounds(x, y, ITEM_WIDTH, ITEM_HEIGHT, mouseX, mouseY)) { itemSelectedTooltip = element.getTooltip(); } - element.draw(x, y, drawers, item == itemSelected); + element.draw(x, y, drawers, item == elementSelected); y += ITEM_HEIGHT; } @@ -180,13 +263,15 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { if (itemSelectedTooltip != null && !itemSelectedTooltip.isEmpty()) { drawTooltip(mouseX, mouseY, I18n.format(itemSelectedTooltip)); } + + tabs.drawTooltip(fontRenderer, mouseX, mouseY); } @Override public int getVisibleRows() { switch (craftingMonitor.getSize()) { case IGrid.SIZE_STRETCH: - int screenSpaceAvailable = height - getTopHeight() - getBottomHeight(); + int screenSpaceAvailable = height - getTopHeight() - getBottomHeight() - tabs.getHeight(); return Math.max(3, Math.min((screenSpaceAvailable / 18) - 3, RS.INSTANCE.config.maxRowsStretch)); case IGrid.SIZE_SMALL: @@ -227,21 +312,24 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { @Override public int getYPlayerInventory() { - return getTopHeight() + (18 * getVisibleRows()) + 38; + return getTopHeight() + (18 * getVisibleRows()) + 38 + tabs.getHeight(); + } + + @Override + protected int getSideButtonYStart() { + return super.getSideButtonYStart() + tabs.getHeight(); } @Override protected void actionPerformed(GuiButton button) throws IOException { super.actionPerformed(button); - if (button == cancelButton && itemSelected != -1) { - ICraftingMonitorElement element = getElements().get(itemSelected); + tabs.actionPerformed(button); - if (element.getTaskId() != -1) { - RS.INSTANCE.network.sendToServer(new MessageCraftingMonitorCancel(element.getTaskId())); - } - } else if (button == cancelAllButton && getElements().size() > 0) { - RS.INSTANCE.network.sendToServer(new MessageCraftingMonitorCancel(-1)); + if (button == cancelButton && hasValidTabSelected()) { + RS.INSTANCE.network.sendToServer(new MessageCraftingMonitorCancel(craftingMonitor.getTabSelected().get())); + } else if (button == cancelAllButton && tasks.size() > 0) { + RS.INSTANCE.network.sendToServer(new MessageCraftingMonitorCancel(null)); } } @@ -249,17 +337,19 @@ public class GuiCraftingMonitor extends GuiBase implements IResizableDisplay { protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { super.mouseClicked(mouseX, mouseY, mouseButton); - this.itemSelected = -1; + this.tabs.mouseClicked(); + + this.elementSelected = -1; if (mouseButton == 0) { int item = scrollbar != null ? scrollbar.getOffset() : 0; for (int i = 0; i < getVisibleRows(); ++i) { int ix = 8; - int iy = 20 + (i * ITEM_HEIGHT); + int iy = 20 + (i * ITEM_HEIGHT) + tabs.getHeight(); if (inBounds(ix, iy, ITEM_WIDTH, ITEM_HEIGHT, mouseX - guiLeft, mouseY - guiTop) && (item + i) < getElements().size()) { - this.itemSelected = item + i; + this.elementSelected = item + i; } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/control/TabList.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/control/TabList.java index b8df75cf1..f03abf98c 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/control/TabList.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/control/TabList.java @@ -32,6 +32,8 @@ public class TabList { private GuiButton left; private GuiButton right; + private int width; + public TabList(GuiBase gui, Supplier> tabs, Supplier pages, Supplier page, Supplier selected, int tabsPerPage) { this.gui = gui; this.tabs = tabs; @@ -41,9 +43,10 @@ public class TabList { this.tabsPerPage = tabsPerPage; } - public void init() { - this.left = gui.addButton(gui.getGuiLeft(), gui.getGuiTop() - 22, 20, 20, "<", true, pages.get() > 0); - this.right = gui.addButton(gui.getGuiLeft() + gui.getXSize() - 22 - 32, gui.getGuiTop() - 22, 20, 20, ">", true, pages.get() > 0); + public void init(int width) { + this.width = width; + this.left = gui.addButton(gui.getGuiLeft(), gui.getGuiTop() - 20, 20, 20, "<", true, pages.get() > 0); + this.right = gui.addButton(gui.getGuiLeft() + width - 22, gui.getGuiTop() - 20, 20, 20, ">", true, pages.get() > 0); } public void addListener(ITabListListener listener) { @@ -76,6 +79,10 @@ public class TabList { gui.initGui(); } + if (page.get() > pages.get()) { + listeners.forEach(t -> t.onPageChanged(pages.get())); + } + left.visible = pages.get() > 0; right.visible = pages.get() > 0; left.enabled = page.get() > 0; @@ -144,7 +151,7 @@ public class TabList { if (pages.get() > 0) { String text = (page.get() + 1) + " / " + (pages.get() + 1); - gui.drawString((int) ((193F - (float) fontRenderer.getStringWidth(text)) / 2F), -16, text, 0xFFFFFF); + gui.drawString((int) ((width - (float) fontRenderer.getStringWidth(text)) / 2F), -14, text, 0xFFFFFF); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java index d255939d3..6a33026df 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java @@ -5,7 +5,6 @@ import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.RSKeyBindings; import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; -import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid; import com.raoulvdberge.refinedstorage.container.ContainerGrid; @@ -102,7 +101,7 @@ public class GuiGrid extends GuiBase implements IResizableDisplay { public void init(int x, int y) { ((ContainerGrid) this.inventorySlots).initSlots(); - this.tabs.init(); + this.tabs.init(xSize - 32); this.scrollbar = new Scrollbar(174, tabs.getHeight() + getTopHeight(), 12, (getVisibleRows() * 18) - 2); @@ -146,7 +145,7 @@ public class GuiGrid extends GuiBase implements IResizableDisplay { @Override protected int getSideButtonYStart() { - return super.getSideButtonYStart() + (!grid.getTabs().isEmpty() ? IGridTab.TAB_HEIGHT - 3 : 0); + return super.getSideButtonYStart() + tabs.getHeight(); } public IGrid getGrid() { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java b/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java index a1d549ddc..665567a86 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java @@ -150,7 +150,7 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment { int count = 0; for (ICraftingTask task : node.getNetwork().getCraftingManager().getTasks()) { if (API.instance().getComparer().isEqual(task.getRequested(), stack, COMPARE_NBT | COMPARE_DAMAGE)) { - node.getNetwork().getCraftingManager().cancel(task); + node.getNetwork().getCraftingManager().cancel(task.getId()); count++; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemWirelessCraftingMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemWirelessCraftingMonitor.java index 688c9cd9a..b22c125a8 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/item/ItemWirelessCraftingMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/item/ItemWirelessCraftingMonitor.java @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.item; +import com.google.common.base.Optional; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.api.network.item.INetworkItem; import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemHandler; @@ -9,9 +10,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import javax.annotation.Nonnull; +import java.util.UUID; public class ItemWirelessCraftingMonitor extends ItemNetworkItem { public static final String NBT_SIZE = "Size"; + public static final String NBT_TAB_SELECTED = "TabSelected"; + public static final String NBT_TAB_PAGE = "TabPage"; public ItemWirelessCraftingMonitor() { super("wireless_crafting_monitor"); @@ -38,4 +42,41 @@ public class ItemWirelessCraftingMonitor extends ItemNetworkItem { stack.getTagCompound().setInteger(NBT_SIZE, size); } + + public static Optional getTabSelected(ItemStack stack) { + if (stack.hasTagCompound() && stack.getTagCompound().hasUniqueId(NBT_TAB_SELECTED)) { + return Optional.of(stack.getTagCompound().getUniqueId(NBT_TAB_SELECTED)); + } + + return Optional.absent(); + } + + public static void setTabSelected(ItemStack stack, Optional tabSelected) { + if (!stack.hasTagCompound()) { + stack.setTagCompound(new NBTTagCompound()); + } + + if (tabSelected.isPresent()) { + stack.getTagCompound().setUniqueId(NBT_TAB_SELECTED, tabSelected.get()); + } else { + stack.getTagCompound().removeTag(NBT_TAB_SELECTED + "Least"); + stack.getTagCompound().removeTag(NBT_TAB_SELECTED + "Most"); + } + } + + public static int getTabPage(ItemStack stack) { + if (stack.hasTagCompound() && stack.getTagCompound().hasKey(NBT_TAB_PAGE)) { + return stack.getTagCompound().getInteger(NBT_TAB_PAGE); + } + + return 0; + } + + public static void setTabPage(ItemStack stack, int tabPage) { + if (!stack.hasTagCompound()) { + stack.setTagCompound(new NBTTagCompound()); + } + + stack.getTagCompound().setInteger(NBT_TAB_PAGE, tabPage); + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorCancel.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorCancel.java index 470e5aa0c..3ba40d6e5 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorCancel.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorCancel.java @@ -3,32 +3,41 @@ package com.raoulvdberge.refinedstorage.network; import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import java.util.UUID; + public class MessageCraftingMonitorCancel extends MessageHandlerPlayerToServer implements IMessage { - private int id; + private UUID taskId; public MessageCraftingMonitorCancel() { } - public MessageCraftingMonitorCancel(int id) { - this.id = id; + public MessageCraftingMonitorCancel(UUID taskId) { + this.taskId = taskId; } @Override public void fromBytes(ByteBuf buf) { - id = buf.readInt(); + if (buf.readBoolean()) { + taskId = UUID.fromString(ByteBufUtils.readUTF8String(buf)); + } } @Override public void toBytes(ByteBuf buf) { - buf.writeInt(id); + buf.writeBoolean(taskId != null); + + if (taskId != null) { + ByteBufUtils.writeUTF8String(buf, taskId.toString()); + } } @Override public void handle(MessageCraftingMonitorCancel message, EntityPlayerMP player) { if (player.openContainer instanceof ContainerCraftingMonitor) { - ((ContainerCraftingMonitor) player.openContainer).getCraftingMonitor().onCancelled(player, message.id); + ((ContainerCraftingMonitor) player.openContainer).getCraftingMonitor().onCancelled(player, message.taskId); } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java index 943b6071d..b6ecb7df0 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java @@ -2,25 +2,27 @@ package com.raoulvdberge.refinedstorage.network; import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; +import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.GuiCraftingMonitor; import com.raoulvdberge.refinedstorage.tile.craftingmonitor.ICraftingMonitor; import io.netty.buffer.ByteBuf; +import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; +import java.util.UUID; import java.util.function.Function; public class MessageCraftingMonitorElements implements IMessage, IMessageHandler { private ICraftingMonitor craftingMonitor; - private List elements = new ArrayList<>(); + private List tasks = new ArrayList<>(); public MessageCraftingMonitorElements() { } @@ -34,34 +36,49 @@ public class MessageCraftingMonitorElements implements IMessage, IMessageHandler int size = buf.readInt(); for (int i = 0; i < size; ++i) { - Function factory = API.instance().getCraftingMonitorElementRegistry().get(ByteBufUtils.readUTF8String(buf)); + UUID id = UUID.fromString(ByteBufUtils.readUTF8String(buf)); + ItemStack requested = ByteBufUtils.readItemStack(buf); + int qty = buf.readInt(); + List elements = new ArrayList<>(); - if (factory != null) { - elements.add(factory.apply(buf)); + int elementCount = buf.readInt(); + + for (int j = 0; j < elementCount; ++j) { + Function factory = API.instance().getCraftingMonitorElementRegistry().get(ByteBufUtils.readUTF8String(buf)); + + if (factory != null) { + elements.add(factory.apply(buf)); + } } + + tasks.add(new GuiCraftingMonitor.CraftingMonitorTask(id, requested, qty, elements)); } } @Override public void toBytes(ByteBuf buf) { - List elements = new LinkedList<>(); + buf.writeInt(craftingMonitor.getTasks().size()); for (ICraftingTask task : craftingMonitor.getTasks()) { - elements.addAll(task.getCraftingMonitorElements()); - } + ByteBufUtils.writeUTF8String(buf, task.getId().toString()); + ByteBufUtils.writeItemStack(buf, task.getRequested()); + buf.writeInt(task.getQuantity()); - buf.writeInt(elements.size()); + List elements = task.getCraftingMonitorElements(); - for (ICraftingMonitorElement element : elements) { - ByteBufUtils.writeUTF8String(buf, element.getId()); + buf.writeInt(elements.size()); - element.write(buf); + for (ICraftingMonitorElement element : elements) { + ByteBufUtils.writeUTF8String(buf, element.getId()); + + element.write(buf); + } } } @Override public IMessage onMessage(MessageCraftingMonitorElements message, MessageContext ctx) { - GuiBase.executeLater(GuiCraftingMonitor.class, craftingMonitor -> craftingMonitor.setElements(message.elements)); + GuiBase.executeLater(GuiCraftingMonitor.class, craftingMonitor -> craftingMonitor.setTasks(message.tasks)); return null; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageWirelessCraftingMonitorSettings.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageWirelessCraftingMonitorSettings.java new file mode 100644 index 000000000..0be8cae7c --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageWirelessCraftingMonitorSettings.java @@ -0,0 +1,63 @@ +package com.raoulvdberge.refinedstorage.network; + +import com.google.common.base.Optional; +import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; +import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor; +import com.raoulvdberge.refinedstorage.item.ItemWirelessCraftingMonitor; +import com.raoulvdberge.refinedstorage.tile.craftingmonitor.WirelessCraftingMonitor; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.common.network.ByteBufUtils; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; + +import java.util.UUID; + +public class MessageWirelessCraftingMonitorSettings extends MessageHandlerPlayerToServer implements IMessage { + private int size; + private Optional tabSelected = Optional.absent(); + private int tabPage; + + public MessageWirelessCraftingMonitorSettings() { + } + + public MessageWirelessCraftingMonitorSettings(int size, Optional tabSelected, int tabPage) { + this.size = size; + this.tabSelected = tabSelected; + this.tabPage = tabPage; + } + + @Override + public void fromBytes(ByteBuf buf) { + size = buf.readInt(); + + if (buf.readBoolean()) { + tabSelected = Optional.of(UUID.fromString(ByteBufUtils.readUTF8String(buf))); + } + + tabPage = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(size); + + buf.writeBoolean(tabSelected.isPresent()); + if (tabSelected.isPresent()) { + ByteBufUtils.writeUTF8String(buf, tabSelected.get().toString()); + } + + buf.writeInt(tabPage); + } + + @Override + public void handle(MessageWirelessCraftingMonitorSettings message, EntityPlayerMP player) { + if (player.openContainer instanceof ContainerCraftingMonitor && IGrid.isValidSize(message.size)) { + ItemStack stack = ((WirelessCraftingMonitor) ((ContainerCraftingMonitor) player.openContainer).getCraftingMonitor()).getStack(); + + ItemWirelessCraftingMonitor.setSize(stack, message.size); + ItemWirelessCraftingMonitor.setTabPage(stack, message.tabPage); + ItemWirelessCraftingMonitor.setTabSelected(stack, message.tabSelected); + } + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageWirelessCraftingMonitorSize.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageWirelessCraftingMonitorSize.java deleted file mode 100644 index 72c0c8e58..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageWirelessCraftingMonitorSize.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.raoulvdberge.refinedstorage.network; - -import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; -import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor; -import com.raoulvdberge.refinedstorage.item.ItemWirelessCraftingMonitor; -import com.raoulvdberge.refinedstorage.tile.craftingmonitor.WirelessCraftingMonitor; -import io.netty.buffer.ByteBuf; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; - -public class MessageWirelessCraftingMonitorSize extends MessageHandlerPlayerToServer implements IMessage { - private int size; - - public MessageWirelessCraftingMonitorSize() { - } - - public MessageWirelessCraftingMonitorSize(int size) { - this.size = size; - } - - @Override - public void fromBytes(ByteBuf buf) { - size = buf.readInt(); - } - - @Override - public void toBytes(ByteBuf buf) { - buf.writeInt(size); - } - - @Override - public void handle(MessageWirelessCraftingMonitorSize message, EntityPlayerMP player) { - if (player.openContainer instanceof ContainerCraftingMonitor && IGrid.isValidSize(message.size)) { - ItemWirelessCraftingMonitor.setSize(((WirelessCraftingMonitor) ((ContainerCraftingMonitor) player.openContainer).getCraftingMonitor()).getStack(), message.size); - } - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java index e18480e4e..ae5e91efc 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java @@ -96,8 +96,8 @@ public class ProxyCommon { API.instance().getCraftingTaskRegistry().add(CraftingTaskFactory.ID, new CraftingTaskFactory()); - API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementItemRender.ID, buf -> new CraftingMonitorElementItemRender(buf.readInt(), ByteBufUtils.readItemStack(buf), buf.readInt(), buf.readInt())); - API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementFluidRender.ID, buf -> new CraftingMonitorElementFluidRender(buf.readInt(), StackUtils.readFluidStack(buf).getRight(), buf.readInt())); + API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementItemRender.ID, buf -> new CraftingMonitorElementItemRender(ByteBufUtils.readItemStack(buf), buf.readInt(), buf.readInt())); + API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementFluidRender.ID, buf -> new CraftingMonitorElementFluidRender(StackUtils.readFluidStack(buf).getRight(), buf.readInt())); API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementText.ID, buf -> new CraftingMonitorElementText(ByteBufUtils.readUTF8String(buf), buf.readInt())); API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementColor.ID, buf -> { int color = buf.readInt(); @@ -178,7 +178,7 @@ public class ProxyCommon { RS.INSTANCE.network.registerMessage(MessageWirelessFluidGridSettingsUpdate.class, MessageWirelessFluidGridSettingsUpdate.class, id++, Side.SERVER); RS.INSTANCE.network.registerMessage(MessageCrafterManagerSlotSizes.class, MessageCrafterManagerSlotSizes.class, id++, Side.CLIENT); RS.INSTANCE.network.registerMessage(MessageCrafterManagerRequestSlotData.class, MessageCrafterManagerRequestSlotData.class, id++, Side.SERVER); - RS.INSTANCE.network.registerMessage(MessageWirelessCraftingMonitorSize.class, MessageWirelessCraftingMonitorSize.class, id++, Side.SERVER); + RS.INSTANCE.network.registerMessage(MessageWirelessCraftingMonitorSettings.class, MessageWirelessCraftingMonitorSettings.class, id++, Side.SERVER); RS.INSTANCE.network.registerMessage(MessageStorageDiskSizeRequest.class, MessageStorageDiskSizeRequest.class, id++, Side.SERVER); RS.INSTANCE.network.registerMessage(MessageStorageDiskSizeResponse.class, MessageStorageDiskSizeResponse.class, id++, Side.CLIENT); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/ICraftingMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/ICraftingMonitor.java index 76b5cc701..576f3549d 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/ICraftingMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/ICraftingMonitor.java @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.tile.craftingmonitor; +import com.google.common.base.Optional; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; @@ -7,16 +8,19 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import javax.annotation.Nullable; -import java.util.List; +import java.util.Collection; +import java.util.UUID; public interface ICraftingMonitor { + int TABS_PER_PAGE = 6; + String getGuiTitle(); - void onCancelled(EntityPlayerMP player, int id); + void onCancelled(EntityPlayerMP player, @Nullable UUID id); TileDataParameter getRedstoneModeParameter(); - List getTasks(); + Collection getTasks(); @Nullable ICraftingManager getCraftingManager(); @@ -28,4 +32,12 @@ public interface ICraftingMonitor { boolean isActive(); void onClosed(EntityPlayer player); + + Optional getTabSelected(); + + int getTabPage(); + + void onTabSelectionChanged(Optional taskId); + + void onTabPageChanged(int page); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/TileCraftingMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/TileCraftingMonitor.java index b00d54ecf..915038487 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/TileCraftingMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/TileCraftingMonitor.java @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.tile.craftingmonitor; +import com.google.common.base.Optional; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeCraftingMonitor; import com.raoulvdberge.refinedstorage.gui.GuiBase; @@ -11,6 +12,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import javax.annotation.Nonnull; +import java.util.UUID; public class TileCraftingMonitor extends TileNode { public static final TileDataParameter SIZE = new TileDataParameter<>(DataSerializers.VARINT, IGrid.SIZE_STRETCH, t -> t.getNode().getSize(), (t, v) -> { @@ -19,9 +21,26 @@ public class TileCraftingMonitor extends TileNode { t.getNode().markDirty(); } }, (initial, p) -> GuiBase.executeLater(GuiCraftingMonitor.class, GuiBase::initGui)); + public static final TileDataParameter, TileCraftingMonitor> TAB_SELECTED = new TileDataParameter<>(DataSerializers.OPTIONAL_UNIQUE_ID, Optional.absent(), t -> t.getNode().getTabSelected(), (t, v) -> { + if (v.isPresent() && t.getNode().getTabSelected().isPresent() && v.get().equals(t.getNode().getTabSelected().get())) { + t.getNode().setTabSelected(Optional.absent()); + } else { + t.getNode().setTabSelected(v); + } + + t.getNode().markDirty(); + }); + public static final TileDataParameter TAB_PAGE = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getTabPage(), (t, v) -> { + if (v >= 0) { + t.getNode().setTabPage(v); + t.getNode().markDirty(); + } + }); public TileCraftingMonitor() { dataManager.addWatchedParameter(SIZE); + dataManager.addWatchedParameter(TAB_SELECTED); + dataManager.addWatchedParameter(TAB_PAGE); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/WirelessCraftingMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/WirelessCraftingMonitor.java index 2e365cf20..78cbc9e78 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/WirelessCraftingMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/craftingmonitor/WirelessCraftingMonitor.java @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.tile.craftingmonitor; +import com.google.common.base.Optional; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; @@ -7,7 +8,7 @@ import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.GuiCraftingMonitor; import com.raoulvdberge.refinedstorage.item.ItemWirelessCraftingMonitor; -import com.raoulvdberge.refinedstorage.network.MessageWirelessCraftingMonitorSize; +import com.raoulvdberge.refinedstorage.network.MessageWirelessCraftingMonitorSettings; import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -18,8 +19,9 @@ import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; import javax.annotation.Nullable; +import java.util.Collection; import java.util.Collections; -import java.util.List; +import java.util.UUID; public class WirelessCraftingMonitor implements ICraftingMonitor { private ItemStack stack; @@ -27,12 +29,16 @@ public class WirelessCraftingMonitor implements ICraftingMonitor { private int networkDimension; private BlockPos network; private int size; + private int tabPage; + private Optional tabSelected; public WirelessCraftingMonitor(int networkDimension, ItemStack stack) { this.stack = stack; this.networkDimension = networkDimension; this.network = new BlockPos(ItemWirelessCraftingMonitor.getX(stack), ItemWirelessCraftingMonitor.getY(stack), ItemWirelessCraftingMonitor.getZ(stack)); this.size = ItemWirelessCraftingMonitor.getSize(stack); + this.tabPage = ItemWirelessCraftingMonitor.getTabPage(stack); + this.tabSelected = ItemWirelessCraftingMonitor.getTabSelected(stack); } @Override @@ -41,7 +47,7 @@ public class WirelessCraftingMonitor implements ICraftingMonitor { } @Override - public void onCancelled(EntityPlayerMP player, int id) { + public void onCancelled(EntityPlayerMP player, UUID id) { INetwork network = getNetwork(); if (network != null) { @@ -55,7 +61,7 @@ public class WirelessCraftingMonitor implements ICraftingMonitor { } @Override - public List getTasks() { + public Collection getTasks() { INetwork network = getNetwork(); if (network != null) { @@ -88,7 +94,7 @@ public class WirelessCraftingMonitor implements ICraftingMonitor { GuiBase.executeLater(GuiCraftingMonitor.class, GuiBase::initGui); - RS.INSTANCE.network.sendToServer(new MessageWirelessCraftingMonitorSize(size)); + RS.INSTANCE.network.sendToServer(new MessageWirelessCraftingMonitorSettings(size, tabSelected, tabPage)); } private INetwork getNetwork() { @@ -120,4 +126,34 @@ public class WirelessCraftingMonitor implements ICraftingMonitor { network.getNetworkItemHandler().onClose(player); } } + + @Override + public Optional getTabSelected() { + return tabSelected; + } + + @Override + public int getTabPage() { + return tabPage; + } + + @Override + public void onTabSelectionChanged(Optional taskId) { + if (taskId.isPresent() && tabSelected.isPresent() && taskId.get().equals(tabSelected.get())) { + this.tabSelected = Optional.absent(); + } else { + this.tabSelected = taskId; + } + + RS.INSTANCE.network.sendToServer(new MessageWirelessCraftingMonitorSettings(size, tabSelected, tabPage)); + } + + @Override + public void onTabPageChanged(int page) { + if (page >= 0) { + this.tabPage = page; + + RS.INSTANCE.network.sendToServer(new MessageWirelessCraftingMonitorSettings(size, tabSelected, tabPage)); + } + } }