From 038b268598e86839ceeb5e7dc6919ea0a06383e3 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 21:00:05 -0700 Subject: [PATCH 001/147] initial work on workbench port --- .../storage/MetaTileEntityWorkbench.java | 149 +++++++++++++----- 1 file changed, 112 insertions(+), 37 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index bbfb8c2685e..55e1d22802b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,23 +1,14 @@ package gregtech.common.metatileentities.storage; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; -import gregtech.api.gui.Widget.ClickData; -import gregtech.api.gui.resources.TextureArea; -import gregtech.api.gui.widgets.*; -import gregtech.api.gui.widgets.TabGroup.TabLocation; -import gregtech.api.gui.widgets.tab.ItemTabInfo; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.api.storage.ICraftingStorage; import gregtech.api.util.GTUtility; import gregtech.api.util.Position; import gregtech.client.renderer.texture.Textures; -import gregtech.common.gui.widget.craftingstation.CraftingSlotWidget; -import gregtech.common.gui.widget.craftingstation.ItemListGridWidget; -import gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget; import gregtech.common.inventory.IItemList; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; @@ -41,6 +32,19 @@ import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.PageButton; +import com.cleanroommc.modularui.widgets.PagedWidget; +import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.base.Preconditions; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; @@ -68,43 +72,43 @@ public MetaTileEntityWorkbench(ResourceLocation metaTileEntityId) { super(metaTileEntityId); } - public static AbstractWidgetGroup createWorkbenchTab(CraftingRecipeLogic craftingRecipeLogic, + public static gregtech.api.gui.widgets.AbstractWidgetGroup createWorkbenchTab(CraftingRecipeLogic craftingRecipeLogic, ItemStackHandler craftingGrid, CraftingRecipeMemory recipeMemory, ItemStackHandler toolInventory, ItemStackHandler internalInventory) { - WidgetGroup widgetGroup = new WidgetGroup(); - widgetGroup.addWidget(new ImageWidget(88 - 13, 44 - 14, 26, 26, GuiTextures.SLOT)); - widgetGroup.addWidget(new CraftingSlotWidget(craftingRecipeLogic, 0, 88 - 9, 44 - 9)); + gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); + widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(88 - 13, 44 - 14, 26, 26, gregtech.api.gui.GuiTextures.SLOT)); + widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.CraftingSlotWidget(craftingRecipeLogic, 0, 88 - 9, 44 - 9)); // crafting grid - widgetGroup.addWidget(new CraftingStationInputWidgetGroup(4, 7, craftingGrid, craftingRecipeLogic)); + widgetGroup.addWidget(new gregtech.api.gui.widgets.CraftingStationInputWidgetGroup(4, 7, craftingGrid, craftingRecipeLogic)); Supplier textSupplier = () -> Integer.toString(craftingRecipeLogic.getItemsCraftedAmount()); - widgetGroup.addWidget(new SimpleTextWidget(88, 44 + 19, "", textSupplier)); + widgetGroup.addWidget(new gregtech.api.gui.widgets.SimpleTextWidget(88, 44 + 19, "", textSupplier)); - Consumer clearAction = (clickData) -> craftingRecipeLogic.clearCraftingGrid(); - widgetGroup.addWidget(new ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction) - .setButtonTexture(GuiTextures.BUTTON_CLEAR_GRID)); + Consumer clearAction = (clickData) -> craftingRecipeLogic.clearCraftingGrid(); + widgetGroup.addWidget(new gregtech.api.gui.widgets.ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction) + .setButtonTexture(gregtech.api.gui.GuiTextures.BUTTON_CLEAR_GRID)); - widgetGroup.addWidget(new ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, - TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); + widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, + gregtech.api.gui.resources.TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - widgetGroup.addWidget(new MemorizedRecipeWidget(recipeMemory, j + i * 3, craftingGrid, + widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget(recipeMemory, j + i * 3, craftingGrid, 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); } } // tool inventory for (int i = 0; i < 9; i++) { - widgetGroup.addWidget(new SlotWidget(toolInventory, i, 7 + i * 18, 75) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.TOOL_SLOT_OVERLAY)); + widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(toolInventory, i, 7 + i * 18, 75) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, gregtech.api.gui.GuiTextures.TOOL_SLOT_OVERLAY)); } // internal inventory for (int i = 0; i < 2; ++i) { for (int j = 0; j < 9; ++j) { - widgetGroup.addWidget(new SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * 18) - .setBackgroundTexture(GuiTextures.SLOT)); + widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * 18) + .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); } } return widgetGroup; @@ -190,29 +194,100 @@ public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) clearInventory(itemBuffer, toolInventory); } - private AbstractWidgetGroup createItemListTab() { - WidgetGroup widgetGroup = new WidgetGroup(); - widgetGroup.addWidget(new LabelWidget(5, 20, "gregtech.machine.workbench.storage_note_1")); - widgetGroup.addWidget(new LabelWidget(5, 30, "gregtech.machine.workbench.storage_note_2")); + private gregtech.api.gui.widgets.AbstractWidgetGroup createItemListTab() { + gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); + widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 20, "gregtech.machine.workbench.storage_note_1")); + widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 30, "gregtech.machine.workbench.storage_note_2")); CraftingRecipeLogic recipeResolver = getCraftingRecipeLogic(); IItemList itemList = recipeResolver == null ? null : recipeResolver.getItemSourceList(); - widgetGroup.addWidget(new ItemListGridWidget(11, 45, 8, 5, itemList)); + widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.ItemListGridWidget(11, 45, 8, 5, itemList)); return widgetGroup; } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { + final String nineSlot = "XXXXXXXXX"; + final String[] craftingGrid = new String[] {"XXX", "XXX", "XXX"}; + final char key = 'X'; + + var toolSlots = new SlotGroup("tool_slots", 9, true); + var inventory = new SlotGroup("inventory", 9, true); + guiSyncManager.registerSlotGroup(toolSlots); + guiSyncManager.registerSlotGroup(inventory); + + var controller = new PagedWidget.Controller(); + + return GTGuis.createPanel(this, 176, 224) + .child(new Row() + .coverChildren() + .topRel(0f, 4, 1f) + .child(new PageButton(0, controller) + .tab(com.cleanroommc.modularui.drawable.GuiTextures.TAB_TOP, -1)) + .child(new PageButton(1, controller) + .tab(com.cleanroommc.modularui.drawable.GuiTextures.TAB_TOP, 0))) + .child(new PagedWidget<>() + .top(7).leftRel(0.5f) + .coverChildren() + .controller(controller) + .addPage(new Column().coverChildren() + .child(new Row().coverChildrenHeight() + .widthRel(1f) + .marginBottom(2) + .child(SlotGroupWidget.builder() + .matrix(craftingGrid) + .key(key, i -> new ItemSlot() + .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i))) + .build()) + .child(new ItemSlot() + // todo figure this shit (recipe output slot) out + .slot(new ItemStackHandler(1), 0) + .background(GTGuiTextures.SLOT.asIcon().size(22)) + .align(Alignment.Center)) + .child(SlotGroupWidget.builder() + .matrix(craftingGrid) + .key(key, i -> new ItemSlot() + // todo recipe memory + .slot(SyncHandlers.phantomItemSlot(new ItemStackHandler(9), i))) + .build() + .right(0))) + .child(SlotGroupWidget.builder() + .row(nineSlot) + .key(key, i -> new ItemSlot() + .overlay(GTGuiTextures.INGOT_OVERLAY) + .slot(SyncHandlers.itemSlot(this.toolInventory, i) + .slotGroup(toolSlots))) + .build().marginBottom(2)) + .child(SlotGroupWidget.builder() + .row(nineSlot) + .row(nineSlot) + .key(key, i -> new ItemSlot() + .slot(SyncHandlers.itemSlot(this.internalInventory, i) + .slotGroup(inventory))) + .build())) + .addPage(new Column() + .child(IKey.str("add storage things").asWidget()))) + .bindPlayerInventory(7); + } + + @Override + protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { createCraftingRecipeLogic(entityPlayer); - Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 221) + gregtech.api.gui.ModularUI.Builder builder = gregtech.api.gui.ModularUI.builder(gregtech.api.gui.GuiTextures.BACKGROUND, 176, 221) .bindPlayerInventory(entityPlayer.inventory, 138); builder.label(5, 5, getMetaFullName()); - TabGroup tabGroup = new TabGroup<>(TabLocation.HORIZONTAL_TOP_LEFT, Position.ORIGIN); - tabGroup.addTab(new ItemTabInfo("gregtech.machine.workbench.tab.workbench", + gregtech.api.gui.widgets.TabGroup tabGroup = new gregtech.api.gui.widgets.TabGroup<>( + gregtech.api.gui.widgets.TabGroup.TabLocation.HORIZONTAL_TOP_LEFT, Position.ORIGIN); + tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.workbench", new ItemStack(Blocks.CRAFTING_TABLE)), createWorkbenchTab(recipeLogic, craftingGrid, recipeMemory, toolInventory, internalInventory)); - tabGroup.addTab(new ItemTabInfo("gregtech.machine.workbench.tab.item_list", + tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.item_list", new ItemStack(Blocks.CHEST)), createItemListTab()); builder.widget(tabGroup); builder.bindCloseListener(() -> discardRecipeResolver(entityPlayer)); From 093710435f14ae26b0c3e40266291d781285f730 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 22:23:15 -0700 Subject: [PATCH 002/147] make crafting logic not server only --- .../storage/MetaTileEntityWorkbench.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 55e1d22802b..5d606fb1a07 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -159,17 +159,15 @@ public void readFromNBT(NBTTagCompound data) { } private void createCraftingRecipeLogic(EntityPlayer entityPlayer) { - if (!getWorld().isRemote) { - if (recipeLogic == null) { - this.recipeLogic = new CraftingRecipeLogic(this); - this.recipeLogic.setItemsCraftedAmount(itemsCrafted); - ItemSources itemSources = this.recipeLogic.getItemSourceList(); - itemSources.addItemHandler(new InventoryItemSource(getWorld(), toolInventory, -2)); - itemSources.addItemHandler(new InventoryItemSource(getWorld(), internalInventory, -1)); - this.recipeLogic.checkNeighbourInventories(getPos()); - } - this.listeners.add(entityPlayer); + if (recipeLogic == null) { + this.recipeLogic = new CraftingRecipeLogic(this); + this.recipeLogic.setItemsCraftedAmount(itemsCrafted); + ItemSources itemSources = this.recipeLogic.getItemSourceList(); + itemSources.addItemHandler(new InventoryItemSource(getWorld(), toolInventory, -2)); + itemSources.addItemHandler(new InventoryItemSource(getWorld(), internalInventory, -1)); + this.recipeLogic.checkNeighbourInventories(getPos()); } + this.listeners.add(entityPlayer); } @Override From 3acd0e386130de9690f1ee5f23550a37680fbd6c Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 22:23:51 -0700 Subject: [PATCH 003/147] fix crafting output slot --- .../storage/MetaTileEntityWorkbench.java | 54 +++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 5d606fb1a07..bd1064570fe 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -19,6 +19,7 @@ import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; @@ -26,6 +27,7 @@ import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; import codechicken.lib.render.CCRenderState; @@ -33,6 +35,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; @@ -217,6 +220,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { var inventory = new SlotGroup("inventory", 9, true); guiSyncManager.registerSlotGroup(toolSlots); guiSyncManager.registerSlotGroup(inventory); + createCraftingRecipeLogic(guiData.getPlayer()); var controller = new PagedWidget.Controller(); @@ -225,9 +229,9 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .coverChildren() .topRel(0f, 4, 1f) .child(new PageButton(0, controller) - .tab(com.cleanroommc.modularui.drawable.GuiTextures.TAB_TOP, -1)) + .tab(GuiTextures.TAB_TOP, 0)) .child(new PageButton(1, controller) - .tab(com.cleanroommc.modularui.drawable.GuiTextures.TAB_TOP, 0))) + .tab(GuiTextures.TAB_TOP, 0))) .child(new PagedWidget<>() .top(7).leftRel(0.5f) .coverChildren() @@ -236,6 +240,9 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(new Row().coverChildrenHeight() .widthRel(1f) .marginBottom(2) + //todo + // make JEI transfer work correctly + // currently it's not possible due to getCurrent() in ModularScreen returning null .child(SlotGroupWidget.builder() .matrix(craftingGrid) .key(key, i -> new ItemSlot() @@ -243,7 +250,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .build()) .child(new ItemSlot() // todo figure this shit (recipe output slot) out - .slot(new ItemStackHandler(1), 0) + .slot(new InventoryWrapper(this.recipeLogic.getCraftingResultInventory()), 0) .background(GTGuiTextures.SLOT.asIcon().size(22)) .align(Alignment.Center)) .child(SlotGroupWidget.builder() @@ -272,9 +279,48 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .bindPlayerInventory(7); } + + + private static class InventoryWrapper implements IItemHandlerModifiable { + + IInventory inventory; + private InventoryWrapper(IInventory inventory) { + this.inventory = inventory; + } + + @Override + public int getSlots() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int slot) { + return inventory.getStackInSlot(slot); + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + return stack; + } + + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int slot) { + return inventory.getInventoryStackLimit(); + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + inventory.setInventorySlotContents(slot, stack); + } + } + @Override protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { - createCraftingRecipeLogic(entityPlayer); gregtech.api.gui.ModularUI.Builder builder = gregtech.api.gui.ModularUI.builder(gregtech.api.gui.GuiTextures.BACKGROUND, 176, 221) .bindPlayerInventory(entityPlayer.inventory, 138); From 4363a18cf7991dd5f957940224716d23d61ca013 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 22:24:22 -0700 Subject: [PATCH 004/147] add class for jei recipe transfer --- .../api/metatileentity/MetaTileEntity.java | 9 +++++- .../mui/GregTechGuiTransferrableScreen.java | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index c89fe48379d..3d3e34b40d2 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -27,6 +27,7 @@ import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.mui.GTGuiTheme; import gregtech.api.mui.GregTechGuiScreen; +import gregtech.api.mui.GregTechGuiTransferrableScreen; import gregtech.api.mui.factory.MetaTileEntityGuiFactory; import gregtech.api.recipes.RecipeMap; import gregtech.api.util.GTLog; @@ -484,7 +485,13 @@ public boolean usesMui2() { @SideOnly(Side.CLIENT) @Override public final ModularScreen createScreen(PosGuiData posGuiData, ModularPanel mainPanel) { - return new GregTechGuiScreen(mainPanel, getUITheme()); + return createTransferableScreen() ? + new GregTechGuiTransferrableScreen(mainPanel, getUITheme()) : + new GregTechGuiScreen(mainPanel, getUITheme()); + } + + protected boolean createTransferableScreen() { + return false; } public GTGuiTheme getUITheme() { diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java new file mode 100644 index 00000000000..1faca7c6fc7 --- /dev/null +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java @@ -0,0 +1,31 @@ +package gregtech.api.mui; + +import com.cleanroommc.modularui.integration.jei.JeiRecipeTransferHandler; +import com.cleanroommc.modularui.screen.ModularPanel; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; + +@SuppressWarnings("UnstableApiUsage") +public class GregTechGuiTransferrableScreen extends GregTechGuiScreen implements JeiRecipeTransferHandler { + + public GregTechGuiTransferrableScreen(ModularPanel mainPanel) { + super(mainPanel); + } + + public GregTechGuiTransferrableScreen(ModularPanel mainPanel, GTGuiTheme theme) { + super(mainPanel, theme); + } + + public GregTechGuiTransferrableScreen(String owner, ModularPanel mainPanel, GTGuiTheme theme) { + super(owner, mainPanel, theme); + } + + public GregTechGuiTransferrableScreen(String owner, ModularPanel mainPanel, String themeId) { + super(owner, mainPanel, themeId); + } + + @Override + public IRecipeTransferError transferRecipe(IRecipeLayout recipeLayout, boolean maxTransfer, boolean simulate) { + return null; + } +} From e2f9ae12f2f796d86de98c364b9e4d6aca0f3b6e Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:09:13 -0700 Subject: [PATCH 005/147] update recipe appropriately --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 035b741ef76..e0d58f0a09b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -168,7 +168,7 @@ public boolean isRecipeValid() { cachedRecipeData.attemptMatchRecipe() == ALL_INGREDIENTS_PRESENT; } - private void updateCurrentRecipe() { + public void updateCurrentRecipe() { if (!cachedRecipeData.matches(inventoryCrafting, world) || !ItemStack.areItemStacksEqual(oldResult, cachedRecipe.getCraftingResult(inventoryCrafting))) { IRecipe newRecipe = CraftingManager.findMatchingRecipe(inventoryCrafting, world); @@ -191,9 +191,6 @@ public void update() { } else { tintLocation = ALL_INGREDIENTS_PRESENT; } - if (hasCraftingGridUpdated()) { - updateCurrentRecipe(); - } } public short getTintLocations() { From 9fc9a8e2bc193820d2a67c2c6d4070ab9b62dc2f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:09:38 -0700 Subject: [PATCH 006/147] more work on ui --- .../handlers/SingleItemStackHandler.java | 5 ++++ .../storage/MetaTileEntityWorkbench.java | 28 +++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java b/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java index 541b241d308..88410d15faa 100644 --- a/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java +++ b/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java @@ -18,4 +18,9 @@ public SingleItemStackHandler(ItemStack itemStack) { public int getSlotLimit(int slot) { return 1; } + + @Override + protected int getStackLimit(int slot, ItemStack stack) { + return getSlotLimit(slot); + } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index bd1064570fe..22209e2dea3 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -246,11 +246,17 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(SlotGroupWidget.builder() .matrix(craftingGrid) .key(key, i -> new ItemSlot() - .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i))) + .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + this.recipeLogic.updateCurrentRecipe(); + }))) .build()) .child(new ItemSlot() // todo figure this shit (recipe output slot) out - .slot(new InventoryWrapper(this.recipeLogic.getCraftingResultInventory()), 0) + .slot(SyncHandlers + .itemSlot(new InventoryWrapper( + this.recipeLogic.getCraftingResultInventory(), + guiData.getPlayer()), 0)) .background(GTGuiTextures.SLOT.asIcon().size(22)) .align(Alignment.Center)) .child(SlotGroupWidget.builder() @@ -279,13 +285,19 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .bindPlayerInventory(7); } + @Override + protected boolean createTransferableScreen() { + return true; + } - - private static class InventoryWrapper implements IItemHandlerModifiable { + private class InventoryWrapper implements IItemHandlerModifiable { IInventory inventory; - private InventoryWrapper(IInventory inventory) { + EntityPlayer player; + + private InventoryWrapper(IInventory inventory, EntityPlayer player) { this.inventory = inventory; + this.player = player; } @Override @@ -295,7 +307,7 @@ public int getSlots() { @Override public ItemStack getStackInSlot(int slot) { - return inventory.getStackInSlot(slot); + return inventory.getStackInSlot(slot).copy(); } @Override @@ -305,6 +317,9 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (recipeLogic.performRecipe(this.player)) { + return inventory.getStackInSlot(slot).copy(); + } return ItemStack.EMPTY; } @@ -315,6 +330,7 @@ public int getSlotLimit(int slot) { @Override public void setStackInSlot(int slot, ItemStack stack) { + if (stack.isEmpty()) return; inventory.setInventorySlotContents(slot, stack); } } From ec224588bd1d625a260b51eede5b6cd0c898da3c Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:50:02 -0700 Subject: [PATCH 007/147] wrap InventoryCrafting --- .../storage/CraftingRecipeLogic.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index e0d58f0a09b..d572f943b1d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -18,6 +18,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; import com.google.common.collect.Lists; @@ -32,7 +33,7 @@ public class CraftingRecipeLogic { private final ItemSources itemSources; private final ItemStackHandler craftingGrid; private final ItemStack[] oldCraftingGrid = new ItemStack[9]; - private final InventoryCrafting inventoryCrafting = new InventoryCrafting(new DummyContainer(), 3, 3); + private final InventoryCrafting inventoryCrafting; private final IInventory craftingResultInventory = new InventoryCraftResult(); private ItemStack oldResult = ItemStack.EMPTY; private final CachedRecipeData cachedRecipeData; @@ -47,6 +48,7 @@ public CraftingRecipeLogic(ICraftingStorage craftingStorage) { this.craftingGrid = craftingStorage.getCraftingGrid(); this.recipeMemory = craftingStorage.getRecipeMemory(); this.itemSources = new ItemSources(world); + this.inventoryCrafting = new CraftingWrapper(craftingGrid); this.cachedRecipeData = new CachedRecipeData(itemSources, null, inventoryCrafting); } @@ -207,4 +209,30 @@ public void checkNeighbourInventories(BlockPos blockPos) { public CachedRecipeData getCachedRecipeData() { return this.cachedRecipeData; } + + private static class CraftingWrapper extends InventoryCrafting { + + IItemHandlerModifiable craftingHandler; + + public CraftingWrapper(IItemHandlerModifiable craftingHandler) { + super(new DummyContainer(), 3, 3); + this.craftingHandler = craftingHandler; + } + + @Override + public ItemStack getStackInRowAndColumn(int row, int column) { + int index = column + (3 * row); + return this.craftingHandler.getStackInSlot(index); + } + + @Override + public ItemStack getStackInSlot(int index) { + return craftingHandler.getStackInSlot(index); + } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) { + craftingHandler.setStackInSlot(index, stack); + } + } } From 71a3b660e672e52c832e1742de6c9a825e587575 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:50:19 -0700 Subject: [PATCH 008/147] more work on output crafting slot --- .../storage/MetaTileEntityWorkbench.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 22209e2dea3..e70eabaf744 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -317,10 +317,9 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (recipeLogic.performRecipe(this.player)) { - return inventory.getStackInSlot(slot).copy(); - } - return ItemStack.EMPTY; + if (!simulate) recipeLogic.performRecipe(this.player); + if (!recipeLogic.isRecipeValid()) return ItemStack.EMPTY; + return inventory.getStackInSlot(slot).copy(); } @Override @@ -330,8 +329,11 @@ public int getSlotLimit(int slot) { @Override public void setStackInSlot(int slot, ItemStack stack) { - if (stack.isEmpty()) return; - inventory.setInventorySlotContents(slot, stack); + if (!recipeLogic.isRecipeValid()) + inventory.setInventorySlotContents(slot, ItemStack.EMPTY); + + if (!stack.isEmpty()) + inventory.setInventorySlotContents(slot, stack); } } From ebd88df514b4d01da76e20056f3636c665e75765 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 01:51:01 -0700 Subject: [PATCH 009/147] test extending modularslot --- .../storage/MetaTileEntityWorkbench.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index e70eabaf744..d493b998553 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,5 +1,7 @@ package gregtech.common.metatileentities.storage; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; + import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -27,6 +29,7 @@ import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; @@ -253,8 +256,8 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .build()) .child(new ItemSlot() // todo figure this shit (recipe output slot) out - .slot(SyncHandlers - .itemSlot(new InventoryWrapper( + .slot(new CraftingOutputSlot( + new InventoryWrapper( this.recipeLogic.getCraftingResultInventory(), guiData.getPlayer()), 0)) .background(GTGuiTextures.SLOT.asIcon().size(22)) @@ -290,6 +293,18 @@ protected boolean createTransferableScreen() { return true; } + private class CraftingOutputSlot extends ModularSlot { + + public CraftingOutputSlot(IItemHandler itemHandler, int index) { + super(itemHandler, index, false); + } + + @Override + public boolean canTakeStack(EntityPlayer playerIn) { + return recipeLogic.performRecipe(playerIn); + } + } + private class InventoryWrapper implements IItemHandlerModifiable { IInventory inventory; @@ -317,7 +332,6 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (!simulate) recipeLogic.performRecipe(this.player); if (!recipeLogic.isRecipeValid()) return ItemStack.EMPTY; return inventory.getStackInSlot(slot).copy(); } @@ -329,8 +343,11 @@ public int getSlotLimit(int slot) { @Override public void setStackInSlot(int slot, ItemStack stack) { - if (!recipeLogic.isRecipeValid()) + if (!recipeLogic.isRecipeValid()) { inventory.setInventorySlotContents(slot, ItemStack.EMPTY); + } else { + recipeLogic.performRecipe(this.player); + } if (!stack.isEmpty()) inventory.setInventorySlotContents(slot, stack); From e732e9089205c336dafa4a7e062a2491c311f811 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 01:51:13 -0700 Subject: [PATCH 010/147] more work on crafting logic --- .../storage/CachedRecipeData.java | 65 ++++++++++++++----- .../storage/CraftingRecipeLogic.java | 7 +- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 403eed12261..57f7ad40f3a 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -25,24 +25,30 @@ public class CachedRecipeData { private final Object2IntMap requiredItems = new Object2IntOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); private final Int2ObjectMap> replaceAttemptMap = new Int2ObjectArrayMap<>(); - private final InventoryCrafting inventory; + private final InventoryCrafting craftingMatrix; public CachedRecipeData(ItemSources sourceList, IRecipe recipe, InventoryCrafting inventoryCrafting) { this.itemSources = sourceList; this.recipe = recipe; - this.inventory = inventoryCrafting; + this.craftingMatrix = inventoryCrafting; } public short attemptMatchRecipe() { short itemsFound = 0; - this.requiredItems.clear(); - for (int i = 0; i < inventory.getSizeInventory(); i++) { - if (getIngredientEquivalent(i)) - itemsFound += 1 << i; // ingredient was found, and indicate in the short of this fact - } - if (itemsFound != CraftingRecipeLogic.ALL_INGREDIENTS_PRESENT) { - requiredItems.clear(); + int i = 0; + for (int j = 0; j < craftingMatrix.getSizeInventory(); j++) { + var stack = craftingMatrix.getStackInSlot(j); + if (requiredItems.containsKey(stack)) + itemsFound += 1 << i; + i++; } +// for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { +// if (getIngredientEquivalent(i)) +// itemsFound += 1 << i; // ingredient was found, and indicate in the short of this fact +// } +// if (itemsFound != CraftingRecipeLogic.ALL_INGREDIENTS_PRESENT) { +// requiredItems.clear(); +// } return itemsFound; } @@ -75,7 +81,7 @@ protected boolean consumeRecipeItems() { } public boolean getIngredientEquivalent(int slot) { - ItemStack currentStack = inventory.getStackInSlot(slot); + ItemStack currentStack = craftingMatrix.getStackInSlot(slot); if (currentStack.isEmpty()) { return true; // stack is empty, nothing to return } @@ -84,7 +90,7 @@ public boolean getIngredientEquivalent(int slot) { return true; } - ItemStack previousStack = recipe.getCraftingResult(inventory); + ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); @@ -121,9 +127,9 @@ public boolean getIngredientEquivalent(int slot) { } // update item in slot, and check that recipe matches and output item is equal to the expected one - inventory.setInventorySlotContents(slot, itemStack); - if (recipe.matches(inventory, itemSources.getWorld()) && - (ItemStack.areItemStacksEqual(recipe.getCraftingResult(inventory), previousStack) || + craftingMatrix.setInventorySlotContents(slot, itemStack); + if (recipe.matches(craftingMatrix, itemSources.getWorld()) && + (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || recipe instanceof ShapedOreEnergyTransferRecipe)) { map.put(itemStack, true); // ingredient matched, attempt to extract it and return if successful @@ -132,7 +138,7 @@ public boolean getIngredientEquivalent(int slot) { } } map.put(itemStack, false); - inventory.setInventorySlotContents(slot, currentStack); + craftingMatrix.setInventorySlotContents(slot, currentStack); } // nothing matched, so return null return false; @@ -158,6 +164,35 @@ public boolean matches(InventoryCrafting inventoryCrafting, World world) { public void setRecipe(IRecipe newRecipe) { this.recipe = newRecipe; this.replaceAttemptMap.clear(); + this.requiredItems.clear(); + if (this.recipe != null) { + Ingredient[] indexedIng = new Ingredient[craftingMatrix.getSizeInventory()]; + var ingredients = this.recipe.getIngredients(); + + int rolling = 0; + for (int i = 0; i < indexedIng.length; i++) { + var stack = craftingMatrix.getStackInSlot(i); + if (rolling >= ingredients.size()) break; + var ingredient = ingredients.get(rolling); + if (ingredient == Ingredient.EMPTY) { + indexedIng[i] = ingredient; + rolling++; + continue; + } + if (stack.isEmpty()) continue; + indexedIng[i] = ingredient; + rolling++; + } + + for (int i = 0; i < indexedIng.length; i++) { + if (indexedIng[i] == null) continue; + var stack = craftingMatrix.getStackInSlot(i); + int count = requiredItems.getOrDefault(stack, 0) + 1; + if (!stack.isEmpty() && indexedIng[i].apply(stack)) { + requiredItems.put(stack.copy(), count); + } + } + } } public IRecipe getRecipe() { diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index d572f943b1d..fc3c193b5e4 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -166,8 +166,7 @@ public void refreshOutputSlot() { } public boolean isRecipeValid() { - return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world) && - cachedRecipeData.attemptMatchRecipe() == ALL_INGREDIENTS_PRESENT; + return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world); } public void updateCurrentRecipe() { @@ -189,7 +188,7 @@ public void update() { // update item sources every tick for fast tinting updates itemSources.update(); if (getCachedRecipeData().getRecipe() != null) { - tintLocation = getCachedRecipeData().attemptMatchRecipe(); +// tintLocation = getCachedRecipeData().attemptMatchRecipe(); } else { tintLocation = ALL_INGREDIENTS_PRESENT; } @@ -221,7 +220,7 @@ public CraftingWrapper(IItemHandlerModifiable craftingHandler) { @Override public ItemStack getStackInRowAndColumn(int row, int column) { - int index = column + (3 * row); + int index = row + (3 * column); return this.craftingHandler.getStackInSlot(index); } From 74b92dba7338477ff47e99780fb6e7b33538e42c Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:45:04 -0700 Subject: [PATCH 011/147] add method to get inventory --- src/main/java/gregtech/api/storage/ICraftingStorage.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/gregtech/api/storage/ICraftingStorage.java b/src/main/java/gregtech/api/storage/ICraftingStorage.java index 15d49e87511..9c529615ef7 100644 --- a/src/main/java/gregtech/api/storage/ICraftingStorage.java +++ b/src/main/java/gregtech/api/storage/ICraftingStorage.java @@ -3,6 +3,7 @@ import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import net.minecraft.world.World; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; public interface ICraftingStorage { @@ -12,4 +13,6 @@ public interface ICraftingStorage { ItemStackHandler getCraftingGrid(); CraftingRecipeMemory getRecipeMemory(); + + IItemHandler getInventory(); } From 5b9400f4535fa7694a5fa45c2fb64c73689abbdb Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:45:28 -0700 Subject: [PATCH 012/147] implement method --- .../storage/MetaTileEntityWorkbench.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index d493b998553..ef0ee0dd03b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -164,6 +164,20 @@ public void readFromNBT(NBTTagCompound data) { this.recipeMemory.deserializeNBT(data.getCompoundTag("RecipeMemory")); } + @Override + public IItemHandler getInventory() { + var handlerList = new ArrayList(); + for (var facing : EnumFacing.VALUES) { + var neighbor = getNeighbor(facing); + if (neighbor == null) continue; + var handler = neighbor.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()); + if (handler != null) handlerList.add(handler); + } + handlerList.add(this.internalInventory); + handlerList.add(this.toolInventory); + return new ItemHandlerList(handlerList); + } + private void createCraftingRecipeLogic(EntityPlayer entityPlayer) { if (recipeLogic == null) { this.recipeLogic = new CraftingRecipeLogic(this); From 56e7a4b6a44cc3d11f4d829652b5b2ef0918e892 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:46:00 -0700 Subject: [PATCH 013/147] sync crafting matrix --- .../storage/MetaTileEntityWorkbench.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index ef0ee0dd03b..c9c65340ac7 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -2,6 +2,7 @@ import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -14,8 +15,6 @@ import gregtech.common.inventory.IItemList; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; -import gregtech.common.inventory.itemsource.ItemSources; -import gregtech.common.inventory.itemsource.sources.InventoryItemSource; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; @@ -24,11 +23,13 @@ import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; @@ -57,6 +58,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; @@ -143,6 +145,24 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, Textures.CRAFTING_TABLE.renderOriented(renderState, translation, pipeline, getFrontFacing()); } + @Override + public void writeInitialSyncData(@NotNull PacketBuffer buf) { + super.writeInitialSyncData(buf); + for (int i = 0; i < craftingGrid.getSlots(); i++) { + buf.writeItemStack(craftingGrid.getStackInSlot(i)); + } + } + + @Override + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { + super.receiveInitialSyncData(buf); + try { + for (int i = 0; i < craftingGrid.getSlots(); i++) { + craftingGrid.setStackInSlot(i, buf.readItemStack()); + } + } catch (IOException ignored) {} + } + @Override public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); From 50624a198ac9c2597c01174c61583fd66f75aa67 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:46:31 -0700 Subject: [PATCH 014/147] fix some issues with the output slot --- .../storage/MetaTileEntityWorkbench.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index c9c65340ac7..01ed594997d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -202,10 +202,10 @@ private void createCraftingRecipeLogic(EntityPlayer entityPlayer) { if (recipeLogic == null) { this.recipeLogic = new CraftingRecipeLogic(this); this.recipeLogic.setItemsCraftedAmount(itemsCrafted); - ItemSources itemSources = this.recipeLogic.getItemSourceList(); - itemSources.addItemHandler(new InventoryItemSource(getWorld(), toolInventory, -2)); - itemSources.addItemHandler(new InventoryItemSource(getWorld(), internalInventory, -1)); - this.recipeLogic.checkNeighbourInventories(getPos()); +// ItemSources itemSources = this.recipeLogic.getItemSourceList(); +// itemSources.addItemHandler(new InventoryItemSource(getWorld(), toolInventory, -2)); +// itemSources.addItemHandler(new InventoryItemSource(getWorld(), internalInventory, -1)); +// this.recipeLogic.checkNeighbourInventories(getPos()); } this.listeners.add(entityPlayer); } @@ -258,6 +258,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup(toolSlots); guiSyncManager.registerSlotGroup(inventory); createCraftingRecipeLogic(guiData.getPlayer()); + this.recipeLogic.updateCurrentRecipe(); var controller = new PagedWidget.Controller(); @@ -285,15 +286,14 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .key(key, i -> new ItemSlot() .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) .changeListener((newItem, onlyAmountChanged, client, init) -> { - this.recipeLogic.updateCurrentRecipe(); + if (!init) this.recipeLogic.updateCurrentRecipe(); }))) .build()) .child(new ItemSlot() // todo figure this shit (recipe output slot) out - .slot(new CraftingOutputSlot( - new InventoryWrapper( + .slot(new CraftingOutputSlot(new InventoryWrapper( this.recipeLogic.getCraftingResultInventory(), - guiData.getPlayer()), 0)) + guiData.getPlayer()))) .background(GTGuiTextures.SLOT.asIcon().size(22)) .align(Alignment.Center)) .child(SlotGroupWidget.builder() @@ -329,14 +329,20 @@ protected boolean createTransferableScreen() { private class CraftingOutputSlot extends ModularSlot { - public CraftingOutputSlot(IItemHandler itemHandler, int index) { - super(itemHandler, index, false); + public CraftingOutputSlot(IItemHandler itemHandler) { + super(itemHandler, 0, false); } @Override public boolean canTakeStack(EntityPlayer playerIn) { return recipeLogic.performRecipe(playerIn); } + + @Override + public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { + recipeLogic.handleItemCraft(stack, thePlayer); + return super.onTake(thePlayer, stack); + } } private class InventoryWrapper implements IItemHandlerModifiable { @@ -366,8 +372,7 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (!recipeLogic.isRecipeValid()) return ItemStack.EMPTY; - return inventory.getStackInSlot(slot).copy(); + return inventory.getStackInSlot(slot); } @Override @@ -379,8 +384,6 @@ public int getSlotLimit(int slot) { public void setStackInSlot(int slot, ItemStack stack) { if (!recipeLogic.isRecipeValid()) { inventory.setInventorySlotContents(slot, ItemStack.EMPTY); - } else { - recipeLogic.performRecipe(this.player); } if (!stack.isEmpty()) @@ -417,7 +420,7 @@ public void addInformation(ItemStack stack, @Nullable World world, List public void discardRecipeResolver(EntityPlayer entityPlayer) { this.listeners.remove(entityPlayer); if (listeners.isEmpty()) { - if (!getWorld().isRemote && recipeLogic != null) { + if (recipeLogic != null) { itemsCrafted = recipeLogic.getItemsCraftedAmount(); this.markDirty(); } From 51a279a150219af2afe94e0386144b7a805e1bd0 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:47:10 -0700 Subject: [PATCH 015/147] more work on crafting logic woo --- .../storage/CachedRecipeData.java | 266 ++++++++++-------- .../storage/CraftingRecipeLogic.java | 6 +- 2 files changed, 149 insertions(+), 123 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 57f7ad40f3a..a3e72f88356 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -1,158 +1,176 @@ package gregtech.common.metatileentities.storage; import gregtech.api.util.ItemStackHashStrategy; -import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; -import gregtech.common.inventory.IItemList; -import gregtech.common.inventory.itemsource.ItemSources; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.Ingredient; import net.minecraft.world.World; +import net.minecraftforge.items.IItemHandler; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; -import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; public class CachedRecipeData { - private final ItemSources itemSources; +// private final ItemSources itemSources; + private final IItemHandler handlerList; private IRecipe recipe; private final Object2IntMap requiredItems = new Object2IntOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); + private final Object2IntOpenCustomHashMap stackIndex = new Object2IntOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); + + private final Ingredient[] indexedIngredients = new Ingredient[9]; private final Int2ObjectMap> replaceAttemptMap = new Int2ObjectArrayMap<>(); private final InventoryCrafting craftingMatrix; - public CachedRecipeData(ItemSources sourceList, IRecipe recipe, InventoryCrafting inventoryCrafting) { - this.itemSources = sourceList; + public CachedRecipeData(final IItemHandler handlerList, IRecipe recipe, InventoryCrafting inventoryCrafting) { + this.handlerList = handlerList; this.recipe = recipe; this.craftingMatrix = inventoryCrafting; } + public void updateStackIndex() { + this.stackIndex.clear(); + for (int i = 0; i < handlerList.getSlots(); i++) { + var stack = handlerList.extractItem(i, Integer.MAX_VALUE, true); + if (stack.isEmpty()) continue; + this.stackIndex.put(stack, i); + } + } + public short attemptMatchRecipe() { + requiredItems.clear(); short itemsFound = 0; - int i = 0; - for (int j = 0; j < craftingMatrix.getSizeInventory(); j++) { - var stack = craftingMatrix.getStackInSlot(j); - if (requiredItems.containsKey(stack)) - itemsFound += 1 << i; - i++; + for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { + var stack = craftingMatrix.getStackInSlot(i); + + if (indexedIngredients[i] != null && indexedIngredients[i].apply(stack)) { + int count = requiredItems.getOrDefault(stack, 0); + requiredItems.put(stack, ++count); + } + + if (indexedIngredients[i] == null || indexedIngredients[i].apply(stack)) + itemsFound += (short) (1 << i); } -// for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { -// if (getIngredientEquivalent(i)) -// itemsFound += 1 << i; // ingredient was found, and indicate in the short of this fact -// } -// if (itemsFound != CraftingRecipeLogic.ALL_INGREDIENTS_PRESENT) { -// requiredItems.clear(); -// } return itemsFound; } protected boolean consumeRecipeItems() { - boolean gathered = true; Object2IntMap gatheredItems = new Object2IntOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); if (requiredItems.isEmpty()) { return false; } - for (Object2IntMap.Entry entry : requiredItems.object2IntEntrySet()) { + for (var entry : requiredItems.object2IntEntrySet()) { ItemStack stack = entry.getKey(); int requestedAmount = entry.getIntValue(); - int extractedAmount = itemSources.extractItem(stack, requestedAmount, false); - if (extractedAmount != requestedAmount) { - gatheredItems.put(stack.copy(), extractedAmount); - gathered = false; - break; - } else { - gatheredItems.put(stack.copy(), requestedAmount); - } + int extractedAmount = 0; + int index = stackIndex.getOrDefault(stack, -1); + if (index == -1) continue; + var extracted = handlerList.extractItem(index, Integer.MAX_VALUE, true).copy(); + extracted.setCount(requestedAmount); + gatheredItems.put(extracted, index); + extractedAmount += extracted.getCount(); + if (extractedAmount < requestedAmount) return false; } - if (!gathered) { - for (Object2IntMap.Entry entry : gatheredItems.object2IntEntrySet()) { - itemSources.insertItem(entry.getKey(), entry.getIntValue(), false, - IItemList.InsertMode.HIGHEST_PRIORITY); - } - } - return gathered; - } - - public boolean getIngredientEquivalent(int slot) { - ItemStack currentStack = craftingMatrix.getStackInSlot(slot); - if (currentStack.isEmpty()) { - return true; // stack is empty, nothing to return - } - - if (simulateExtractItem(currentStack)) { - return true; - } - - ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); - - Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, - (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); - - // iterate stored items to find equivalent - for (ItemStack itemStack : itemSources.getStoredItems()) { - boolean matchedPreviously = false; - if (map.containsKey(itemStack)) { - if (!map.get(itemStack)) { - continue; - } else { - // cant return here before checking if: - // The item is available for extraction - // The recipe output is still the same, as depending on the ingredient, the output NBT may change - matchedPreviously = true; - } - } - - if (!matchedPreviously) { - boolean matched = false; - // Matching shapeless recipes actually is very bad for performance, as it checks the entire - // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can - // take the stack - for (Ingredient in : recipe.getIngredients()) { - if (in.apply(itemStack)) { - matched = true; - break; - } - } - if (!matched) { - map.put(itemStack.copy(), false); - continue; - } - } - - // update item in slot, and check that recipe matches and output item is equal to the expected one - craftingMatrix.setInventorySlotContents(slot, itemStack); - if (recipe.matches(craftingMatrix, itemSources.getWorld()) && - (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || - recipe instanceof ShapedOreEnergyTransferRecipe)) { - map.put(itemStack, true); - // ingredient matched, attempt to extract it and return if successful - if (simulateExtractItem(itemStack)) { - return true; - } - } - map.put(itemStack, false); - craftingMatrix.setInventorySlotContents(slot, currentStack); + for (var gathered : gatheredItems.entrySet()) { + handlerList.extractItem(gathered.getValue(), gathered.getKey().getCount(), false); } - // nothing matched, so return null - return false; + return !gatheredItems.isEmpty(); +// extractedAmount = itemSources.extractItem(stack, requestedAmount, false); +// if (extractedAmount != requestedAmount) { +// gatheredItems.put(stack.copy(), extractedAmount); +// gathered = false; +// break; +// } else { +// gatheredItems.put(stack.copy(), requestedAmount); +// } +// if (!gathered) { +// for (Object2IntMap.Entry entry : gatheredItems.object2IntEntrySet()) { +// itemSources.insertItem(entry.getKey(), entry.getIntValue(), false, +// IItemList.InsertMode.HIGHEST_PRIORITY); +// } +// } } - private boolean simulateExtractItem(ItemStack itemStack) { - int amountToExtract = requiredItems.getOrDefault(itemStack, 0) + 1; - int extracted = itemSources.extractItem(itemStack, amountToExtract, true); - if (extracted == amountToExtract) { - requiredItems.put(itemStack.copy(), amountToExtract); - return true; - } - return false; - } +// public boolean getIngredientEquivalent(int slot) { +// ItemStack currentStack = craftingMatrix.getStackInSlot(slot); +// if (currentStack.isEmpty()) { +// return true; // stack is empty, nothing to return +// } +// +// if (simulateExtractItem(currentStack)) { +// return true; +// } +// +// ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); +// +// Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, +// (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); +// +// // iterate stored items to find equivalent +// for (ItemStack itemStack : itemSources.getStoredItems()) { +// boolean matchedPreviously = false; +// if (map.containsKey(itemStack)) { +// if (!map.get(itemStack)) { +// continue; +// } else { +// // cant return here before checking if: +// // The item is available for extraction +// // The recipe output is still the same, as depending on the ingredient, the output NBT may change +// matchedPreviously = true; +// } +// } +// +// if (!matchedPreviously) { +// boolean matched = false; +// // Matching shapeless recipes actually is very bad for performance, as it checks the entire +// // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can +// // take the stack +// for (Ingredient in : recipe.getIngredients()) { +// if (in.apply(itemStack)) { +// matched = true; +// break; +// } +// } +// if (!matched) { +// map.put(itemStack.copy(), false); +// continue; +// } +// } +// +// // update item in slot, and check that recipe matches and output item is equal to the expected one +// craftingMatrix.setInventorySlotContents(slot, itemStack); +// if (recipe.matches(craftingMatrix, itemSources.getWorld()) && +// (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || +// recipe instanceof ShapedOreEnergyTransferRecipe)) { +// map.put(itemStack, true); +// // ingredient matched, attempt to extract it and return if successful +// if (simulateExtractItem(itemStack)) { +// return true; +// } +// } +// map.put(itemStack, false); +// craftingMatrix.setInventorySlotContents(slot, currentStack); +// } +// // nothing matched, so return null +// return false; +// } + +// private boolean simulateExtractItem(ItemStack itemStack) { +// int amountToExtract = requiredIngredients.getOrDefault(itemStack, 0) + 1; +// int extracted = itemSources.extractItem(itemStack, amountToExtract, true); +// if (extracted == amountToExtract) { +// requiredIngredients.put(itemStack.copy(), amountToExtract); +// return true; +// } +// return false; +// } public boolean matches(InventoryCrafting inventoryCrafting, World world) { if (recipe == null) { @@ -166,32 +184,38 @@ public void setRecipe(IRecipe newRecipe) { this.replaceAttemptMap.clear(); this.requiredItems.clear(); if (this.recipe != null) { - Ingredient[] indexedIng = new Ingredient[craftingMatrix.getSizeInventory()]; +// Ingredient[] indexedIng = new Ingredient[craftingMatrix.getSizeInventory()]; var ingredients = this.recipe.getIngredients(); +// for (var ing : ingredients) { +// int count = requiredIngredients.getOrDefault(ing, 0) + 1; +// requiredIngredients.put(ing, count); +// } + int rolling = 0; - for (int i = 0; i < indexedIng.length; i++) { + for (int i = 0; i < indexedIngredients.length; i++) { + indexedIngredients[i] = null; var stack = craftingMatrix.getStackInSlot(i); if (rolling >= ingredients.size()) break; var ingredient = ingredients.get(rolling); if (ingredient == Ingredient.EMPTY) { - indexedIng[i] = ingredient; + indexedIngredients[i] = ingredient; rolling++; continue; } if (stack.isEmpty()) continue; - indexedIng[i] = ingredient; + indexedIngredients[i] = ingredient; rolling++; } - for (int i = 0; i < indexedIng.length; i++) { - if (indexedIng[i] == null) continue; - var stack = craftingMatrix.getStackInSlot(i); - int count = requiredItems.getOrDefault(stack, 0) + 1; - if (!stack.isEmpty() && indexedIng[i].apply(stack)) { - requiredItems.put(stack.copy(), count); - } - } +// for (int i = 0; i < indexedIng.length; i++) { +// if (indexedIng[i] == null) continue; +// var stack = craftingMatrix.getStackInSlot(i); +// int count = requiredIngredients.getOrDefault(stack, 0) + 1; +// if (!stack.isEmpty() && indexedIng[i].apply(stack)) { +// requiredIngredients.put(stack.copy(), count); +// } +// } } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index fc3c193b5e4..49b85b4ed81 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -49,7 +49,7 @@ public CraftingRecipeLogic(ICraftingStorage craftingStorage) { this.recipeMemory = craftingStorage.getRecipeMemory(); this.itemSources = new ItemSources(world); this.inventoryCrafting = new CraftingWrapper(craftingGrid); - this.cachedRecipeData = new CachedRecipeData(itemSources, null, inventoryCrafting); + this.cachedRecipeData = new CachedRecipeData(craftingStorage.getInventory(), null, inventoryCrafting); } public ItemSources getItemSourceList() { @@ -109,6 +109,7 @@ public boolean performRecipe(EntityPlayer player) { if (!isRecipeValid()) { return false; } + cachedRecipeData.updateStackIndex(); if (!cachedRecipeData.consumeRecipeItems()) { return false; } @@ -166,7 +167,8 @@ public void refreshOutputSlot() { } public boolean isRecipeValid() { - return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world); + return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world) && + cachedRecipeData.attemptMatchRecipe() == ALL_INGREDIENTS_PRESENT; } public void updateCurrentRecipe() { From ecce71f49b532f5665e41238e91db0643ba61527 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 13:54:39 -0700 Subject: [PATCH 016/147] crafting logic mostly done now? --- .../storage/CachedRecipeData.java | 166 +++++++++--------- .../storage/CraftingRecipeLogic.java | 9 +- 2 files changed, 90 insertions(+), 85 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index a3e72f88356..8019b8c8eb2 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -2,6 +2,10 @@ import gregtech.api.util.ItemStackHashStrategy; +import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; + +import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; + import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; @@ -49,10 +53,7 @@ public short attemptMatchRecipe() { for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { var stack = craftingMatrix.getStackInSlot(i); - if (indexedIngredients[i] != null && indexedIngredients[i].apply(stack)) { - int count = requiredItems.getOrDefault(stack, 0); - requiredItems.put(stack, ++count); - } + if (!getIngredientEquivalent(i)) continue; if (indexedIngredients[i] == null || indexedIngredients[i].apply(stack)) itemsFound += (short) (1 << i); @@ -66,14 +67,16 @@ protected boolean consumeRecipeItems() { if (requiredItems.isEmpty()) { return false; } + for (var entry : requiredItems.object2IntEntrySet()) { ItemStack stack = entry.getKey(); int requestedAmount = entry.getIntValue(); int extractedAmount = 0; int index = stackIndex.getOrDefault(stack, -1); - if (index == -1) continue; - var extracted = handlerList.extractItem(index, Integer.MAX_VALUE, true).copy(); - extracted.setCount(requestedAmount); + if (index == -1) { + continue; + } + var extracted = handlerList.extractItem(index, requestedAmount, true).copy(); gatheredItems.put(extracted, index); extractedAmount += extracted.getCount(); if (extractedAmount < requestedAmount) return false; @@ -98,79 +101,82 @@ protected boolean consumeRecipeItems() { // } } -// public boolean getIngredientEquivalent(int slot) { -// ItemStack currentStack = craftingMatrix.getStackInSlot(slot); -// if (currentStack.isEmpty()) { -// return true; // stack is empty, nothing to return -// } -// -// if (simulateExtractItem(currentStack)) { -// return true; -// } -// -// ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); -// -// Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, -// (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); -// -// // iterate stored items to find equivalent -// for (ItemStack itemStack : itemSources.getStoredItems()) { -// boolean matchedPreviously = false; -// if (map.containsKey(itemStack)) { -// if (!map.get(itemStack)) { -// continue; -// } else { -// // cant return here before checking if: -// // The item is available for extraction -// // The recipe output is still the same, as depending on the ingredient, the output NBT may change -// matchedPreviously = true; -// } -// } -// -// if (!matchedPreviously) { -// boolean matched = false; -// // Matching shapeless recipes actually is very bad for performance, as it checks the entire -// // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can -// // take the stack -// for (Ingredient in : recipe.getIngredients()) { -// if (in.apply(itemStack)) { -// matched = true; -// break; -// } -// } -// if (!matched) { -// map.put(itemStack.copy(), false); -// continue; -// } -// } -// -// // update item in slot, and check that recipe matches and output item is equal to the expected one -// craftingMatrix.setInventorySlotContents(slot, itemStack); -// if (recipe.matches(craftingMatrix, itemSources.getWorld()) && -// (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || -// recipe instanceof ShapedOreEnergyTransferRecipe)) { -// map.put(itemStack, true); -// // ingredient matched, attempt to extract it and return if successful -// if (simulateExtractItem(itemStack)) { -// return true; -// } -// } -// map.put(itemStack, false); -// craftingMatrix.setInventorySlotContents(slot, currentStack); -// } -// // nothing matched, so return null -// return false; -// } - -// private boolean simulateExtractItem(ItemStack itemStack) { -// int amountToExtract = requiredIngredients.getOrDefault(itemStack, 0) + 1; -// int extracted = itemSources.extractItem(itemStack, amountToExtract, true); -// if (extracted == amountToExtract) { -// requiredIngredients.put(itemStack.copy(), amountToExtract); -// return true; -// } -// return false; -// } + public boolean getIngredientEquivalent(int slot) { + ItemStack currentStack = craftingMatrix.getStackInSlot(slot).copy(); + if (currentStack.isEmpty()) { + return true; // stack is empty, nothing to return + } + updateStackIndex(); + + if (simulateExtractItem(currentStack)) { + return true; + } + + ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); + + Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, + (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); + + // iterate stored items to find equivalent + for (int i = 0; i < handlerList.getSlots(); i++) { + var itemStack = handlerList.getStackInSlot(i); + boolean matchedPreviously = false; + if (map.containsKey(itemStack)) { + if (!map.get(itemStack)) { + continue; + } else { + // cant return here before checking if: + // The item is available for extraction + // The recipe output is still the same, as depending on the ingredient, the output NBT may change + matchedPreviously = true; + } + } + + if (!matchedPreviously) { + boolean matched = false; + // Matching shapeless recipes actually is very bad for performance, as it checks the entire + // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can + // take the stack + for (Ingredient in : recipe.getIngredients()) { + if (in.apply(itemStack)) { + matched = true; + break; + } + } + if (!matched) { + map.put(itemStack.copy(), false); + continue; + } + } + + // update item in slot, and check that recipe matches and output item is equal to the expected one + craftingMatrix.setInventorySlotContents(slot, itemStack); + if (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || + recipe instanceof ShapedOreEnergyTransferRecipe) { + map.put(itemStack, true); + // ingredient matched, attempt to extract it and return if successful + if (simulateExtractItem(itemStack)) { + return true; + } + } + map.put(itemStack, false); + craftingMatrix.setInventorySlotContents(slot, currentStack); + } + // nothing matched, so return null + return false; + } + + private boolean simulateExtractItem(ItemStack itemStack) { + int amountToExtract = requiredItems.getOrDefault(itemStack, 0) + 1; + int index = stackIndex.getOrDefault(itemStack, -1); + if (index == -1) return false; + var extracted = handlerList.extractItem(index, amountToExtract, true).copy(); + if (extracted.getCount() == amountToExtract) { + requiredItems.put(extracted, amountToExtract); + return true; + } + return false; + } public boolean matches(InventoryCrafting inventoryCrafting, World world) { if (recipe == null) { diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 49b85b4ed81..43bb9fc2957 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -2,6 +2,7 @@ import gregtech.api.storage.ICraftingStorage; import gregtech.api.util.DummyContainer; +import gregtech.api.util.GTUtility; import gregtech.common.inventory.IItemList; import gregtech.common.inventory.itemsource.ItemSources; import gregtech.common.inventory.itemsource.sources.TileItemSource; @@ -109,8 +110,7 @@ public boolean performRecipe(EntityPlayer player) { if (!isRecipeValid()) { return false; } - cachedRecipeData.updateStackIndex(); - if (!cachedRecipeData.consumeRecipeItems()) { + if (cachedRecipeData.attemptMatchRecipe() != ALL_INGREDIENTS_PRESENT || !cachedRecipeData.consumeRecipeItems()) { return false; } ForgeHooks.setCraftingPlayer(player); @@ -167,8 +167,7 @@ public void refreshOutputSlot() { } public boolean isRecipeValid() { - return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world) && - cachedRecipeData.attemptMatchRecipe() == ALL_INGREDIENTS_PRESENT; + return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world); } public void updateCurrentRecipe() { @@ -233,7 +232,7 @@ public ItemStack getStackInSlot(int index) { @Override public void setInventorySlotContents(int index, ItemStack stack) { - craftingHandler.setStackInSlot(index, stack); + craftingHandler.setStackInSlot(index, GTUtility.copy(1, stack)); } } } From ba8857a55bfd7825fba99ad5165e8cee7c3bb4cd Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:10:53 -0700 Subject: [PATCH 017/147] work on workbench ui add crafting amount to ui --- .../storage/MetaTileEntityWorkbench.java | 54 +++++++++++++------ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 01ed594997d..8b435573ede 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,7 +1,5 @@ package gregtech.common.metatileentities.storage; -import com.cleanroommc.modularui.widgets.slot.ModularSlot; - import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; @@ -42,8 +40,8 @@ import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.PageButton; @@ -51,6 +49,7 @@ import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.layout.Column; import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.base.Preconditions; import org.apache.commons.lang3.ArrayUtils; @@ -260,21 +259,31 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { createCraftingRecipeLogic(guiData.getPlayer()); this.recipeLogic.updateCurrentRecipe(); + var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); + guiSyncManager.syncValue("amount_crafted", amountCrafted); + if (!guiSyncManager.isClient()) { + amountCrafted.setValue(this.itemsCrafted, false, true); + } + var controller = new PagedWidget.Controller(); return GTGuis.createPanel(this, 176, 224) - .child(new Row() - .coverChildren() - .topRel(0f, 4, 1f) + .child(new Row().widthRel(1f) + .leftRel(0.5f) + .margin(2, 0) + .coverChildrenHeight() + .topRel(0f, 3, 1f) .child(new PageButton(0, controller) .tab(GuiTextures.TAB_TOP, 0)) .child(new PageButton(1, controller) .tab(GuiTextures.TAB_TOP, 0))) .child(new PagedWidget<>() - .top(7).leftRel(0.5f) - .coverChildren() + .top(7) + .margin(7) + .expanded() .controller(controller) - .addPage(new Column().coverChildren() + .addPage(new Column() + .coverChildren() .child(new Row().coverChildrenHeight() .widthRel(1f) .marginBottom(2) @@ -289,20 +298,23 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { if (!init) this.recipeLogic.updateCurrentRecipe(); }))) .build()) - .child(new ItemSlot() - // todo figure this shit (recipe output slot) out - .slot(new CraftingOutputSlot(new InventoryWrapper( + .child(new Column() + .size(54) + .child(new ItemSlot().marginTop(18) + // todo figure this shit (recipe output slot) out + .slot(new CraftingOutputSlot(new InventoryWrapper( this.recipeLogic.getCraftingResultInventory(), guiData.getPlayer()))) - .background(GTGuiTextures.SLOT.asIcon().size(22)) - .align(Alignment.Center)) + .background(GTGuiTextures.SLOT.asIcon().size(22)) + .marginBottom(4)) + .child(IKey.dynamic(amountCrafted::getStringValue) + .asWidget())) .child(SlotGroupWidget.builder() .matrix(craftingGrid) .key(key, i -> new ItemSlot() // todo recipe memory .slot(SyncHandlers.phantomItemSlot(new ItemStackHandler(9), i))) - .build() - .right(0))) + .build().right(0))) .child(SlotGroupWidget.builder() .row(nineSlot) .key(key, i -> new ItemSlot() @@ -317,11 +329,19 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .slot(SyncHandlers.itemSlot(this.internalInventory, i) .slotGroup(inventory))) .build())) - .addPage(new Column() + .addPage(new Column().coverChildren() .child(IKey.str("add storage things").asWidget()))) .bindPlayerInventory(7); } + public int getItemsCrafted() { + return this.itemsCrafted; + } + + public void setItemsCrafted(int itemsCrafted) { + this.itemsCrafted = itemsCrafted; + } + @Override protected boolean createTransferableScreen() { return true; From 2417953e81c75bfe010333cd3af2fc41afdf2287 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:51:17 -0700 Subject: [PATCH 018/147] make handlerlist nonfinal add method to update handler --- .../common/metatileentities/storage/CachedRecipeData.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 8019b8c8eb2..c61a41c1562 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -22,7 +22,7 @@ public class CachedRecipeData { // private final ItemSources itemSources; - private final IItemHandler handlerList; + private IItemHandler handlerList; private IRecipe recipe; private final Object2IntMap requiredItems = new Object2IntOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); @@ -47,6 +47,10 @@ public void updateStackIndex() { } } + public void updateInventory(IItemHandler handler) { + this.handlerList = handler; + } + public short attemptMatchRecipe() { requiredItems.clear(); short itemsFound = 0; From 2edbafca8743357b030aba74ec0e3797864b22f1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:51:35 -0700 Subject: [PATCH 019/147] add method to update cache handler --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 43bb9fc2957..225dad996ef 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -19,6 +19,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; @@ -73,6 +74,10 @@ public void clearCraftingGrid() { fillCraftingGrid(Collections.emptyMap()); } + public void updateInventory(IItemHandler handler) { + this.cachedRecipeData.updateInventory(handler); + } + public void fillCraftingGrid(Map ingredients) { for (int i = 0; i < craftingGrid.getSlots(); i++) { craftingGrid.setStackInSlot(i, ingredients.getOrDefault(i + 1, ItemStack.EMPTY)); From 6207fc27457bfe04c1f122a89e2a0627ddfb4df5 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:52:38 -0700 Subject: [PATCH 020/147] even more ui work sync item crafted amount update recipe logic inventory on neighbor change --- .../storage/MetaTileEntityWorkbench.java | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 8b435573ede..5b75a808f46 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,5 +1,7 @@ package gregtech.common.metatileentities.storage; +import com.cleanroommc.modularui.utils.Alignment; + import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; @@ -147,6 +149,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, @Override public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); + buf.writeInt(this.itemsCrafted); for (int i = 0; i < craftingGrid.getSlots(); i++) { buf.writeItemStack(craftingGrid.getStackInSlot(i)); } @@ -155,6 +158,7 @@ public void writeInitialSyncData(@NotNull PacketBuffer buf) { @Override public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); + this.itemsCrafted = buf.readInt(); try { for (int i = 0; i < craftingGrid.getSlots(); i++) { craftingGrid.setStackInSlot(i, buf.readItemStack()); @@ -201,10 +205,6 @@ private void createCraftingRecipeLogic(EntityPlayer entityPlayer) { if (recipeLogic == null) { this.recipeLogic = new CraftingRecipeLogic(this); this.recipeLogic.setItemsCraftedAmount(itemsCrafted); -// ItemSources itemSources = this.recipeLogic.getItemSourceList(); -// itemSources.addItemHandler(new InventoryItemSource(getWorld(), toolInventory, -2)); -// itemSources.addItemHandler(new InventoryItemSource(getWorld(), internalInventory, -1)); -// this.recipeLogic.checkNeighbourInventories(getPos()); } this.listeners.add(entityPlayer); } @@ -219,6 +219,11 @@ public void update() { } } + @Override + public void onNeighborChanged() { + this.recipeLogic.updateInventory(getInventory()); + } + private CraftingRecipeLogic getCraftingRecipeLogic() { Preconditions.checkState(getWorld() != null, "getRecipeResolver called too early"); return recipeLogic; @@ -261,9 +266,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); guiSyncManager.syncValue("amount_crafted", amountCrafted); - if (!guiSyncManager.isClient()) { - amountCrafted.setValue(this.itemsCrafted, false, true); - } + amountCrafted.updateCacheFromSource(true); var controller = new PagedWidget.Controller(); @@ -295,7 +298,9 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .key(key, i -> new ItemSlot() .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) .changeListener((newItem, onlyAmountChanged, client, init) -> { - if (!init) this.recipeLogic.updateCurrentRecipe(); + if (!init) { + this.recipeLogic.updateCurrentRecipe(); + } }))) .build()) .child(new Column() @@ -304,11 +309,12 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { // todo figure this shit (recipe output slot) out .slot(new CraftingOutputSlot(new InventoryWrapper( this.recipeLogic.getCraftingResultInventory(), - guiData.getPlayer()))) + guiData.getPlayer()), amountCrafted)) .background(GTGuiTextures.SLOT.asIcon().size(22)) .marginBottom(4)) .child(IKey.dynamic(amountCrafted::getStringValue) - .asWidget())) + .alignment(Alignment.Center) + .asWidget().width(22))) .child(SlotGroupWidget.builder() .matrix(craftingGrid) .key(key, i -> new ItemSlot() @@ -348,14 +354,20 @@ protected boolean createTransferableScreen() { } private class CraftingOutputSlot extends ModularSlot { + IntSyncValue syncValue; - public CraftingOutputSlot(IItemHandler itemHandler) { + public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { super(itemHandler, 0, false); + this.syncValue = syncValue; } @Override public boolean canTakeStack(EntityPlayer playerIn) { - return recipeLogic.performRecipe(playerIn); + boolean success = recipeLogic.performRecipe(playerIn); + if (success) { + this.syncValue.setValue(this.syncValue.getValue() + 1, true, false); + } + return success; } @Override From f97a9b926cb9060758ffcdc705d0a9fd8f876135 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:58:46 -0700 Subject: [PATCH 021/147] the great commenting of 2024 --- .../craftingstation/CraftingSlotWidget.java | 158 ++++++++--------- .../storage/CraftingRecipeLogic.java | 66 +++---- .../storage/MetaTileEntityWorkbench.java | 162 +++++++++--------- 3 files changed, 180 insertions(+), 206 deletions(-) diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java index 973ef3c478b..ae16bd40a39 100644 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java @@ -40,85 +40,85 @@ private static IInventory createInventory(CraftingRecipeLogic resolver) { @Override public void handleClientAction(int id, PacketBuffer buffer) { super.handleClientAction(id, buffer); - if (id == 1) { - HashMap ingredients = new HashMap<>(); - int ingredientAmount = buffer.readVarInt(); - try { - for (int i = 0; i < ingredientAmount; i++) { - ingredients.put(buffer.readVarInt(), buffer.readItemStack()); - } - } catch (IOException exception) { - throw new RuntimeException(exception); - } - recipeResolver.fillCraftingGrid(ingredients); - } - if (id == 2) { - if (recipeResolver.isRecipeValid()) { - ClickData clickData = ClickData.readFromBuf(buffer); - boolean isShiftDown = clickData.isShiftClick; - boolean isLeftClick = clickData.button == 0; - boolean isRightClick = clickData.button == 1; - EntityPlayer player = gui.entityPlayer; - if (isShiftDown) { - OverlayedItemHandler playerInventory = new OverlayedItemHandler( - new PlayerMainInvWrapper(gui.entityPlayer.inventory)); - ItemStack toMerge = slotReference.getStack(); - int crafts = this.slotReference.getStack().getCount(); - if (isLeftClick) { - if (crafts != 0) { - // limit shift click to one stack at a time - int totalCrafts = 0; - int maxCrafts = toMerge.getMaxStackSize() / crafts; - for (int i = 0; i < maxCrafts; i++) { - if (canMergeToInv(playerInventory, toMerge, crafts) && - recipeResolver.performRecipe(gui.entityPlayer)) { - this.recipeResolver.refreshOutputSlot(); - recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - totalCrafts += crafts; - } - } - ItemStack toAdd = this.slotReference.getStack().copy(); - toAdd.setCount(totalCrafts); - player.inventory.addItemStackToInventory(toAdd); - } - } else if (isRightClick) { - int totalCrafts = 0; - while (canMergeToInv(playerInventory, toMerge, crafts) && - recipeResolver.performRecipe(gui.entityPlayer)) { - this.recipeResolver.refreshOutputSlot(); - recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - totalCrafts += crafts; - } - ItemStack toAdd = this.slotReference.getStack().copy(); - toAdd.setCount(totalCrafts); - player.inventory.addItemStackToInventory(toAdd); - } - } else { - if (isLeftClick) { - if (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && - recipeResolver.performRecipe(gui.entityPlayer)) { - this.recipeResolver.refreshOutputSlot(); - recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - // send slot changes now, both of consumed items in inventory and result slot - ItemStack result = this.slotReference.getStack(); - mergeToHand(result); - } - } else if (isRightClick) { - while (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && - recipeResolver.performRecipe(gui.entityPlayer)) { - this.recipeResolver.refreshOutputSlot(); - recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - ItemStack result = this.slotReference.getStack(); - mergeToHand(result); - } - } - } - uiAccess.sendHeldItemUpdate(); - // send slot changes now, both of consumed items in inventory and result slot - gui.entityPlayer.openContainer.detectAndSendChanges(); - uiAccess.sendSlotUpdate(this); - } - } +// if (id == 1) { +// HashMap ingredients = new HashMap<>(); +// int ingredientAmount = buffer.readVarInt(); +// try { +// for (int i = 0; i < ingredientAmount; i++) { +// ingredients.put(buffer.readVarInt(), buffer.readItemStack()); +// } +// } catch (IOException exception) { +// throw new RuntimeException(exception); +// } +// recipeResolver.fillCraftingGrid(ingredients); +// } +// if (id == 2) { +// if (recipeResolver.isRecipeValid()) { +// ClickData clickData = ClickData.readFromBuf(buffer); +// boolean isShiftDown = clickData.isShiftClick; +// boolean isLeftClick = clickData.button == 0; +// boolean isRightClick = clickData.button == 1; +// EntityPlayer player = gui.entityPlayer; +// if (isShiftDown) { +// OverlayedItemHandler playerInventory = new OverlayedItemHandler( +// new PlayerMainInvWrapper(gui.entityPlayer.inventory)); +// ItemStack toMerge = slotReference.getStack(); +// int crafts = this.slotReference.getStack().getCount(); +// if (isLeftClick) { +// if (crafts != 0) { +// // limit shift click to one stack at a time +// int totalCrafts = 0; +// int maxCrafts = toMerge.getMaxStackSize() / crafts; +// for (int i = 0; i < maxCrafts; i++) { +// if (canMergeToInv(playerInventory, toMerge, crafts) && +// recipeResolver.performRecipe(gui.entityPlayer)) { +// this.recipeResolver.refreshOutputSlot(); +// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); +// totalCrafts += crafts; +// } +// } +// ItemStack toAdd = this.slotReference.getStack().copy(); +// toAdd.setCount(totalCrafts); +// player.inventory.addItemStackToInventory(toAdd); +// } +// } else if (isRightClick) { +// int totalCrafts = 0; +// while (canMergeToInv(playerInventory, toMerge, crafts) && +// recipeResolver.performRecipe(gui.entityPlayer)) { +// this.recipeResolver.refreshOutputSlot(); +// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); +// totalCrafts += crafts; +// } +// ItemStack toAdd = this.slotReference.getStack().copy(); +// toAdd.setCount(totalCrafts); +// player.inventory.addItemStackToInventory(toAdd); +// } +// } else { +// if (isLeftClick) { +// if (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && +// recipeResolver.performRecipe(gui.entityPlayer)) { +// this.recipeResolver.refreshOutputSlot(); +// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); +// // send slot changes now, both of consumed items in inventory and result slot +// ItemStack result = this.slotReference.getStack(); +// mergeToHand(result); +// } +// } else if (isRightClick) { +// while (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && +// recipeResolver.performRecipe(gui.entityPlayer)) { +// this.recipeResolver.refreshOutputSlot(); +// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); +// ItemStack result = this.slotReference.getStack(); +// mergeToHand(result); +// } +// } +// } +// uiAccess.sendHeldItemUpdate(); +// // send slot changes now, both of consumed items in inventory and result slot +// gui.entityPlayer.openContainer.detectAndSendChanges(); +// uiAccess.sendSlotUpdate(this); +// } +// } } private static boolean canMerge(ItemStack stack, ItemStack stack1) { diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 225dad996ef..b3bf6af4964 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -71,45 +71,18 @@ public void setItemsCraftedAmount(int itemsCrafted) { } public void clearCraftingGrid() { - fillCraftingGrid(Collections.emptyMap()); +// fillCraftingGrid(Collections.emptyMap()); } public void updateInventory(IItemHandler handler) { this.cachedRecipeData.updateInventory(handler); } - public void fillCraftingGrid(Map ingredients) { - for (int i = 0; i < craftingGrid.getSlots(); i++) { - craftingGrid.setStackInSlot(i, ingredients.getOrDefault(i + 1, ItemStack.EMPTY)); - } - } - - private boolean hasCraftingGridUpdated() { - boolean craftingGridChanged = false; - for (int i = 0; i < craftingGrid.getSlots(); i++) { - ItemStack oldStack = oldCraftingGrid[i]; - ItemStack newStack = craftingGrid.getStackInSlot(i); - if (oldStack == null || oldStack.isEmpty()) { - if (newStack.isEmpty()) { - continue; - } - oldStack = newStack; - oldCraftingGrid[i] = oldStack; - inventoryCrafting.setInventorySlotContents(i, newStack.copy()); - craftingGridChanged = true; - } else if (newStack.isEmpty()) { - oldCraftingGrid[i] = null; - inventoryCrafting.setInventorySlotContents(i, ItemStack.EMPTY); - craftingGridChanged = true; - } else if (!ItemStack.areItemsEqual(oldStack, newStack) || - !ItemStack.areItemStackTagsEqual(oldStack, newStack)) { - oldCraftingGrid[i] = newStack; - inventoryCrafting.setInventorySlotContents(i, newStack.copy()); - craftingGridChanged = true; - } - } - return craftingGridChanged; - } +// public void fillCraftingGrid(Map ingredients) { +// for (int i = 0; i < craftingGrid.getSlots(); i++) { +// craftingGrid.setStackInSlot(i, ingredients.getOrDefault(i + 1, ItemStack.EMPTY)); +// } +// } public boolean performRecipe(EntityPlayer player) { if (!isRecipeValid()) { @@ -163,13 +136,13 @@ public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { } } - public void refreshOutputSlot() { - ItemStack itemStack = ItemStack.EMPTY; - if (cachedRecipe != null) { - itemStack = cachedRecipe.getCraftingResult(inventoryCrafting); - } - this.craftingResultInventory.setInventorySlotContents(0, itemStack); - } +// public void refreshOutputSlot() { +// ItemStack itemStack = ItemStack.EMPTY; +// if (cachedRecipe != null) { +// itemStack = cachedRecipe.getCraftingResult(inventoryCrafting); +// } +// this.craftingResultInventory.setInventorySlotContents(0, itemStack); +// } public boolean isRecipeValid() { return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world); @@ -194,6 +167,7 @@ public void update() { // update item sources every tick for fast tinting updates itemSources.update(); if (getCachedRecipeData().getRecipe() != null) { + //todo fix tint location // tintLocation = getCachedRecipeData().attemptMatchRecipe(); } else { tintLocation = ALL_INGREDIENTS_PRESENT; @@ -204,12 +178,12 @@ public short getTintLocations() { return tintLocation; } - public void checkNeighbourInventories(BlockPos blockPos) { - for (EnumFacing side : EnumFacing.VALUES) { - TileItemSource itemSource = new TileItemSource(world, blockPos, side); - this.itemSources.addItemHandler(itemSource); - } - } +// public void checkNeighbourInventories(BlockPos blockPos) { +// for (EnumFacing side : EnumFacing.VALUES) { +// TileItemSource itemSource = new TileItemSource(world, blockPos, side); +// this.itemSources.addItemHandler(itemSource); +// } +// } public CachedRecipeData getCachedRecipeData() { return this.cachedRecipeData; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 5b75a808f46..324ee2d2109 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -81,47 +81,47 @@ public MetaTileEntityWorkbench(ResourceLocation metaTileEntityId) { super(metaTileEntityId); } - public static gregtech.api.gui.widgets.AbstractWidgetGroup createWorkbenchTab(CraftingRecipeLogic craftingRecipeLogic, - ItemStackHandler craftingGrid, - CraftingRecipeMemory recipeMemory, - ItemStackHandler toolInventory, - ItemStackHandler internalInventory) { - gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); - widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(88 - 13, 44 - 14, 26, 26, gregtech.api.gui.GuiTextures.SLOT)); - widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.CraftingSlotWidget(craftingRecipeLogic, 0, 88 - 9, 44 - 9)); - - // crafting grid - widgetGroup.addWidget(new gregtech.api.gui.widgets.CraftingStationInputWidgetGroup(4, 7, craftingGrid, craftingRecipeLogic)); - - Supplier textSupplier = () -> Integer.toString(craftingRecipeLogic.getItemsCraftedAmount()); - widgetGroup.addWidget(new gregtech.api.gui.widgets.SimpleTextWidget(88, 44 + 19, "", textSupplier)); - - Consumer clearAction = (clickData) -> craftingRecipeLogic.clearCraftingGrid(); - widgetGroup.addWidget(new gregtech.api.gui.widgets.ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction) - .setButtonTexture(gregtech.api.gui.GuiTextures.BUTTON_CLEAR_GRID)); - - widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, - gregtech.api.gui.resources.TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget(recipeMemory, j + i * 3, craftingGrid, - 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); - } - } - // tool inventory - for (int i = 0; i < 9; i++) { - widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(toolInventory, i, 7 + i * 18, 75) - .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, gregtech.api.gui.GuiTextures.TOOL_SLOT_OVERLAY)); - } - // internal inventory - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < 9; ++j) { - widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * 18) - .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); - } - } - return widgetGroup; - } +// public static gregtech.api.gui.widgets.AbstractWidgetGroup createWorkbenchTab(CraftingRecipeLogic craftingRecipeLogic, +// ItemStackHandler craftingGrid, +// CraftingRecipeMemory recipeMemory, +// ItemStackHandler toolInventory, +// ItemStackHandler internalInventory) { +// gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); +// widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(88 - 13, 44 - 14, 26, 26, gregtech.api.gui.GuiTextures.SLOT)); +// widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.CraftingSlotWidget(craftingRecipeLogic, 0, 88 - 9, 44 - 9)); +// +// // crafting grid +// widgetGroup.addWidget(new gregtech.api.gui.widgets.CraftingStationInputWidgetGroup(4, 7, craftingGrid, craftingRecipeLogic)); +// +// Supplier textSupplier = () -> Integer.toString(craftingRecipeLogic.getItemsCraftedAmount()); +// widgetGroup.addWidget(new gregtech.api.gui.widgets.SimpleTextWidget(88, 44 + 19, "", textSupplier)); +// +// Consumer clearAction = (clickData) -> craftingRecipeLogic.clearCraftingGrid(); +// widgetGroup.addWidget(new gregtech.api.gui.widgets.ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction) +// .setButtonTexture(gregtech.api.gui.GuiTextures.BUTTON_CLEAR_GRID)); +// +// widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, +// gregtech.api.gui.resources.TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); +// for (int i = 0; i < 3; ++i) { +// for (int j = 0; j < 3; ++j) { +// widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget(recipeMemory, j + i * 3, craftingGrid, +// 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); +// } +// } +// // tool inventory +// for (int i = 0; i < 9; i++) { +// widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(toolInventory, i, 7 + i * 18, 75) +// .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, gregtech.api.gui.GuiTextures.TOOL_SLOT_OVERLAY)); +// } +// // internal inventory +// for (int i = 0; i < 2; ++i) { +// for (int j = 0; j < 9; ++j) { +// widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * 18) +// .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); +// } +// } +// return widgetGroup; +// } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { @@ -149,7 +149,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, @Override public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); - buf.writeInt(this.itemsCrafted); + buf.writeInt(this.recipeLogic.getItemsCraftedAmount()); for (int i = 0; i < craftingGrid.getSlots(); i++) { buf.writeItemStack(craftingGrid.getStackInSlot(i)); } @@ -158,7 +158,7 @@ public void writeInitialSyncData(@NotNull PacketBuffer buf) { @Override public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); - this.itemsCrafted = buf.readInt(); + this.recipeLogic.setItemsCraftedAmount(buf.readInt()); try { for (int i = 0; i < craftingGrid.getSlots(); i++) { craftingGrid.setStackInSlot(i, buf.readItemStack()); @@ -236,15 +236,15 @@ public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) clearInventory(itemBuffer, toolInventory); } - private gregtech.api.gui.widgets.AbstractWidgetGroup createItemListTab() { - gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); - widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 20, "gregtech.machine.workbench.storage_note_1")); - widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 30, "gregtech.machine.workbench.storage_note_2")); - CraftingRecipeLogic recipeResolver = getCraftingRecipeLogic(); - IItemList itemList = recipeResolver == null ? null : recipeResolver.getItemSourceList(); - widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.ItemListGridWidget(11, 45, 8, 5, itemList)); - return widgetGroup; - } +// private gregtech.api.gui.widgets.AbstractWidgetGroup createItemListTab() { +// gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); +// widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 20, "gregtech.machine.workbench.storage_note_1")); +// widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 30, "gregtech.machine.workbench.storage_note_2")); +// CraftingRecipeLogic recipeResolver = getCraftingRecipeLogic(); +// IItemList itemList = recipeResolver == null ? null : recipeResolver.getItemSourceList(); +// widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.ItemListGridWidget(11, 45, 8, 5, itemList)); +// return widgetGroup; +// } @Override public boolean usesMui2() { @@ -423,25 +423,25 @@ public void setStackInSlot(int slot, ItemStack stack) { } } - @Override - protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { - - gregtech.api.gui.ModularUI.Builder builder = gregtech.api.gui.ModularUI.builder(gregtech.api.gui.GuiTextures.BACKGROUND, 176, 221) - .bindPlayerInventory(entityPlayer.inventory, 138); - builder.label(5, 5, getMetaFullName()); - - gregtech.api.gui.widgets.TabGroup tabGroup = new gregtech.api.gui.widgets.TabGroup<>( - gregtech.api.gui.widgets.TabGroup.TabLocation.HORIZONTAL_TOP_LEFT, Position.ORIGIN); - tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.workbench", - new ItemStack(Blocks.CRAFTING_TABLE)), - createWorkbenchTab(recipeLogic, craftingGrid, recipeMemory, toolInventory, internalInventory)); - tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.item_list", - new ItemStack(Blocks.CHEST)), createItemListTab()); - builder.widget(tabGroup); - builder.bindCloseListener(() -> discardRecipeResolver(entityPlayer)); - - return builder.build(getHolder(), entityPlayer); - } +// @Override +// protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { +// +// gregtech.api.gui.ModularUI.Builder builder = gregtech.api.gui.ModularUI.builder(gregtech.api.gui.GuiTextures.BACKGROUND, 176, 221) +// .bindPlayerInventory(entityPlayer.inventory, 138); +// builder.label(5, 5, getMetaFullName()); +// +// gregtech.api.gui.widgets.TabGroup tabGroup = new gregtech.api.gui.widgets.TabGroup<>( +// gregtech.api.gui.widgets.TabGroup.TabLocation.HORIZONTAL_TOP_LEFT, Position.ORIGIN); +// tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.workbench", +// new ItemStack(Blocks.CRAFTING_TABLE)), +// createWorkbenchTab(recipeLogic, craftingGrid, recipeMemory, toolInventory, internalInventory)); +// tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.item_list", +// new ItemStack(Blocks.CHEST)), createItemListTab()); +// builder.widget(tabGroup); +// builder.bindCloseListener(() -> discardRecipeResolver(entityPlayer)); +// +// return builder.build(getHolder(), entityPlayer); +// } @Override public void addInformation(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { @@ -449,16 +449,16 @@ public void addInformation(ItemStack stack, @Nullable World world, List tooltip.add(I18n.format("gregtech.machine.workbench.tooltip2")); } - public void discardRecipeResolver(EntityPlayer entityPlayer) { - this.listeners.remove(entityPlayer); - if (listeners.isEmpty()) { - if (recipeLogic != null) { - itemsCrafted = recipeLogic.getItemsCraftedAmount(); - this.markDirty(); - } - recipeLogic = null; - } - } +// public void discardRecipeResolver(EntityPlayer entityPlayer) { +// this.listeners.remove(entityPlayer); +// if (listeners.isEmpty()) { +// if (recipeLogic != null) { +// itemsCrafted = recipeLogic.getItemsCraftedAmount(); +// this.markDirty(); +// } +// recipeLogic = null; +// } +// } public ItemStackHandler getCraftingGrid() { return craftingGrid; From ee3304cd27fd90fbe3024af3cc5cca1a224d686b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:58:47 -0700 Subject: [PATCH 022/147] update stack index --- .../common/metatileentities/storage/CachedRecipeData.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index c61a41c1562..2c9e6e3c6b5 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -49,6 +49,7 @@ public void updateStackIndex() { public void updateInventory(IItemHandler handler) { this.handlerList = handler; + updateStackIndex(); } public short attemptMatchRecipe() { From 0ed6d7e75bfb9d81a61104e713708c7459c62ce0 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:59:38 -0700 Subject: [PATCH 023/147] revert change to itemCrafting fix issue with temp tool slot "overlay" --- .../metatileentities/storage/MetaTileEntityWorkbench.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 324ee2d2109..4b5c61c2110 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -149,7 +149,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, @Override public void writeInitialSyncData(@NotNull PacketBuffer buf) { super.writeInitialSyncData(buf); - buf.writeInt(this.recipeLogic.getItemsCraftedAmount()); + buf.writeInt(this.itemsCrafted); for (int i = 0; i < craftingGrid.getSlots(); i++) { buf.writeItemStack(craftingGrid.getStackInSlot(i)); } @@ -158,7 +158,7 @@ public void writeInitialSyncData(@NotNull PacketBuffer buf) { @Override public void receiveInitialSyncData(@NotNull PacketBuffer buf) { super.receiveInitialSyncData(buf); - this.recipeLogic.setItemsCraftedAmount(buf.readInt()); + this.itemsCrafted = buf.readInt(); try { for (int i = 0; i < craftingGrid.getSlots(); i++) { craftingGrid.setStackInSlot(i, buf.readItemStack()); @@ -172,7 +172,7 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { data.setTag("CraftingGridInventory", craftingGrid.serializeNBT()); data.setTag("ToolInventory", toolInventory.serializeNBT()); data.setTag("InternalInventory", internalInventory.serializeNBT()); - data.setInteger("ItemsCrafted", recipeLogic == null ? itemsCrafted : recipeLogic.getItemsCraftedAmount()); + data.setInteger("ItemsCrafted", itemsCrafted); data.setTag("RecipeMemory", recipeMemory.serializeNBT()); return data; } @@ -324,7 +324,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(SlotGroupWidget.builder() .row(nineSlot) .key(key, i -> new ItemSlot() - .overlay(GTGuiTextures.INGOT_OVERLAY) + .background(GTGuiTextures.SLOT, GTGuiTextures.INGOT_OVERLAY) .slot(SyncHandlers.itemSlot(this.toolInventory, i) .slotGroup(toolSlots))) .build().marginBottom(2)) From a05dd0595b0a7469ca0dd7775a46483e5b91744a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 27 Jan 2024 20:21:44 -0700 Subject: [PATCH 024/147] simplify crafting logic slightly --- .../common/metatileentities/storage/CachedRecipeData.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 2c9e6e3c6b5..8d77332c83b 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -53,14 +53,9 @@ public void updateInventory(IItemHandler handler) { } public short attemptMatchRecipe() { - requiredItems.clear(); short itemsFound = 0; for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { - var stack = craftingMatrix.getStackInSlot(i); - - if (!getIngredientEquivalent(i)) continue; - - if (indexedIngredients[i] == null || indexedIngredients[i].apply(stack)) + if (getIngredientEquivalent(i)) itemsFound += (short) (1 << i); } return itemsFound; @@ -112,6 +107,7 @@ public boolean getIngredientEquivalent(int slot) { return true; // stack is empty, nothing to return } updateStackIndex(); + requiredItems.clear(); if (simulateExtractItem(currentStack)) { return true; From d4c0347ffd71ff43080569117cb29023302fd208 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 27 Jan 2024 20:23:50 -0700 Subject: [PATCH 025/147] more work on recipe logic make recipe logic a sync handler more work on station ui --- .../storage/CraftingRecipeLogic.java | 87 ++++++++++--------- .../storage/MetaTileEntityWorkbench.java | 59 +++++++++---- 2 files changed, 86 insertions(+), 60 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index b3bf6af4964..4682be7bb7a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -2,10 +2,9 @@ import gregtech.api.storage.ICraftingStorage; import gregtech.api.util.DummyContainer; +import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; -import gregtech.common.inventory.IItemList; import gregtech.common.inventory.itemsource.ItemSources; -import gregtech.common.inventory.itemsource.sources.TileItemSource; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; @@ -14,60 +13,50 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.NonNullList; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; -import com.google.common.collect.Lists; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; -public class CraftingRecipeLogic { +public class CraftingRecipeLogic extends SyncHandler { private final World world; - private final ItemSources itemSources; + private IItemHandler handlerList; private final ItemStackHandler craftingGrid; - private final ItemStack[] oldCraftingGrid = new ItemStack[9]; private final InventoryCrafting inventoryCrafting; private final IInventory craftingResultInventory = new InventoryCraftResult(); private ItemStack oldResult = ItemStack.EMPTY; private final CachedRecipeData cachedRecipeData; - private final CraftingRecipeMemory recipeMemory; private IRecipe cachedRecipe = null; - private int itemsCrafted = 0; public static short ALL_INGREDIENTS_PRESENT = 511; private short tintLocation = ALL_INGREDIENTS_PRESENT; public CraftingRecipeLogic(ICraftingStorage craftingStorage) { this.world = craftingStorage.getWorld(); this.craftingGrid = craftingStorage.getCraftingGrid(); - this.recipeMemory = craftingStorage.getRecipeMemory(); - this.itemSources = new ItemSources(world); + this.handlerList = craftingStorage.getInventory(); this.inventoryCrafting = new CraftingWrapper(craftingGrid); - this.cachedRecipeData = new CachedRecipeData(craftingStorage.getInventory(), null, inventoryCrafting); - } - - public ItemSources getItemSourceList() { - return itemSources; + this.cachedRecipeData = new CachedRecipeData(this.handlerList, null, inventoryCrafting); } public IInventory getCraftingResultInventory() { return craftingResultInventory; } - public int getItemsCraftedAmount() { - return itemsCrafted; - } - - public void setItemsCraftedAmount(int itemsCrafted) { - this.itemsCrafted = itemsCrafted; + public InventoryCrafting getCraftingMatrix() { + return this.inventoryCrafting; } public void clearCraftingGrid() { @@ -103,16 +92,14 @@ public boolean performRecipe(EntityPlayer player) { ItemStack current = inventoryCrafting.getStackInSlot(i); inventoryCrafting.setInventorySlotContents(i, itemStack); - if (!cachedRecipe.matches(inventoryCrafting, itemSources.getWorld())) { + if (!cachedRecipe.matches(inventoryCrafting, this.world)) { inventoryCrafting.setInventorySlotContents(i, current); } - int remainingAmount = itemStack.getCount() - itemSources.insertItem(itemStack, itemStack.getCount(), false, - IItemList.InsertMode.HIGHEST_PRIORITY); + int remainingAmount = itemStack.getCount() - GTTransferUtils.insertItem(this.handlerList, itemStack, false).getCount(); if (remainingAmount > 0) { itemStack.setCount(remainingAmount); - player.addItemStackToInventory(itemStack); - if (itemStack.getCount() > 0) { + if (!player.addItemStackToInventory(itemStack)) { player.dropItem(itemStack, false, false); } } @@ -120,21 +107,21 @@ public boolean performRecipe(EntityPlayer player) { return true; } - public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { - itemStack.onCrafting(world, player, 1); - itemStack.getItem().onCreated(itemStack, world, player); - // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds - FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); - - if (cachedRecipe != null && !cachedRecipe.isDynamic()) { - player.unlockRecipes(Lists.newArrayList(cachedRecipe)); - } - if (cachedRecipe != null) { - ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); - this.itemsCrafted += resultStack.getCount(); - recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); - } - } +// public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { +// itemStack.onCrafting(world, player, 1); +// itemStack.getItem().onCreated(itemStack, world, player); +// // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds +// FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); +// +// if (cachedRecipe != null && !cachedRecipe.isDynamic()) { +// player.unlockRecipes(Lists.newArrayList(cachedRecipe)); +// } +// if (cachedRecipe != null) { +// ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); +// this.itemsCrafted += resultStack.getCount(); +// recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); +// } +// } // public void refreshOutputSlot() { // ItemStack itemStack = ItemStack.EMPTY; @@ -163,9 +150,13 @@ public void updateCurrentRecipe() { } } + public IRecipe getCachedRecipe() { + return this.cachedRecipe; + } + public void update() { // update item sources every tick for fast tinting updates - itemSources.update(); +// itemSources.update(); if (getCachedRecipeData().getRecipe() != null) { //todo fix tint location // tintLocation = getCachedRecipeData().attemptMatchRecipe(); @@ -189,6 +180,16 @@ public CachedRecipeData getCachedRecipeData() { return this.cachedRecipeData; } + @Override + public void readOnClient(int id, PacketBuffer buf) throws IOException { + if (id == 0) { + getSyncManager().setCursorItem(buf.readItemStack()); + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) throws IOException {} + private static class CraftingWrapper extends InventoryCrafting { IItemHandlerModifiable craftingHandler; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 4b5c61c2110..f21f213b16d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,7 +1,5 @@ package gregtech.common.metatileentities.storage; -import com.cleanroommc.modularui.utils.Alignment; - import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; @@ -10,9 +8,7 @@ import gregtech.api.mui.GTGuis; import gregtech.api.storage.ICraftingStorage; import gregtech.api.util.GTUtility; -import gregtech.api.util.Position; import gregtech.client.renderer.texture.Textures; -import gregtech.common.inventory.IItemList; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; @@ -29,6 +25,7 @@ import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -40,8 +37,10 @@ import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.GuiTextures; +import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandlers; @@ -54,6 +53,7 @@ import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; @@ -62,8 +62,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; -import java.util.function.Supplier; public class MetaTileEntityWorkbench extends MetaTileEntity implements ICraftingStorage { @@ -204,7 +202,7 @@ public IItemHandler getInventory() { private void createCraftingRecipeLogic(EntityPlayer entityPlayer) { if (recipeLogic == null) { this.recipeLogic = new CraftingRecipeLogic(this); - this.recipeLogic.setItemsCraftedAmount(itemsCrafted); + this.recipeLogic.updateInventory(getInventory()); } this.listeners.add(entityPlayer); } @@ -266,6 +264,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); guiSyncManager.syncValue("amount_crafted", amountCrafted); + guiSyncManager.syncValue("recipe_logic", this.recipeLogic); amountCrafted.updateCacheFromSource(true); var controller = new PagedWidget.Controller(); @@ -273,13 +272,17 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { return GTGuis.createPanel(this, 176, 224) .child(new Row().widthRel(1f) .leftRel(0.5f) - .margin(2, 0) + .margin(3, 0) .coverChildrenHeight() .topRel(0f, 3, 1f) .child(new PageButton(0, controller) - .tab(GuiTextures.TAB_TOP, 0)) + .tab(GuiTextures.TAB_TOP, 0) + .overlay(new ItemDrawable(getStackForm()) + .asIcon().size(16))) .child(new PageButton(1, controller) - .tab(GuiTextures.TAB_TOP, 0))) + .tab(GuiTextures.TAB_TOP, 0) + .overlay(new ItemDrawable(new ItemStack(Blocks.CHEST)) + .asIcon().size(16)))) .child(new PagedWidget<>() .top(7) .margin(7) @@ -337,7 +340,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .build())) .addPage(new Column().coverChildren() .child(IKey.str("add storage things").asWidget()))) - .bindPlayerInventory(7); + .bindPlayerInventory(); } public int getItemsCrafted() { @@ -363,18 +366,40 @@ public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { @Override public boolean canTakeStack(EntityPlayer playerIn) { - boolean success = recipeLogic.performRecipe(playerIn); - if (success) { - this.syncValue.setValue(this.syncValue.getValue() + 1, true, false); - } - return success; + return recipeLogic.performRecipe(playerIn); } @Override public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { - recipeLogic.handleItemCraft(stack, thePlayer); + handleItemCraft(stack, thePlayer); + recipeLogic.sync(0, buffer -> buffer.writeItemStack(stack)); return super.onTake(thePlayer, stack); } + + @Override + public void putStack(@NotNull ItemStack stack) { + super.putStack(stack); + } + + public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { + itemStack.onCrafting(getWorld(), player, 1); + + var inventoryCrafting = recipeLogic.getCraftingMatrix(); + + // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds + FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); + + var cachedRecipe = recipeLogic.getCachedRecipe(); + if (cachedRecipe != null && !cachedRecipe.isDynamic()) { + player.unlockRecipes(Lists.newArrayList(cachedRecipe)); + } + if (cachedRecipe != null) { + ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); + this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, false); +// itemsCrafted += resultStack.getCount(); + recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); + } + } } private class InventoryWrapper implements IItemHandlerModifiable { From 51233328ce8866fdc0f56d21ecc43adbffc15470 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 15:18:19 -0700 Subject: [PATCH 026/147] move logic/fields in CachedRecipeData to CraftingRecipeLogic remove ICraftingStorage.java greatly rework CraftingRecipeLogic simplify some methods in MetaTileEntityWorkbench --- .../api/storage/ICraftingStorage.java | 18 - .../storage/CachedRecipeData.java | 208 +---------- .../storage/CraftingRecipeLogic.java | 350 ++++++++++++++---- .../storage/MetaTileEntityWorkbench.java | 42 +-- 4 files changed, 302 insertions(+), 316 deletions(-) delete mode 100644 src/main/java/gregtech/api/storage/ICraftingStorage.java diff --git a/src/main/java/gregtech/api/storage/ICraftingStorage.java b/src/main/java/gregtech/api/storage/ICraftingStorage.java deleted file mode 100644 index 9c529615ef7..00000000000 --- a/src/main/java/gregtech/api/storage/ICraftingStorage.java +++ /dev/null @@ -1,18 +0,0 @@ -package gregtech.api.storage; - -import gregtech.common.metatileentities.storage.CraftingRecipeMemory; - -import net.minecraft.world.World; -import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.ItemStackHandler; - -public interface ICraftingStorage { - - World getWorld(); - - ItemStackHandler getCraftingGrid(); - - CraftingRecipeMemory getRecipeMemory(); - - IItemHandler getInventory(); -} diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 8d77332c83b..8ba3e8f6e78 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -1,182 +1,20 @@ package gregtech.common.metatileentities.storage; -import gregtech.api.util.ItemStackHashStrategy; - -import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; - -import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; - import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.Ingredient; import net.minecraft.world.World; -import net.minecraftforge.items.IItemHandler; -import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.objects.Object2BooleanMap; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; +import org.jetbrains.annotations.Nullable; public class CachedRecipeData { -// private final ItemSources itemSources; - private IItemHandler handlerList; private IRecipe recipe; - private final Object2IntMap requiredItems = new Object2IntOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); - private final Object2IntOpenCustomHashMap stackIndex = new Object2IntOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); - - private final Ingredient[] indexedIngredients = new Ingredient[9]; - private final Int2ObjectMap> replaceAttemptMap = new Int2ObjectArrayMap<>(); - private final InventoryCrafting craftingMatrix; - - public CachedRecipeData(final IItemHandler handlerList, IRecipe recipe, InventoryCrafting inventoryCrafting) { - this.handlerList = handlerList; - this.recipe = recipe; - this.craftingMatrix = inventoryCrafting; - } - - public void updateStackIndex() { - this.stackIndex.clear(); - for (int i = 0; i < handlerList.getSlots(); i++) { - var stack = handlerList.extractItem(i, Integer.MAX_VALUE, true); - if (stack.isEmpty()) continue; - this.stackIndex.put(stack, i); - } - } - - public void updateInventory(IItemHandler handler) { - this.handlerList = handler; - updateStackIndex(); - } - - public short attemptMatchRecipe() { - short itemsFound = 0; - for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { - if (getIngredientEquivalent(i)) - itemsFound += (short) (1 << i); - } - return itemsFound; - } - - protected boolean consumeRecipeItems() { - Object2IntMap gatheredItems = new Object2IntOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); - if (requiredItems.isEmpty()) { - return false; - } - - for (var entry : requiredItems.object2IntEntrySet()) { - ItemStack stack = entry.getKey(); - int requestedAmount = entry.getIntValue(); - int extractedAmount = 0; - int index = stackIndex.getOrDefault(stack, -1); - if (index == -1) { - continue; - } - var extracted = handlerList.extractItem(index, requestedAmount, true).copy(); - gatheredItems.put(extracted, index); - extractedAmount += extracted.getCount(); - if (extractedAmount < requestedAmount) return false; - } - for (var gathered : gatheredItems.entrySet()) { - handlerList.extractItem(gathered.getValue(), gathered.getKey().getCount(), false); - } - return !gatheredItems.isEmpty(); -// extractedAmount = itemSources.extractItem(stack, requestedAmount, false); -// if (extractedAmount != requestedAmount) { -// gatheredItems.put(stack.copy(), extractedAmount); -// gathered = false; -// break; -// } else { -// gatheredItems.put(stack.copy(), requestedAmount); -// } -// if (!gathered) { -// for (Object2IntMap.Entry entry : gatheredItems.object2IntEntrySet()) { -// itemSources.insertItem(entry.getKey(), entry.getIntValue(), false, -// IItemList.InsertMode.HIGHEST_PRIORITY); -// } -// } - } - - public boolean getIngredientEquivalent(int slot) { - ItemStack currentStack = craftingMatrix.getStackInSlot(slot).copy(); - if (currentStack.isEmpty()) { - return true; // stack is empty, nothing to return - } - updateStackIndex(); - requiredItems.clear(); - - if (simulateExtractItem(currentStack)) { - return true; - } - - ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); - - Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, - (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); - - // iterate stored items to find equivalent - for (int i = 0; i < handlerList.getSlots(); i++) { - var itemStack = handlerList.getStackInSlot(i); - boolean matchedPreviously = false; - if (map.containsKey(itemStack)) { - if (!map.get(itemStack)) { - continue; - } else { - // cant return here before checking if: - // The item is available for extraction - // The recipe output is still the same, as depending on the ingredient, the output NBT may change - matchedPreviously = true; - } - } - if (!matchedPreviously) { - boolean matched = false; - // Matching shapeless recipes actually is very bad for performance, as it checks the entire - // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can - // take the stack - for (Ingredient in : recipe.getIngredients()) { - if (in.apply(itemStack)) { - matched = true; - break; - } - } - if (!matched) { - map.put(itemStack.copy(), false); - continue; - } - } - - // update item in slot, and check that recipe matches and output item is equal to the expected one - craftingMatrix.setInventorySlotContents(slot, itemStack); - if (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || - recipe instanceof ShapedOreEnergyTransferRecipe) { - map.put(itemStack, true); - // ingredient matched, attempt to extract it and return if successful - if (simulateExtractItem(itemStack)) { - return true; - } - } - map.put(itemStack, false); - craftingMatrix.setInventorySlotContents(slot, currentStack); - } - // nothing matched, so return null - return false; + public CachedRecipeData() { + this(null); } - - private boolean simulateExtractItem(ItemStack itemStack) { - int amountToExtract = requiredItems.getOrDefault(itemStack, 0) + 1; - int index = stackIndex.getOrDefault(itemStack, -1); - if (index == -1) return false; - var extracted = handlerList.extractItem(index, amountToExtract, true).copy(); - if (extracted.getCount() == amountToExtract) { - requiredItems.put(extracted, amountToExtract); - return true; - } - return false; + public CachedRecipeData(@Nullable IRecipe recipe) { + this.recipe = recipe; } public boolean matches(InventoryCrafting inventoryCrafting, World world) { @@ -188,42 +26,6 @@ public boolean matches(InventoryCrafting inventoryCrafting, World world) { public void setRecipe(IRecipe newRecipe) { this.recipe = newRecipe; - this.replaceAttemptMap.clear(); - this.requiredItems.clear(); - if (this.recipe != null) { -// Ingredient[] indexedIng = new Ingredient[craftingMatrix.getSizeInventory()]; - var ingredients = this.recipe.getIngredients(); - -// for (var ing : ingredients) { -// int count = requiredIngredients.getOrDefault(ing, 0) + 1; -// requiredIngredients.put(ing, count); -// } - - int rolling = 0; - for (int i = 0; i < indexedIngredients.length; i++) { - indexedIngredients[i] = null; - var stack = craftingMatrix.getStackInSlot(i); - if (rolling >= ingredients.size()) break; - var ingredient = ingredients.get(rolling); - if (ingredient == Ingredient.EMPTY) { - indexedIngredients[i] = ingredient; - rolling++; - continue; - } - if (stack.isEmpty()) continue; - indexedIngredients[i] = ingredient; - rolling++; - } - -// for (int i = 0; i < indexedIng.length; i++) { -// if (indexedIng[i] == null) continue; -// var stack = craftingMatrix.getStackInSlot(i); -// int count = requiredIngredients.getOrDefault(stack, 0) + 1; -// if (!stack.isEmpty() && indexedIng[i].apply(stack)) { -// requiredIngredients.put(stack.copy(), count); -// } -// } - } } public IRecipe getRecipe() { diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 4682be7bb7a..ba8d6a86652 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -1,10 +1,11 @@ package gregtech.common.metatileentities.storage; -import gregtech.api.storage.ICraftingStorage; import gregtech.api.util.DummyContainer; +import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; -import gregtech.common.inventory.itemsource.ItemSources; +import gregtech.api.util.ItemStackHashStrategy; +import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; @@ -13,6 +14,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; import net.minecraft.network.PacketBuffer; import net.minecraft.util.NonNullList; import net.minecraft.util.EnumFacing; @@ -21,34 +23,59 @@ import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; -import net.minecraftforge.items.ItemStackHandler; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandler; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.objects.Object2BooleanMap; +import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; +@SuppressWarnings("OverrideOnly") //stupid annotations conflicting with each other public class CraftingRecipeLogic extends SyncHandler { private final World world; - private IItemHandler handlerList; - private final ItemStackHandler craftingGrid; - private final InventoryCrafting inventoryCrafting; + private IItemHandler availableHandlers; + + /** Used to lookup a list of slots for a given stack */ + private final Object2ObjectOpenCustomHashMap> stackLookupMap = + new Object2ObjectOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); + + /** List of items needed to complete the crafting recipe, + * filled by {@link CraftingRecipeLogic#getIngredientEquivalent(int)} + **/ + private final Map requiredItems = + new Object2IntOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); + + /** Maps every non-empty stack to their slot. DO NOT MODIFY THE ITEM STACK */ + private final Map availableItems = new Int2ObjectArrayMap<>(); + private final Map> replaceAttemptMap = new Int2ObjectArrayMap<>(); + private final InventoryCrafting craftingMatrix; private final IInventory craftingResultInventory = new InventoryCraftResult(); - private ItemStack oldResult = ItemStack.EMPTY; private final CachedRecipeData cachedRecipeData; - private IRecipe cachedRecipe = null; public static short ALL_INGREDIENTS_PRESENT = 511; private short tintLocation = ALL_INGREDIENTS_PRESENT; - public CraftingRecipeLogic(ICraftingStorage craftingStorage) { - this.world = craftingStorage.getWorld(); - this.craftingGrid = craftingStorage.getCraftingGrid(); - this.handlerList = craftingStorage.getInventory(); - this.inventoryCrafting = new CraftingWrapper(craftingGrid); - this.cachedRecipeData = new CachedRecipeData(this.handlerList, null, inventoryCrafting); + public CraftingRecipeLogic(World world, IItemHandler handlers, IItemHandlerModifiable craftingMatrix) { + this.world = world; + this.availableHandlers = handlers; + this.craftingMatrix = new CraftingWrapper(craftingMatrix); + this.cachedRecipeData = new CachedRecipeData(); + } + + @Override + public void init(String key, GuiSyncManager syncManager) { + super.init(key, syncManager); + if (!syncManager.isClient() && this.collectAvailableItems()) + syncToClient(1, this::writeAvailableStacks); } public IInventory getCraftingResultInventory() { @@ -56,33 +83,143 @@ public IInventory getCraftingResultInventory() { } public InventoryCrafting getCraftingMatrix() { - return this.inventoryCrafting; + return this.craftingMatrix; + } + + public void updateInventory(IItemHandler handler) { + this.availableHandlers = handler; } public void clearCraftingGrid() { -// fillCraftingGrid(Collections.emptyMap()); + fillCraftingGrid(Collections.emptyMap()); } - public void updateInventory(IItemHandler handler) { - this.cachedRecipeData.updateInventory(handler); + public void fillCraftingGrid(Map ingredients) { + for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { + craftingMatrix.setInventorySlotContents(i, ingredients.getOrDefault(i + 1, ItemStack.EMPTY)); + } + } + + /** + * Attempts to match the crafting matrix against all available inventories + * @return true if all items matched + */ + public boolean attemptMatchRecipe() { + requiredItems.clear(); + short itemsFound = 0; + for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { + if (getIngredientEquivalent(i)) + itemsFound += (short) (1 << i); + } + return itemsFound == ALL_INGREDIENTS_PRESENT; + } + + /** + * Searches all available inventories for an ingredient equivalent for a stack in the crafting matrix + * @param slot index of the crafting matrix + * @return true if a valid substitute exists for the stack in the slot + */ + public boolean getIngredientEquivalent(int slot) { + ItemStack currentStack = craftingMatrix.getStackInSlot(slot).copy(); + if (currentStack.isEmpty()) { + return true; // stack is empty, nothing to return + } + + if (simulateExtractItem(currentStack)) { + return true; + } + + var recipe = getCachedRecipe(); + + ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); + + Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, + (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); + + // iterate stored items to find equivalent + for (var item : stackLookupMap.entrySet()) { + var itemStack = availableHandlers.getStackInSlot(item.getValue().get(0)); + boolean matchedPreviously = false; + if (map.containsKey(itemStack)) { + if (!map.get(itemStack)) { + continue; + } else { + // cant return here before checking if: + // The item is available for extraction + // The recipe output is still the same, as depending on the ingredient, the output NBT may change + matchedPreviously = true; + } + } + + if (!matchedPreviously) { + boolean matched = false; + // Matching shapeless recipes actually is very bad for performance, as it checks the entire + // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can + // take the stack + for (Ingredient in : recipe.getIngredients()) { + if (in.apply(itemStack)) { + matched = true; + break; + } + } + if (!matched) { + map.put(itemStack.copy(), false); + continue; + } + } + + // update item in slot, and check that recipe matches and output item is equal to the expected one + craftingMatrix.setInventorySlotContents(slot, itemStack); + if (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || + recipe instanceof ShapedOreEnergyTransferRecipe) { + map.put(itemStack, true); + // ingredient matched, attempt to extract it and return if successful + if (simulateExtractItem(itemStack)) { + return true; + } + } + map.put(itemStack, false); + craftingMatrix.setInventorySlotContents(slot, currentStack); + } + // nothing matched, so return null + return false; } -// public void fillCraftingGrid(Map ingredients) { -// for (int i = 0; i < craftingGrid.getSlots(); i++) { -// craftingGrid.setStackInSlot(i, ingredients.getOrDefault(i + 1, ItemStack.EMPTY)); -// } -// } + /** + * Attempts to extract the given stack from connected inventories + * @param itemStack - stack from the crafting matrix + * @return true if the item exists in available inventories + */ + private boolean simulateExtractItem(ItemStack itemStack) { + int amountToExtract = requiredItems.getOrDefault(itemStack, 0) + 1; + if (!stackLookupMap.containsKey(itemStack)) return false; + + var extracted = ItemStack.EMPTY; + for (int slot : stackLookupMap.get(itemStack)) { + extracted = availableHandlers.extractItem(slot, amountToExtract, true).copy(); + if (extracted.getCount() == amountToExtract) { + requiredItems.put(extracted, amountToExtract); + return true; + } + } + return false; + } public boolean performRecipe(EntityPlayer player) { if (!isRecipeValid()) { return false; } - if (cachedRecipeData.attemptMatchRecipe() != ALL_INGREDIENTS_PRESENT || !cachedRecipeData.consumeRecipeItems()) { + + if (!getSyncManager().isClient() && this.collectAvailableItems()) + syncToClient(1, this::writeAvailableStacks); + + if (!attemptMatchRecipe() || !consumeRecipeItems()) { return false; } + var cachedRecipe = cachedRecipeData.getRecipe(); ForgeHooks.setCraftingPlayer(player); // todo right here is where tools get damaged (in UI) - List remainingItems = cachedRecipe.getRemainingItems(inventoryCrafting); + NonNullList remainingItems = cachedRecipe.getRemainingItems(craftingMatrix); ForgeHooks.setCraftingPlayer(null); for (int i = 0; i < remainingItems.size(); i++) { ItemStack itemStack = remainingItems.get(i); @@ -90,13 +227,13 @@ public boolean performRecipe(EntityPlayer player) { continue; } - ItemStack current = inventoryCrafting.getStackInSlot(i); - inventoryCrafting.setInventorySlotContents(i, itemStack); - if (!cachedRecipe.matches(inventoryCrafting, this.world)) { - inventoryCrafting.setInventorySlotContents(i, current); + ItemStack current = craftingMatrix.getStackInSlot(i); + craftingMatrix.setInventorySlotContents(i, itemStack); + if (!cachedRecipe.matches(craftingMatrix, this.world)) { + craftingMatrix.setInventorySlotContents(i, current); } - int remainingAmount = itemStack.getCount() - GTTransferUtils.insertItem(this.handlerList, itemStack, false).getCount(); + int remainingAmount = itemStack.getCount() - GTTransferUtils.insertItem(this.availableHandlers, itemStack, false).getCount(); if (remainingAmount > 0) { itemStack.setCount(remainingAmount); if (!player.addItemStackToInventory(itemStack)) { @@ -107,43 +244,56 @@ public boolean performRecipe(EntityPlayer player) { return true; } -// public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { -// itemStack.onCrafting(world, player, 1); -// itemStack.getItem().onCreated(itemStack, world, player); -// // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds -// FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); -// -// if (cachedRecipe != null && !cachedRecipe.isDynamic()) { -// player.unlockRecipes(Lists.newArrayList(cachedRecipe)); -// } -// if (cachedRecipe != null) { -// ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); -// this.itemsCrafted += resultStack.getCount(); -// recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); -// } -// } - -// public void refreshOutputSlot() { -// ItemStack itemStack = ItemStack.EMPTY; -// if (cachedRecipe != null) { -// itemStack = cachedRecipe.getCraftingResult(inventoryCrafting); -// } -// this.craftingResultInventory.setInventorySlotContents(0, itemStack); -// } + protected boolean consumeRecipeItems() { + Object2IntMap gatheredItems = new Object2IntOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount());; + if (requiredItems.isEmpty()) { + return false; + } + + for (var entry : requiredItems.entrySet()) { + ItemStack stack = entry.getKey(); + int requestedAmount = entry.getValue(); + var slotList = stackLookupMap.getOrDefault(stack, new IntArrayList()); + if (slotList.size() == 0) { + continue; + } + int extractedAmount = 0; + for (int slot : slotList) { + var extracted = availableHandlers.extractItem(slot, requestedAmount, true).copy(); + gatheredItems.put(extracted, slot); + extractedAmount += extracted.getCount(); + if (extractedAmount == requestedAmount) break; + } + if (extractedAmount < requestedAmount) return false; + } + + boolean extracted = false; + for (var gathered : gatheredItems.entrySet()) { + var stack = gathered.getKey(); + int slot = gathered.getValue(); + if (stack.isEmpty()) { + stackLookupMap.get(stack).remove(slot); + availableItems.remove(slot); + } else { + availableItems.get(slot).shrink(stack.getCount()); + availableHandlers.extractItem(slot, stack.getCount(), false); + extracted = true; + } + } + return extracted; + } public boolean isRecipeValid() { - return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(inventoryCrafting, this.world); + return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(craftingMatrix, this.world); } public void updateCurrentRecipe() { - if (!cachedRecipeData.matches(inventoryCrafting, world) || - !ItemStack.areItemStacksEqual(oldResult, cachedRecipe.getCraftingResult(inventoryCrafting))) { - IRecipe newRecipe = CraftingManager.findMatchingRecipe(inventoryCrafting, world); - this.cachedRecipe = newRecipe; + if (!cachedRecipeData.matches(craftingMatrix, world)) { + IRecipe newRecipe = CraftingManager.findMatchingRecipe(craftingMatrix, world); ItemStack resultStack = ItemStack.EMPTY; if (newRecipe != null) { - resultStack = newRecipe.getCraftingResult(inventoryCrafting); - oldResult = resultStack.copy(); + resultStack = newRecipe.getCraftingResult(craftingMatrix); } this.craftingResultInventory.setInventorySlotContents(0, resultStack); this.cachedRecipeData.setRecipe(newRecipe); @@ -151,7 +301,7 @@ public void updateCurrentRecipe() { } public IRecipe getCachedRecipe() { - return this.cachedRecipe; + return this.cachedRecipeData.getRecipe(); } public void update() { @@ -169,26 +319,84 @@ public short getTintLocations() { return tintLocation; } -// public void checkNeighbourInventories(BlockPos blockPos) { -// for (EnumFacing side : EnumFacing.VALUES) { -// TileItemSource itemSource = new TileItemSource(world, blockPos, side); -// this.itemSources.addItemHandler(itemSource); -// } -// } - public CachedRecipeData getCachedRecipeData() { return this.cachedRecipeData; } + + private void writeAvailableStacks(PacketBuffer buffer) { + buffer.writeInt(this.availableItems.size()); + for (var entry : this.availableItems.entrySet()) { + buffer.writeInt(entry.getKey()); + writeStackSafe(buffer, entry.getValue()); + } + } + + public boolean collectAvailableItems() { + var oldMap = this.stackLookupMap.clone(); + this.stackLookupMap.clear(); + this.availableItems.clear(); + for (int i = 0; i < this.availableHandlers.getSlots(); i++) { + var stack = this.availableHandlers.getStackInSlot(i); + if (stack.isEmpty()) continue; + this.stackLookupMap + .computeIfAbsent(stack, k -> new IntArrayList()) + .add(i); + this.availableItems.put(i, stack); + } + return !oldMap.equals(this.stackLookupMap); + } + @Override - public void readOnClient(int id, PacketBuffer buf) throws IOException { + public void readOnClient(int id, PacketBuffer buf) { if (id == 0) { - getSyncManager().setCursorItem(buf.readItemStack()); +// getSyncManager().setCursorItem(buf.readItemStack()); + } else if (id == 1) { + updateClientStacks(buf); } } @Override - public void readOnServer(int id, PacketBuffer buf) throws IOException {} + public void readOnServer(int id, PacketBuffer buf) {} + + public void updateClientStacks(PacketBuffer buffer) { + this.availableItems.clear(); + this.stackLookupMap.clear(); + int size = buffer.readInt(); + for (int i = 0; i < size; i++) { + int slot = buffer.readInt(); + var serverStack = readStackSafe(buffer); + var clientStack = this.availableHandlers.extractItem(slot, Integer.MAX_VALUE, true); + + if (clientStack.isEmpty() || !ItemStack.areItemStacksEqual(clientStack, serverStack)) { + this.availableHandlers.extractItem(slot, Integer.MAX_VALUE, false); + this.availableHandlers.insertItem(slot, serverStack.copy(), false); + } + + this.availableItems.put(slot, serverStack); + this.stackLookupMap + .computeIfAbsent(serverStack, k -> new IntArrayList()) + .add(slot); + } + } + + private static ItemStack readStackSafe(PacketBuffer buffer) { + var stack = ItemStack.EMPTY; + try { + var tag = buffer.readCompoundTag(); + if (tag == null) return stack; + GTLog.logger.warn("Read from NBT: %s", tag); + stack = new ItemStack(tag); + } catch (IOException ignore) {} + if (stack.isEmpty()) GTLog.logger.warn("An empty stack was read, something is seriously wrong!"); + return stack; + } + + private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { + var tag = stack.serializeNBT(); + GTLog.logger.warn(String.format("Written to NBT: %s", tag)); + buffer.writeCompoundTag(tag); + } private static class CraftingWrapper extends InventoryCrafting { diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index f21f213b16d..25c1b4be3de 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -6,7 +6,6 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; -import gregtech.api.storage.ICraftingStorage; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.common.inventory.handlers.SingleItemStackHandler; @@ -63,18 +62,18 @@ import java.util.ArrayList; import java.util.List; -public class MetaTileEntityWorkbench extends MetaTileEntity implements ICraftingStorage { +public class MetaTileEntityWorkbench extends MetaTileEntity { private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18); private final ItemStackHandler craftingGrid = new SingleItemStackHandler(9); private final ItemStackHandler toolInventory = new ToolItemStackHandler(9); + private IItemHandler combinedInventory; + private final CraftingRecipeMemory recipeMemory = new CraftingRecipeMemory(9); private CraftingRecipeLogic recipeLogic = null; private int itemsCrafted = 0; - private final ArrayList listeners = new ArrayList<>(); - public MetaTileEntityWorkbench(ResourceLocation metaTileEntityId) { super(metaTileEntityId); } @@ -185,26 +184,18 @@ public void readFromNBT(NBTTagCompound data) { this.recipeMemory.deserializeNBT(data.getCompoundTag("RecipeMemory")); } - @Override - public IItemHandler getInventory() { - var handlerList = new ArrayList(); + public IItemHandler getAvailableHandlers() { + var handlers = new ArrayList(); for (var facing : EnumFacing.VALUES) { var neighbor = getNeighbor(facing); if (neighbor == null) continue; var handler = neighbor.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()); - if (handler != null) handlerList.add(handler); - } - handlerList.add(this.internalInventory); - handlerList.add(this.toolInventory); - return new ItemHandlerList(handlerList); - } - - private void createCraftingRecipeLogic(EntityPlayer entityPlayer) { - if (recipeLogic == null) { - this.recipeLogic = new CraftingRecipeLogic(this); - this.recipeLogic.updateInventory(getInventory()); + if (handler != null) handlers.add(handler); } - this.listeners.add(entityPlayer); + handlers.add(this.internalInventory); + handlers.add(this.toolInventory); + this.combinedInventory = new ItemHandlerList(handlers); + return this.combinedInventory; } @Override @@ -219,12 +210,15 @@ public void update() { @Override public void onNeighborChanged() { - this.recipeLogic.updateInventory(getInventory()); + this.recipeLogic.updateInventory(getAvailableHandlers()); } - private CraftingRecipeLogic getCraftingRecipeLogic() { + private @NotNull CraftingRecipeLogic getCraftingRecipeLogic() { Preconditions.checkState(getWorld() != null, "getRecipeResolver called too early"); - return recipeLogic; + if (this.recipeLogic == null) { + this.recipeLogic = new CraftingRecipeLogic(getWorld(), getAvailableHandlers(), getCraftingGrid()); + } + return this.recipeLogic; } @Override @@ -259,8 +253,8 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { var inventory = new SlotGroup("inventory", 9, true); guiSyncManager.registerSlotGroup(toolSlots); guiSyncManager.registerSlotGroup(inventory); - createCraftingRecipeLogic(guiData.getPlayer()); - this.recipeLogic.updateCurrentRecipe(); + + getCraftingRecipeLogic().updateCurrentRecipe(); var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); guiSyncManager.syncValue("amount_crafted", amountCrafted); From 37e7d14abb6ea074ec369c85efb8c44efb7f710b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 15:42:14 -0700 Subject: [PATCH 027/147] fix sync issue don't sync `onTake()` --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 4 +--- .../metatileentities/storage/MetaTileEntityWorkbench.java | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index ba8d6a86652..ac780851eec 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -74,8 +74,6 @@ public CraftingRecipeLogic(World world, IItemHandler handlers, IItemHandlerModif @Override public void init(String key, GuiSyncManager syncManager) { super.init(key, syncManager); - if (!syncManager.isClient() && this.collectAvailableItems()) - syncToClient(1, this::writeAvailableStacks); } public IInventory getCraftingResultInventory() { @@ -96,7 +94,7 @@ public void clearCraftingGrid() { public void fillCraftingGrid(Map ingredients) { for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { - craftingMatrix.setInventorySlotContents(i, ingredients.getOrDefault(i + 1, ItemStack.EMPTY)); + craftingMatrix.setInventorySlotContents(i, ingredients.getOrDefault(i, ItemStack.EMPTY)); } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 25c1b4be3de..53d3e7b23c0 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -366,7 +366,6 @@ public boolean canTakeStack(EntityPlayer playerIn) { @Override public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { handleItemCraft(stack, thePlayer); - recipeLogic.sync(0, buffer -> buffer.writeItemStack(stack)); return super.onTake(thePlayer, stack); } From bc857c22f26d785073d6d97e29d62d477da82774 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:36:21 -0700 Subject: [PATCH 028/147] properly fix sync issues update handler for client --- .../storage/CraftingRecipeLogic.java | 13 ++++---- .../storage/MetaTileEntityWorkbench.java | 33 ++++++++++++++++++- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index ac780851eec..4bf0d77c664 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -322,7 +322,7 @@ public CachedRecipeData getCachedRecipeData() { } - private void writeAvailableStacks(PacketBuffer buffer) { + public void writeAvailableStacks(PacketBuffer buffer) { buffer.writeInt(this.availableItems.size()); for (var entry : this.availableItems.entrySet()) { buffer.writeInt(entry.getKey()); @@ -382,17 +382,18 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { var stack = ItemStack.EMPTY; try { var tag = buffer.readCompoundTag(); - if (tag == null) return stack; - GTLog.logger.warn("Read from NBT: %s", tag); + if (tag == null) throw new IOException(); + GTLog.logger.warn(String.format("Received: %s", tag)); stack = new ItemStack(tag); - } catch (IOException ignore) {} - if (stack.isEmpty()) GTLog.logger.warn("An empty stack was read, something is seriously wrong!"); + } catch (IOException ignore) { + GTLog.logger.warn("A stack was read incorrectly, something is seriously wrong!"); + } return stack; } private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { var tag = stack.serializeNBT(); - GTLog.logger.warn(String.format("Written to NBT: %s", tag)); + GTLog.logger.warn(String.format("Sent: %s", tag)); buffer.writeCompoundTag(tag); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 53d3e7b23c0..a4ef1fdd1e6 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,5 +1,6 @@ package gregtech.common.metatileentities.storage; +import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; @@ -210,7 +211,8 @@ public void update() { @Override public void onNeighborChanged() { - this.recipeLogic.updateInventory(getAvailableHandlers()); + getCraftingRecipeLogic().updateInventory(getAvailableHandlers()); + writeCustomData(GregtechDataCodes.UPDATE_ITEM, this::sendHandlerToClient); } private @NotNull CraftingRecipeLogic getCraftingRecipeLogic() { @@ -255,6 +257,9 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { guiSyncManager.registerSlotGroup(inventory); getCraftingRecipeLogic().updateCurrentRecipe(); + if (!guiSyncManager.isClient() && getCraftingRecipeLogic().collectAvailableItems()) { + writeCustomData(GregtechDataCodes.UPDATE_MACHINE, getCraftingRecipeLogic()::writeAvailableStacks); + } var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); guiSyncManager.syncValue("amount_crafted", amountCrafted); @@ -337,6 +342,32 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .bindPlayerInventory(); } + public void sendHandlerToClient(PacketBuffer buffer) { + buffer.writeVarInt(this.combinedInventory.getSlots()); + boolean changed = getCraftingRecipeLogic().collectAvailableItems(); + buffer.writeBoolean(changed); + if (changed) + getCraftingRecipeLogic().writeAvailableStacks(buffer); + } + + @Override + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.UPDATE_MACHINE) { + getCraftingRecipeLogic() + .updateClientStacks(buf); + + } else if (dataId == GregtechDataCodes.UPDATE_ITEM) { + getCraftingRecipeLogic() + .updateInventory(new ItemStackHandler(buf.readVarInt())); + + if (!buf.readBoolean()) return; + + getCraftingRecipeLogic() + .updateClientStacks(buf); + } + } + public int getItemsCrafted() { return this.itemsCrafted; } From b0d714bac0a4d74834d63415493b80530a039601 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:29:04 -0700 Subject: [PATCH 029/147] remove GregTechGuiTransferrableScreen.java and usages --- .../api/metatileentity/MetaTileEntity.java | 9 +----- .../mui/GregTechGuiTransferrableScreen.java | 31 ------------------- .../storage/MetaTileEntityWorkbench.java | 5 --- 3 files changed, 1 insertion(+), 44 deletions(-) delete mode 100644 src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 3d3e34b40d2..c89fe48379d 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -27,7 +27,6 @@ import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.mui.GTGuiTheme; import gregtech.api.mui.GregTechGuiScreen; -import gregtech.api.mui.GregTechGuiTransferrableScreen; import gregtech.api.mui.factory.MetaTileEntityGuiFactory; import gregtech.api.recipes.RecipeMap; import gregtech.api.util.GTLog; @@ -485,13 +484,7 @@ public boolean usesMui2() { @SideOnly(Side.CLIENT) @Override public final ModularScreen createScreen(PosGuiData posGuiData, ModularPanel mainPanel) { - return createTransferableScreen() ? - new GregTechGuiTransferrableScreen(mainPanel, getUITheme()) : - new GregTechGuiScreen(mainPanel, getUITheme()); - } - - protected boolean createTransferableScreen() { - return false; + return new GregTechGuiScreen(mainPanel, getUITheme()); } public GTGuiTheme getUITheme() { diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java deleted file mode 100644 index 1faca7c6fc7..00000000000 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferrableScreen.java +++ /dev/null @@ -1,31 +0,0 @@ -package gregtech.api.mui; - -import com.cleanroommc.modularui.integration.jei.JeiRecipeTransferHandler; -import com.cleanroommc.modularui.screen.ModularPanel; -import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.recipe.transfer.IRecipeTransferError; - -@SuppressWarnings("UnstableApiUsage") -public class GregTechGuiTransferrableScreen extends GregTechGuiScreen implements JeiRecipeTransferHandler { - - public GregTechGuiTransferrableScreen(ModularPanel mainPanel) { - super(mainPanel); - } - - public GregTechGuiTransferrableScreen(ModularPanel mainPanel, GTGuiTheme theme) { - super(mainPanel, theme); - } - - public GregTechGuiTransferrableScreen(String owner, ModularPanel mainPanel, GTGuiTheme theme) { - super(owner, mainPanel, theme); - } - - public GregTechGuiTransferrableScreen(String owner, ModularPanel mainPanel, String themeId) { - super(owner, mainPanel, themeId); - } - - @Override - public IRecipeTransferError transferRecipe(IRecipeLayout recipeLayout, boolean maxTransfer, boolean simulate) { - return null; - } -} diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index a4ef1fdd1e6..24bf70b1090 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -376,11 +376,6 @@ public void setItemsCrafted(int itemsCrafted) { this.itemsCrafted = itemsCrafted; } - @Override - protected boolean createTransferableScreen() { - return true; - } - private class CraftingOutputSlot extends ModularSlot { IntSyncValue syncValue; From 125d6741d5ca5899f0aa3bc22947e64b96734bc2 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:30:39 -0700 Subject: [PATCH 030/147] implement jei compat directly --- .../api/mui/GregTechGuiTransferHandler.java | 32 +++++++++++++++++++ .../jei/JustEnoughItemsModule.java | 4 +++ 2 files changed, 36 insertions(+) create mode 100644 src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java new file mode 100644 index 00000000000..88802fc1952 --- /dev/null +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -0,0 +1,32 @@ +package gregtech.api.mui; + +import com.cleanroommc.modularui.screen.ModularContainer; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; + +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; + +import net.minecraft.entity.player.EntityPlayer; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class GregTechGuiTransferHandler implements IRecipeTransferHandler { + + private final IRecipeTransferHandlerHelper handlerHelper; + + public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { + this.handlerHelper = handlerHelper; + } + @Override + public @NotNull Class getContainerClass() { + return ModularContainer.class; + } + + @Override + public @Nullable IRecipeTransferError transferRecipe(ModularContainer container, IRecipeLayout recipeLayout, + EntityPlayer player, boolean maxTransfer, boolean doTransfer) { + return null; + } +} diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 5a182dbadde..8a715fb86a2 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -12,6 +12,7 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.modules.GregTechModule; +import gregtech.api.mui.GregTechGuiTransferHandler; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.category.GTRecipeCategory; @@ -170,6 +171,9 @@ public void register(IModRegistry registry) { jeiHelpers.recipeTransferHandlerHelper()); registry.getRecipeTransferRegistry().addRecipeTransferHandler(craftingStationGuiHandler, VanillaRecipeCategoryUid.CRAFTING); + registry.getRecipeTransferRegistry().addRecipeTransferHandler(new GregTechGuiTransferHandler( + jeiHelpers.recipeTransferHandlerHelper() + ), VanillaRecipeCategoryUid.CRAFTING); for (RecipeMap recipeMap : RecipeMap.getRecipeMaps()) { if (recipeMap.getRecipeMapUI().isJEIVisible()) { From 19ff620b82d33232cc19b9ae57ed7c91638713a0 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:31:02 -0700 Subject: [PATCH 031/147] add slot group for crafting matrix --- .../metatileentities/storage/MetaTileEntityWorkbench.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 24bf70b1090..96188d55d22 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -253,6 +253,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { var toolSlots = new SlotGroup("tool_slots", 9, true); var inventory = new SlotGroup("inventory", 9, true); + var craftingMatrix = new SlotGroup("crafting_matrix", 3, false); guiSyncManager.registerSlotGroup(toolSlots); guiSyncManager.registerSlotGroup(inventory); @@ -299,6 +300,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .matrix(craftingGrid) .key(key, i -> new ItemSlot() .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) + .slotGroup(craftingMatrix) .changeListener((newItem, onlyAmountChanged, client, init) -> { if (!init) { this.recipeLogic.updateCurrentRecipe(); From 6bb5e7525738d0302d01017795867479802f3a9a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 18:12:09 -0700 Subject: [PATCH 032/147] uncomment a portion of code --- .../craftingstation/CraftingSlotWidget.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java index ae16bd40a39..3820187d641 100644 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java @@ -40,18 +40,18 @@ private static IInventory createInventory(CraftingRecipeLogic resolver) { @Override public void handleClientAction(int id, PacketBuffer buffer) { super.handleClientAction(id, buffer); -// if (id == 1) { -// HashMap ingredients = new HashMap<>(); -// int ingredientAmount = buffer.readVarInt(); -// try { -// for (int i = 0; i < ingredientAmount; i++) { -// ingredients.put(buffer.readVarInt(), buffer.readItemStack()); -// } -// } catch (IOException exception) { -// throw new RuntimeException(exception); -// } -// recipeResolver.fillCraftingGrid(ingredients); -// } + if (id == 1) { + HashMap ingredients = new HashMap<>(); + int ingredientAmount = buffer.readVarInt(); + try { + for (int i = 0; i < ingredientAmount; i++) { + ingredients.put(buffer.readVarInt(), buffer.readItemStack()); + } + } catch (IOException exception) { + throw new RuntimeException(exception); + } + recipeResolver.fillCraftingGrid(ingredients); + } // if (id == 2) { // if (recipeResolver.isRecipeValid()) { // ClickData clickData = ClickData.readFromBuf(buffer); From f59bdd0349303f751c6e7a3735de39a19dbe591d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 18:33:00 -0700 Subject: [PATCH 033/147] add recipe transferring from JEI --- .../api/mui/GregTechGuiTransferHandler.java | 48 +++++++++++++++++-- .../storage/CraftingRecipeLogic.java | 11 ++++- .../storage/MetaTileEntityWorkbench.java | 1 + 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 88802fc1952..5851f9e8b60 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -1,20 +1,34 @@ package gregtech.api.mui; +import gregtech.api.recipes.category.RecipeCategories; +import gregtech.common.metatileentities.storage.CraftingRecipeLogic; + +import mezz.jei.api.recipe.IRecipeCategory; + +import mezz.jei.plugins.vanilla.crafting.CraftingRecipeCategory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.IItemHandlerModifiable; + import com.cleanroommc.modularui.screen.ModularContainer; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; - import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; - -import net.minecraft.entity.player.EntityPlayer; - import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Objects; + public class GregTechGuiTransferHandler implements IRecipeTransferHandler { private final IRecipeTransferHandlerHelper handlerHelper; + private InventoryCrafting craftingMatrix; public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { this.handlerHelper = handlerHelper; @@ -27,6 +41,32 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { @Override public @Nullable IRecipeTransferError transferRecipe(ModularContainer container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer) { + CraftingRecipeLogic recipeLogic = (CraftingRecipeLogic) container.getSyncManager() + .getSyncHandler(GuiSyncManager.makeSyncKey("recipe_logic", 0)); + + if (!doTransfer) { + // todo highlighting in JEI? + return null; + } + + var ingredients = recipeLayout.getItemStacks().getGuiIngredients(); + this.craftingMatrix = recipeLogic.getCraftingMatrix(); + + for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { + var ing = ingredients.get(i + 1).getDisplayedIngredient(); + this.craftingMatrix.setInventorySlotContents(i, ing == null ? ItemStack.EMPTY : ing); + } + + recipeLogic.syncToServer(0, this::writeCraftingMatrix); + recipeLogic.updateCurrentRecipe(); return null; } + + private void writeCraftingMatrix(PacketBuffer buffer) { + buffer.writeVarInt(this.craftingMatrix.getSizeInventory()); + for (int i = 0; i < this.craftingMatrix.getSizeInventory(); i++) { + var stack = this.craftingMatrix.getStackInSlot(i); + buffer.writeItemStack(stack); + } + } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 4bf0d77c664..e35a292d380 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -355,7 +355,16 @@ public void readOnClient(int id, PacketBuffer buf) { } @Override - public void readOnServer(int id, PacketBuffer buf) {} + public void readOnServer(int id, PacketBuffer buf) { + if (id == 0) { + int size = buf.readVarInt(); + for (int i = 0; i < size; i++) { + try { + this.craftingMatrix.setInventorySlotContents(i, buf.readItemStack()); + } catch (IOException ignore) {} + } + } + } public void updateClientStacks(PacketBuffer buffer) { this.availableItems.clear(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 96188d55d22..b944dce26a1 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -256,6 +256,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { var craftingMatrix = new SlotGroup("crafting_matrix", 3, false); guiSyncManager.registerSlotGroup(toolSlots); guiSyncManager.registerSlotGroup(inventory); + guiSyncManager.registerSlotGroup(craftingMatrix); getCraftingRecipeLogic().updateCurrentRecipe(); if (!guiSyncManager.isClient() && getCraftingRecipeLogic().collectAvailableItems()) { From b14764d1d1f3cb82f4f8bb9502607c74a81bf481 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 18:38:10 -0700 Subject: [PATCH 034/147] remove todo comment out logging, to be removed later --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 4 ++-- .../metatileentities/storage/MetaTileEntityWorkbench.java | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index e35a292d380..fd0cc0ffe27 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -392,7 +392,7 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { try { var tag = buffer.readCompoundTag(); if (tag == null) throw new IOException(); - GTLog.logger.warn(String.format("Received: %s", tag)); +// GTLog.logger.warn(String.format("Received: %s", tag)); stack = new ItemStack(tag); } catch (IOException ignore) { GTLog.logger.warn("A stack was read incorrectly, something is seriously wrong!"); @@ -402,7 +402,7 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { var tag = stack.serializeNBT(); - GTLog.logger.warn(String.format("Sent: %s", tag)); +// GTLog.logger.warn(String.format("Sent: %s", tag)); buffer.writeCompoundTag(tag); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index b944dce26a1..b75c05f5cac 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -294,9 +294,6 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(new Row().coverChildrenHeight() .widthRel(1f) .marginBottom(2) - //todo - // make JEI transfer work correctly - // currently it's not possible due to getCurrent() in ModularScreen returning null .child(SlotGroupWidget.builder() .matrix(craftingGrid) .key(key, i -> new ItemSlot() From 54dd165fa3f9e97f4b1045408242d9c39edc8486 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 31 Jan 2024 19:01:40 -0700 Subject: [PATCH 035/147] update handler on client --- .../api/mui/GregTechGuiTransferHandler.java | 1 + .../storage/CraftingRecipeLogic.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 5851f9e8b60..0e8cee8bb01 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -58,6 +58,7 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { } recipeLogic.syncToServer(0, this::writeCraftingMatrix); + recipeLogic.updateClientHandler(); recipeLogic.updateCurrentRecipe(); return null; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index fd0cc0ffe27..3f33b734533 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -279,6 +279,15 @@ protected boolean consumeRecipeItems() { extracted = true; } } +// if (!getSyncManager().isClient()) +// syncToClient(1, buffer -> { +// buffer.writeVarInt(gatheredItems.size()); +// for (var gathered : gatheredItems.entrySet()) { +// var slot = gathered.getValue(); +// buffer.writeVarInt(slot); +// writeStackSafe(buffer, availableItems.get(slot)); +// } +// }); return extracted; } @@ -387,6 +396,14 @@ public void updateClientStacks(PacketBuffer buffer) { } } + public void updateClientHandler() { + for (var items : availableItems.entrySet()) { + int slot = items.getKey(); + this.availableHandlers.extractItem(slot, Integer.MAX_VALUE, false); + this.availableHandlers.insertItem(slot, items.getValue().copy(), false); + } + } + private static ItemStack readStackSafe(PacketBuffer buffer) { var stack = ItemStack.EMPTY; try { From e97a60981d20649b90360339a028632568d796be Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:16:07 -0700 Subject: [PATCH 036/147] remove available item map make sync better maybe --- .../api/mui/GregTechGuiTransferHandler.java | 2 +- .../storage/CraftingRecipeLogic.java | 49 ++++++------------- .../storage/MetaTileEntityWorkbench.java | 8 +-- 3 files changed, 19 insertions(+), 40 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 0e8cee8bb01..d8e219783c9 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -58,7 +58,7 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { } recipeLogic.syncToServer(0, this::writeCraftingMatrix); - recipeLogic.updateClientHandler(); + recipeLogic.syncToServer(1); recipeLogic.updateCurrentRecipe(); return null; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 3f33b734533..b6e6ba2d231 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -55,8 +55,6 @@ public class CraftingRecipeLogic extends SyncHandler { private final Map requiredItems = new Object2IntOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); - /** Maps every non-empty stack to their slot. DO NOT MODIFY THE ITEM STACK */ - private final Map availableItems = new Int2ObjectArrayMap<>(); private final Map> replaceAttemptMap = new Int2ObjectArrayMap<>(); private final InventoryCrafting craftingMatrix; private final IInventory craftingResultInventory = new InventoryCraftResult(); @@ -231,7 +229,7 @@ public boolean performRecipe(EntityPlayer player) { craftingMatrix.setInventorySlotContents(i, current); } - int remainingAmount = itemStack.getCount() - GTTransferUtils.insertItem(this.availableHandlers, itemStack, false).getCount(); + int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, false).getCount(); if (remainingAmount > 0) { itemStack.setCount(remainingAmount); if (!player.addItemStackToInventory(itemStack)) { @@ -272,22 +270,11 @@ protected boolean consumeRecipeItems() { int slot = gathered.getValue(); if (stack.isEmpty()) { stackLookupMap.get(stack).remove(slot); - availableItems.remove(slot); } else { - availableItems.get(slot).shrink(stack.getCount()); availableHandlers.extractItem(slot, stack.getCount(), false); extracted = true; } } -// if (!getSyncManager().isClient()) -// syncToClient(1, buffer -> { -// buffer.writeVarInt(gatheredItems.size()); -// for (var gathered : gatheredItems.entrySet()) { -// var slot = gathered.getValue(); -// buffer.writeVarInt(slot); -// writeStackSafe(buffer, availableItems.get(slot)); -// } -// }); return extracted; } @@ -312,8 +299,6 @@ public IRecipe getCachedRecipe() { } public void update() { - // update item sources every tick for fast tinting updates -// itemSources.update(); if (getCachedRecipeData().getRecipe() != null) { //todo fix tint location // tintLocation = getCachedRecipeData().attemptMatchRecipe(); @@ -332,8 +317,16 @@ public CachedRecipeData getCachedRecipeData() { public void writeAvailableStacks(PacketBuffer buffer) { - buffer.writeInt(this.availableItems.size()); - for (var entry : this.availableItems.entrySet()) { + Map written = new Int2ObjectArrayMap<>(); + for (var slots : this.stackLookupMap.entrySet()) { + for (var slot : slots.getValue()) { + var stack = this.availableHandlers.getStackInSlot(slot); + written.put(slot, stack); + } + } + + buffer.writeInt(written.size()); + for (var entry : written.entrySet()) { buffer.writeInt(entry.getKey()); writeStackSafe(buffer, entry.getValue()); } @@ -342,23 +335,19 @@ public void writeAvailableStacks(PacketBuffer buffer) { public boolean collectAvailableItems() { var oldMap = this.stackLookupMap.clone(); this.stackLookupMap.clear(); - this.availableItems.clear(); for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var stack = this.availableHandlers.getStackInSlot(i); if (stack.isEmpty()) continue; this.stackLookupMap .computeIfAbsent(stack, k -> new IntArrayList()) .add(i); - this.availableItems.put(i, stack); } return !oldMap.equals(this.stackLookupMap); } @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == 0) { -// getSyncManager().setCursorItem(buf.readItemStack()); - } else if (id == 1) { + if (id == 1) { updateClientStacks(buf); } } @@ -372,11 +361,14 @@ public void readOnServer(int id, PacketBuffer buf) { this.craftingMatrix.setInventorySlotContents(i, buf.readItemStack()); } catch (IOException ignore) {} } + } else if (id == 1) { + if (this.collectAvailableItems()) { + syncToClient(1, this::writeAvailableStacks); + } } } public void updateClientStacks(PacketBuffer buffer) { - this.availableItems.clear(); this.stackLookupMap.clear(); int size = buffer.readInt(); for (int i = 0; i < size; i++) { @@ -389,21 +381,12 @@ public void updateClientStacks(PacketBuffer buffer) { this.availableHandlers.insertItem(slot, serverStack.copy(), false); } - this.availableItems.put(slot, serverStack); this.stackLookupMap .computeIfAbsent(serverStack, k -> new IntArrayList()) .add(slot); } } - public void updateClientHandler() { - for (var items : availableItems.entrySet()) { - int slot = items.getKey(); - this.availableHandlers.extractItem(slot, Integer.MAX_VALUE, false); - this.availableHandlers.insertItem(slot, items.getValue().copy(), false); - } - } - private static ItemStack readStackSafe(PacketBuffer buffer) { var stack = ItemStack.EMPTY; try { diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index b75c05f5cac..3472fcda5c0 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -344,10 +344,8 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { public void sendHandlerToClient(PacketBuffer buffer) { buffer.writeVarInt(this.combinedInventory.getSlots()); - boolean changed = getCraftingRecipeLogic().collectAvailableItems(); - buffer.writeBoolean(changed); - if (changed) - getCraftingRecipeLogic().writeAvailableStacks(buffer); + getCraftingRecipeLogic().collectAvailableItems(); + getCraftingRecipeLogic().writeAvailableStacks(buffer); } @Override @@ -361,8 +359,6 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { getCraftingRecipeLogic() .updateInventory(new ItemStackHandler(buf.readVarInt())); - if (!buf.readBoolean()) return; - getCraftingRecipeLogic() .updateClientStacks(buf); } From 764ffff5b90dc5a4a6ccc29e71b597a0371e14d6 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:04:00 -0700 Subject: [PATCH 037/147] unique sync codes --- .../storage/MetaTileEntityWorkbench.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 3472fcda5c0..81abd4e40cf 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -65,6 +65,10 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { + // todo move these to GregtechDataCodes + public static final int UPDATE_CLIENT_STACKS = GregtechDataCodes.assignId(); + public static final int UPDATE_CLIENT_HANDLER = GregtechDataCodes.assignId(); + private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18); private final ItemStackHandler craftingGrid = new SingleItemStackHandler(9); private final ItemStackHandler toolInventory = new ToolItemStackHandler(9); @@ -212,7 +216,7 @@ public void update() { @Override public void onNeighborChanged() { getCraftingRecipeLogic().updateInventory(getAvailableHandlers()); - writeCustomData(GregtechDataCodes.UPDATE_ITEM, this::sendHandlerToClient); + writeCustomData(UPDATE_CLIENT_HANDLER, this::sendHandlerToClient); } private @NotNull CraftingRecipeLogic getCraftingRecipeLogic() { @@ -260,7 +264,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); if (!guiSyncManager.isClient() && getCraftingRecipeLogic().collectAvailableItems()) { - writeCustomData(GregtechDataCodes.UPDATE_MACHINE, getCraftingRecipeLogic()::writeAvailableStacks); + writeCustomData(UPDATE_CLIENT_STACKS, getCraftingRecipeLogic()::writeAvailableStacks); } var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); @@ -351,11 +355,11 @@ public void sendHandlerToClient(PacketBuffer buffer) { @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); - if (dataId == GregtechDataCodes.UPDATE_MACHINE) { + if (dataId == UPDATE_CLIENT_STACKS) { getCraftingRecipeLogic() .updateClientStacks(buf); - } else if (dataId == GregtechDataCodes.UPDATE_ITEM) { + } else if (dataId == UPDATE_CLIENT_HANDLER) { getCraftingRecipeLogic() .updateInventory(new ItemStackHandler(buf.readVarInt())); From 3879d175249fbf6b4ae73bb6c1af00c37fe90dc7 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 2 Feb 2024 11:52:33 -0700 Subject: [PATCH 038/147] try implement storage view --- .../storage/MetaTileEntityWorkbench.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 81abd4e40cf..d4554a65d16 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -36,6 +36,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.PosGuiData; @@ -49,6 +50,7 @@ import com.cleanroommc.modularui.widgets.PagedWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Grid; import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.cleanroommc.modularui.widgets.slot.SlotGroup; @@ -61,6 +63,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class MetaTileEntityWorkbench extends MetaTileEntity { @@ -234,16 +237,6 @@ public void clearMachineInventory(@NotNull List<@NotNull ItemStack> itemBuffer) clearInventory(itemBuffer, toolInventory); } -// private gregtech.api.gui.widgets.AbstractWidgetGroup createItemListTab() { -// gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); -// widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 20, "gregtech.machine.workbench.storage_note_1")); -// widgetGroup.addWidget(new gregtech.api.gui.widgets.LabelWidget(5, 30, "gregtech.machine.workbench.storage_note_2")); -// CraftingRecipeLogic recipeResolver = getCraftingRecipeLogic(); -// IItemList itemList = recipeResolver == null ? null : recipeResolver.getItemSourceList(); -// widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.ItemListGridWidget(11, 45, 8, 5, itemList)); -// return widgetGroup; -// } - @Override public boolean usesMui2() { return true; @@ -255,6 +248,11 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { final String[] craftingGrid = new String[] {"XXX", "XXX", "XXX"}; final char key = 'X'; + this.combinedInventory = getAvailableHandlers(); + int rows = 1 + this.combinedInventory.getSlots() / 8; + final String[] combinedMatrix = new String[rows]; + Arrays.fill(combinedMatrix, "XXXXXXXX"); // 8 slots wide + var toolSlots = new SlotGroup("tool_slots", 9, true); var inventory = new SlotGroup("inventory", 9, true); var craftingMatrix = new SlotGroup("crafting_matrix", 3, false); @@ -291,7 +289,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(new PagedWidget<>() .top(7) .margin(7) - .expanded() + .coverChildren() .controller(controller) .addPage(new Column() .coverChildren() @@ -341,8 +339,14 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .slot(SyncHandlers.itemSlot(this.internalInventory, i) .slotGroup(inventory))) .build())) - .addPage(new Column().coverChildren() - .child(IKey.str("add storage things").asWidget()))) + .addPage(new Column() + .expanded() + .child(new Grid() + .heightRel(.9f).coverChildrenWidth() + .child(SlotGroupWidget.builder() + .matrix(combinedMatrix) + .key(key, this::createInventoryList) + .build().marginRight(4))))) .bindPlayerInventory(); } @@ -352,6 +356,14 @@ public void sendHandlerToClient(PacketBuffer buffer) { getCraftingRecipeLogic().writeAvailableStacks(buffer); } + public IWidget createInventoryList(int slot) { + if (slot >= this.combinedInventory.getSlots()) { + return GuiTextures.DISABLED.asWidget().size(18); + } + return new ItemSlot() + .slot(SyncHandlers.itemSlot((IItemHandlerModifiable) this.combinedInventory, slot)); + } + @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); From 989eea3a4ebcf6583f1dd2f61bac76a43903821e Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 2 Feb 2024 13:03:18 -0700 Subject: [PATCH 039/147] fully implement storage view --- .../storage/MetaTileEntityWorkbench.java | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index d4554a65d16..6f38e446d12 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,5 +1,11 @@ package gregtech.common.metatileentities.storage; +import com.cleanroommc.modularui.widget.ScrollWidget; + +import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; + +import com.cleanroommc.modularui.widgets.layout.Grid; + import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; @@ -50,7 +56,6 @@ import com.cleanroommc.modularui.widgets.PagedWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Grid; import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.cleanroommc.modularui.widgets.slot.SlotGroup; @@ -75,8 +80,8 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18); private final ItemStackHandler craftingGrid = new SingleItemStackHandler(9); private final ItemStackHandler toolInventory = new ToolItemStackHandler(9); - - private IItemHandler combinedInventory; + private IItemHandlerModifiable combinedInventory; + private IItemHandlerModifiable connectedInventory; private final CraftingRecipeMemory recipeMemory = new CraftingRecipeMemory(9); private CraftingRecipeLogic recipeLogic = null; @@ -192,7 +197,7 @@ public void readFromNBT(NBTTagCompound data) { this.recipeMemory.deserializeNBT(data.getCompoundTag("RecipeMemory")); } - public IItemHandler getAvailableHandlers() { + public IItemHandlerModifiable getAvailableHandlers() { var handlers = new ArrayList(); for (var facing : EnumFacing.VALUES) { var neighbor = getNeighbor(facing); @@ -200,10 +205,10 @@ public IItemHandler getAvailableHandlers() { var handler = neighbor.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()); if (handler != null) handlers.add(handler); } + this.connectedInventory = new ItemHandlerList(handlers); handlers.add(this.internalInventory); handlers.add(this.toolInventory); - this.combinedInventory = new ItemHandlerList(handlers); - return this.combinedInventory; + return this.combinedInventory = new ItemHandlerList(handlers); } @Override @@ -286,8 +291,10 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .tab(GuiTextures.TAB_TOP, 0) .overlay(new ItemDrawable(new ItemStack(Blocks.CHEST)) .asIcon().size(16)))) + .child(IKey.lang(getMetaFullName()).asWidget() + .top(7).left(7)) .child(new PagedWidget<>() - .top(7) + .top(22) .margin(7) .coverChildren() .controller(controller) @@ -340,13 +347,11 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .slotGroup(inventory))) .build())) .addPage(new Column() - .expanded() - .child(new Grid() - .heightRel(.9f).coverChildrenWidth() - .child(SlotGroupWidget.builder() - .matrix(combinedMatrix) - .key(key, this::createInventoryList) - .build().marginRight(4))))) + .margin(7, 0) + .background(GTGuiTextures.DISPLAY) + .coverChildren() + .padding(2) + .child(createInventoryList(guiSyncManager)))) .bindPlayerInventory(); } @@ -356,12 +361,27 @@ public void sendHandlerToClient(PacketBuffer buffer) { getCraftingRecipeLogic().writeAvailableStacks(buffer); } - public IWidget createInventoryList(int slot) { - if (slot >= this.combinedInventory.getSlots()) { - return GuiTextures.DISABLED.asWidget().size(18); + public IWidget createInventoryList(GuiSyncManager syncManager) { + var connected = new SlotGroup("connected_inventory", 9, true); + syncManager.registerSlotGroup(connected); + + List list = new ArrayList<>(this.connectedInventory.getSlots()); + for (int i = 0; i < this.connectedInventory.getSlots(); i++) { + if (i < this.connectedInventory.getSlots()) { + list.add(new ItemSlot() + .slot(SyncHandlers.itemSlot(this.connectedInventory, i) + .slotGroup(connected))); + //todo maybe show what inventory a slot belongs to? + continue; + } + list.add(GuiTextures.DISABLED.asWidget().size(18)); } - return new ItemSlot() - .slot(SyncHandlers.itemSlot((IItemHandlerModifiable) this.combinedInventory, slot)); + return new Grid() + .coverChildrenWidth() + .height(18 * 6) + .scrollable(new VerticalScrollData(), null) + .minElementMargin(0, 0) + .mapTo(8, list, (index, value) -> value); } @Override From 23e2bcf5b773cdd02bc939ba1799d7ff2a2c64bf Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:40:47 -0700 Subject: [PATCH 040/147] add method to get result stack --- .../common/metatileentities/storage/CachedRecipeData.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 8ba3e8f6e78..1db38a93ca0 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -1,6 +1,7 @@ package gregtech.common.metatileentities.storage; import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.world.World; @@ -31,4 +32,8 @@ public void setRecipe(IRecipe newRecipe) { public IRecipe getRecipe() { return recipe; } + + public ItemStack getRecipeOutput() { + return recipe == null ? ItemStack.EMPTY : recipe.getRecipeOutput(); + } } From c210058958064e06473b357f4497d36bf40b11ad Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:42:07 -0700 Subject: [PATCH 041/147] fix issues with tools being damages fix crafting matrix changing unexpectedly --- .../storage/CraftingRecipeLogic.java | 129 ++++++++++-------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index b6e6ba2d231..b2f228146b2 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -1,5 +1,6 @@ package gregtech.common.metatileentities.storage; +import gregtech.api.items.toolitem.IGTTool; import gregtech.api.util.DummyContainer; import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; @@ -7,7 +8,6 @@ import gregtech.api.util.ItemStackHashStrategy; import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; @@ -133,49 +133,53 @@ public boolean getIngredientEquivalent(int slot) { (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); // iterate stored items to find equivalent - for (var item : stackLookupMap.entrySet()) { - var itemStack = availableHandlers.getStackInSlot(item.getValue().get(0)); - boolean matchedPreviously = false; - if (map.containsKey(itemStack)) { - if (!map.get(itemStack)) { - continue; - } else { - // cant return here before checking if: - // The item is available for extraction - // The recipe output is still the same, as depending on the ingredient, the output NBT may change - matchedPreviously = true; + for (var entry : stackLookupMap.entrySet()) { + for (int i : entry.getValue()) { + var itemStack = availableHandlers.getStackInSlot(i); + + boolean matchedPreviously = false; + if (map.containsKey(itemStack)) { + if (!map.get(itemStack)) { + continue; + } else { + // cant return here before checking if: + // The item is available for extraction + // The recipe output is still the same, as depending on the ingredient, the output NBT may change + matchedPreviously = true; + } } - } - if (!matchedPreviously) { - boolean matched = false; - // Matching shapeless recipes actually is very bad for performance, as it checks the entire - // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can - // take the stack - for (Ingredient in : recipe.getIngredients()) { - if (in.apply(itemStack)) { - matched = true; - break; + if (!matchedPreviously) { + boolean matched = false; + // Matching shapeless recipes actually is very bad for performance, as it checks the entire + // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can + // take the stack + for (Ingredient in : recipe.getIngredients()) { + if (in.apply(itemStack)) { + matched = true; + break; + } + } + if (!matched) { + map.put(itemStack.copy(), false); + continue; } } - if (!matched) { - map.put(itemStack.copy(), false); - continue; - } - } - // update item in slot, and check that recipe matches and output item is equal to the expected one - craftingMatrix.setInventorySlotContents(slot, itemStack); - if (ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack) || - recipe instanceof ShapedOreEnergyTransferRecipe) { - map.put(itemStack, true); - // ingredient matched, attempt to extract it and return if successful - if (simulateExtractItem(itemStack)) { - return true; + // update item in slot, and check that recipe matches and output item is equal to the expected one + craftingMatrix.setInventorySlotContents(slot, itemStack); + if ((cachedRecipeData.matches(craftingMatrix, world) && + ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack)) || + recipe instanceof ShapedOreEnergyTransferRecipe) { + map.put(itemStack, true); + // ingredient matched, attempt to extract it and return if successful + if (simulateExtractItem(itemStack)) { + return true; + } } + map.put(itemStack, false); + craftingMatrix.setInventorySlotContents(slot, currentStack); } - map.put(itemStack, false); - craftingMatrix.setInventorySlotContents(slot, currentStack); } // nothing matched, so return null return false; @@ -201,18 +205,20 @@ private boolean simulateExtractItem(ItemStack itemStack) { return false; } - public boolean performRecipe(EntityPlayer player) { + public void performRecipe() { if (!isRecipeValid()) { - return false; + return; } - if (!getSyncManager().isClient() && this.collectAvailableItems()) + if (!getSyncManager().isClient()) syncToClient(1, this::writeAvailableStacks); if (!attemptMatchRecipe() || !consumeRecipeItems()) { - return false; + return; } + var cachedRecipe = cachedRecipeData.getRecipe(); + var player = getSyncManager().getPlayer(); ForgeHooks.setCraftingPlayer(player); // todo right here is where tools get damaged (in UI) NonNullList remainingItems = cachedRecipe.getRemainingItems(craftingMatrix); @@ -223,13 +229,13 @@ public boolean performRecipe(EntityPlayer player) { continue; } - ItemStack current = craftingMatrix.getStackInSlot(i); - craftingMatrix.setInventorySlotContents(i, itemStack); - if (!cachedRecipe.matches(craftingMatrix, this.world)) { - craftingMatrix.setInventorySlotContents(i, current); - } +// ItemStack current = craftingMatrix.getStackInSlot(i); +// craftingMatrix.setInventorySlotContents(i, itemStack); +// if (!cachedRecipe.matches(craftingMatrix, this.world)) { +// craftingMatrix.setInventorySlotContents(i, current); +// } - int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, false).getCount(); + int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, true).getCount(); if (remainingAmount > 0) { itemStack.setCount(remainingAmount); if (!player.addItemStackToInventory(itemStack)) { @@ -237,15 +243,14 @@ public boolean performRecipe(EntityPlayer player) { } } } - return true; } protected boolean consumeRecipeItems() { - Object2IntMap gatheredItems = new Object2IntOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount());; if (requiredItems.isEmpty()) { return false; } + Object2IntMap gatheredItems = new Object2IntOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount()); for (var entry : requiredItems.entrySet()) { ItemStack stack = entry.getKey(); @@ -256,10 +261,11 @@ protected boolean consumeRecipeItems() { } int extractedAmount = 0; for (int slot : slotList) { - var extracted = availableHandlers.extractItem(slot, requestedAmount, true).copy(); + var extracted = availableHandlers.extractItem(slot, requestedAmount, true); gatheredItems.put(extracted, slot); extractedAmount += extracted.getCount(); - if (extractedAmount == requestedAmount) break; + requestedAmount -= extractedAmount; + if (requestedAmount == 0) break; } if (extractedAmount < requestedAmount) return false; } @@ -271,7 +277,15 @@ protected boolean consumeRecipeItems() { if (stack.isEmpty()) { stackLookupMap.get(stack).remove(slot); } else { - availableHandlers.extractItem(slot, stack.getCount(), false); + if (stack.getItem().hasContainerItem(stack) && stack.isItemStackDamageable()) { + int damage = 1; + if (stack.getItem() instanceof IGTTool gtTool) { + damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); + } + stack.damageItem(damage, getSyncManager().getPlayer()); + } else { + availableHandlers.extractItem(slot, stack.getCount(), false); + } extracted = true; } } @@ -317,6 +331,7 @@ public CachedRecipeData getCachedRecipeData() { public void writeAvailableStacks(PacketBuffer buffer) { + this.collectAvailableItems(); Map written = new Int2ObjectArrayMap<>(); for (var slots : this.stackLookupMap.entrySet()) { for (var slot : slots.getValue()) { @@ -332,8 +347,7 @@ public void writeAvailableStacks(PacketBuffer buffer) { } } - public boolean collectAvailableItems() { - var oldMap = this.stackLookupMap.clone(); + public void collectAvailableItems() { this.stackLookupMap.clear(); for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var stack = this.availableHandlers.getStackInSlot(i); @@ -342,7 +356,6 @@ public boolean collectAvailableItems() { .computeIfAbsent(stack, k -> new IntArrayList()) .add(i); } - return !oldMap.equals(this.stackLookupMap); } @Override @@ -362,9 +375,7 @@ public void readOnServer(int id, PacketBuffer buf) { } catch (IOException ignore) {} } } else if (id == 1) { - if (this.collectAvailableItems()) { - syncToClient(1, this::writeAvailableStacks); - } + syncToClient(1, this::writeAvailableStacks); } } From 8140c0395a4427a2eb90014b60501c2120f6a7ed Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:42:37 -0700 Subject: [PATCH 042/147] more work on ui --- .../storage/MetaTileEntityWorkbench.java | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 6f38e446d12..4d03bb3bba5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,11 +1,5 @@ package gregtech.common.metatileentities.storage; -import com.cleanroommc.modularui.widget.ScrollWidget; - -import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; - -import com.cleanroommc.modularui.widgets.layout.Grid; - import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; @@ -51,11 +45,13 @@ import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.PageButton; import com.cleanroommc.modularui.widgets.PagedWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Grid; import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.cleanroommc.modularui.widgets.slot.SlotGroup; @@ -68,7 +64,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class MetaTileEntityWorkbench extends MetaTileEntity { @@ -253,20 +248,13 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { final String[] craftingGrid = new String[] {"XXX", "XXX", "XXX"}; final char key = 'X'; - this.combinedInventory = getAvailableHandlers(); - int rows = 1 + this.combinedInventory.getSlots() / 8; - final String[] combinedMatrix = new String[rows]; - Arrays.fill(combinedMatrix, "XXXXXXXX"); // 8 slots wide - var toolSlots = new SlotGroup("tool_slots", 9, true); var inventory = new SlotGroup("inventory", 9, true); - var craftingMatrix = new SlotGroup("crafting_matrix", 3, false); guiSyncManager.registerSlotGroup(toolSlots); guiSyncManager.registerSlotGroup(inventory); - guiSyncManager.registerSlotGroup(craftingMatrix); getCraftingRecipeLogic().updateCurrentRecipe(); - if (!guiSyncManager.isClient() && getCraftingRecipeLogic().collectAvailableItems()) { + if (!guiSyncManager.isClient()) { writeCustomData(UPDATE_CLIENT_STACKS, getCraftingRecipeLogic()::writeAvailableStacks); } @@ -298,16 +286,17 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .margin(7) .coverChildren() .controller(controller) + // workstation page .addPage(new Column() .coverChildren() .child(new Row().coverChildrenHeight() .widthRel(1f) .marginBottom(2) + // crafting grid .child(SlotGroupWidget.builder() .matrix(craftingGrid) .key(key, i -> new ItemSlot() .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) - .slotGroup(craftingMatrix) .changeListener((newItem, onlyAmountChanged, client, init) -> { if (!init) { this.recipeLogic.updateCurrentRecipe(); @@ -316,6 +305,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .build()) .child(new Column() .size(54) + // crafting output slot .child(new ItemSlot().marginTop(18) // todo figure this shit (recipe output slot) out .slot(new CraftingOutputSlot(new InventoryWrapper( @@ -325,13 +315,16 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .marginBottom(4)) .child(IKey.dynamic(amountCrafted::getStringValue) .alignment(Alignment.Center) - .asWidget().width(22))) + .asWidget().widthRel(1f))) + // recipe memory .child(SlotGroupWidget.builder() .matrix(craftingGrid) .key(key, i -> new ItemSlot() // todo recipe memory - .slot(SyncHandlers.phantomItemSlot(new ItemStackHandler(9), i))) + .slot(SyncHandlers.phantomItemSlot(new ItemStackHandler(9), i) + .accessibility(false, false))) .build().right(0))) + // tool inventory .child(SlotGroupWidget.builder() .row(nineSlot) .key(key, i -> new ItemSlot() @@ -339,6 +332,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .slot(SyncHandlers.itemSlot(this.toolInventory, i) .slotGroup(toolSlots))) .build().marginBottom(2)) + // internal inventory .child(SlotGroupWidget.builder() .row(nineSlot) .row(nineSlot) @@ -346,6 +340,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .slot(SyncHandlers.itemSlot(this.internalInventory, i) .slotGroup(inventory))) .build())) + // storage page .addPage(new Column() .margin(7, 0) .background(GTGuiTextures.DISPLAY) @@ -357,7 +352,6 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { public void sendHandlerToClient(PacketBuffer buffer) { buffer.writeVarInt(this.combinedInventory.getSlots()); - getCraftingRecipeLogic().collectAvailableItems(); getCraftingRecipeLogic().writeAvailableStacks(buffer); } @@ -418,18 +412,25 @@ public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { @Override public boolean canTakeStack(EntityPlayer playerIn) { - return recipeLogic.performRecipe(playerIn); + return recipeLogic.isRecipeValid() && recipeLogic.attemptMatchRecipe(); } @Override public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { + recipeLogic.performRecipe(); handleItemCraft(stack, thePlayer); return super.onTake(thePlayer, stack); } @Override public void putStack(@NotNull ItemStack stack) { - super.putStack(stack); + if (stack.isEmpty()) recipeLogic.consumeRecipeItems(); + super.putStack(recipeLogic.getCachedRecipeData().getRecipeOutput()); + } + + @Override + public ItemStack decrStackSize(int amount) { + return getStack(); } public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { From 7e5c6a52fa6fbf1f217625c2ba1e64af44e60bca Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:01:36 -0700 Subject: [PATCH 043/147] help me --- .../metatileentities/storage/CraftingRecipeLogic.java | 8 +++++--- .../metatileentities/storage/MetaTileEntityWorkbench.java | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index b2f228146b2..ba86fff3181 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -206,9 +206,7 @@ private boolean simulateExtractItem(ItemStack itemStack) { } public void performRecipe() { - if (!isRecipeValid()) { - return; - } + if (!isRecipeValid()) return; if (!getSyncManager().isClient()) syncToClient(1, this::writeAvailableStacks); @@ -362,6 +360,8 @@ public void collectAvailableItems() { public void readOnClient(int id, PacketBuffer buf) { if (id == 1) { updateClientStacks(buf); + } else if (id == 3) { + syncToServer(3); } } @@ -376,6 +376,8 @@ public void readOnServer(int id, PacketBuffer buf) { } } else if (id == 1) { syncToClient(1, this::writeAvailableStacks); + } else if (id == 3) { + syncToClient(1, this::writeAvailableStacks); } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 4d03bb3bba5..0139ae033d8 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -412,7 +412,8 @@ public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { @Override public boolean canTakeStack(EntityPlayer playerIn) { - return recipeLogic.isRecipeValid() && recipeLogic.attemptMatchRecipe(); + if (recipeLogic.getSyncManager().isClient()) recipeLogic.syncToServer(3); + return recipeLogic.isRecipeValid(); } @Override @@ -424,7 +425,6 @@ public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { @Override public void putStack(@NotNull ItemStack stack) { - if (stack.isEmpty()) recipeLogic.consumeRecipeItems(); super.putStack(recipeLogic.getCachedRecipeData().getRecipeOutput()); } From 7d79d7116603cb3e8fe380367e02c9993b2bb57d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:27:58 -0700 Subject: [PATCH 044/147] only set stack if item is different from current no need to call super for onContentsChanged --- .../api/items/itemhandlers/GTItemStackHandler.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java b/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java index eab9612c747..91c5a6f2853 100644 --- a/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java +++ b/src/main/java/gregtech/api/items/itemhandlers/GTItemStackHandler.java @@ -25,9 +25,16 @@ public GTItemStackHandler(MetaTileEntity metaTileEntity, NonNullList this.metaTileEntity = metaTileEntity; } + @Override + public void setStackInSlot(int slot, ItemStack stack) { + if (ItemStack.areItemStacksEqual(stack, getStackInSlot(slot))) + return; + + super.setStackInSlot(slot, stack); + } + @Override public void onContentsChanged(int slot) { - super.onContentsChanged(slot); metaTileEntity.markDirty(); } } From a7d046f6909759b7348cb8f01d631a1ed6e8a11f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:28:35 -0700 Subject: [PATCH 045/147] don't throw exception remove useless local var --- .../gregtech/api/capability/impl/ItemHandlerList.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java index c696ee00759..762262daa50 100644 --- a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java +++ b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java @@ -41,16 +41,18 @@ public int getSlots() { @Override public void setStackInSlot(int slot, @NotNull ItemStack stack) { IItemHandler itemHandler = handlerBySlotIndex.get(slot); - if (!(itemHandler instanceof IItemHandlerModifiable)) - throw new UnsupportedOperationException("Handler " + itemHandler + " does not support this method"); - ((IItemHandlerModifiable) itemHandler).setStackInSlot(slot - baseIndexOffset.get(itemHandler), stack); + if (itemHandler instanceof IItemHandlerModifiable modifiable) { + modifiable.setStackInSlot(slot - baseIndexOffset.get(itemHandler), stack); + } else { + itemHandler.extractItem(slot, Integer.MAX_VALUE, false); + itemHandler.insertItem(slot, stack, false); + } } @NotNull @Override public ItemStack getStackInSlot(int slot) { IItemHandler itemHandler = handlerBySlotIndex.get(slot); - int realSlot = slot - baseIndexOffset.get(itemHandler); return itemHandler.getStackInSlot(slot - baseIndexOffset.get(itemHandler)); } From 4bbea3441e5c0548fd6c617ca1c56a6352523464 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:29:00 -0700 Subject: [PATCH 046/147] notify neighbors on slot change --- .../storage/MetaTileEntityCrate.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java index 1f00f06818b..11f209a86e2 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java @@ -148,8 +148,19 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) for (int i = 0; i < rows; i++) { widgets.add(new ArrayList<>()); for (int j = 0; j < this.rowSize; j++) { - widgets.get(i).add(new ItemSlot().slot(SyncHandlers.itemSlot(inventory, i * rowSize + j) - .slotGroup("item_inv"))); + int index = i * rowSize + j; + widgets.get(i).add(new ItemSlot().slot(SyncHandlers.itemSlot(inventory, index) + .slotGroup("item_inv") + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (!onlyAmountChanged && !client) { + for (var facing : EnumFacing.VALUES) { + var neighbor = getNeighbor(facing); + if (neighbor instanceof IGregTechTileEntity gregTechTileEntity) { + gregTechTileEntity.getMetaTileEntity().onNeighborChanged(); + } + } + } + }))); } } return GTGuis.createPanel(this, rowSize * 18 + 14, 18 + 4 * 18 + 5 + 14 + 18 * rows) From 7ab42941527a54d7807e1444bfdc305521b1d50d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:29:28 -0700 Subject: [PATCH 047/147] make handler modifiable --- .../storage/CraftingRecipeLogic.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index ba86fff3181..daec9148562 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -43,7 +43,7 @@ public class CraftingRecipeLogic extends SyncHandler { private final World world; - private IItemHandler availableHandlers; + private IItemHandlerModifiable availableHandlers; /** Used to lookup a list of slots for a given stack */ private final Object2ObjectOpenCustomHashMap> stackLookupMap = @@ -62,7 +62,7 @@ public class CraftingRecipeLogic extends SyncHandler { public static short ALL_INGREDIENTS_PRESENT = 511; private short tintLocation = ALL_INGREDIENTS_PRESENT; - public CraftingRecipeLogic(World world, IItemHandler handlers, IItemHandlerModifiable craftingMatrix) { + public CraftingRecipeLogic(World world, IItemHandlerModifiable handlers, IItemHandlerModifiable craftingMatrix) { this.world = world; this.availableHandlers = handlers; this.craftingMatrix = new CraftingWrapper(craftingMatrix); @@ -82,7 +82,7 @@ public InventoryCrafting getCraftingMatrix() { return this.craftingMatrix; } - public void updateInventory(IItemHandler handler) { + public void updateInventory(IItemHandlerModifiable handler) { this.availableHandlers = handler; } @@ -362,6 +362,10 @@ public void readOnClient(int id, PacketBuffer buf) { updateClientStacks(buf); } else if (id == 3) { syncToServer(3); + } else if (id == 5) { + int slot = buf.readVarInt(); + var stack = readStackSafe(buf); + this.availableHandlers.setStackInSlot(slot, stack); } } @@ -378,6 +382,12 @@ public void readOnServer(int id, PacketBuffer buf) { syncToClient(1, this::writeAvailableStacks); } else if (id == 3) { syncToClient(1, this::writeAvailableStacks); + } else if (id == 4) { + int slot = buf.readVarInt(); + syncToClient(5, buffer -> { + buffer.writeVarInt(slot); + writeStackSafe(buffer, availableHandlers.getStackInSlot(slot)); + }); } } From 3fdbd22d8e2f5d85de7f3cdb626a631105015431 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:30:04 -0700 Subject: [PATCH 048/147] sync on contents change re arrange handler list --- .../storage/MetaTileEntityWorkbench.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 0139ae033d8..f5ea18bd8b9 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -72,9 +72,27 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { public static final int UPDATE_CLIENT_STACKS = GregtechDataCodes.assignId(); public static final int UPDATE_CLIENT_HANDLER = GregtechDataCodes.assignId(); - private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18); private final ItemStackHandler craftingGrid = new SingleItemStackHandler(9); - private final ItemStackHandler toolInventory = new ToolItemStackHandler(9); + private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18) { + + @Override + protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + var logic = getCraftingRecipeLogic(); + if (logic.isValid() && logic.getSyncManager().isClient()) + logic.syncToServer(4, buffer -> buffer.writeVarInt(slot)); + } + }; + private final ItemStackHandler toolInventory = new ToolItemStackHandler(9) { + @Override + protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + var logic = getCraftingRecipeLogic(); + if (logic.isValid() && logic.getSyncManager().isClient()) + logic.syncToServer(4, buffer -> buffer.writeVarInt(slot)); + } + }; + private IItemHandlerModifiable combinedInventory; private IItemHandlerModifiable connectedInventory; @@ -201,8 +219,11 @@ public IItemHandlerModifiable getAvailableHandlers() { if (handler != null) handlers.add(handler); } this.connectedInventory = new ItemHandlerList(handlers); + handlers.clear(); + handlers.add(this.internalInventory); handlers.add(this.toolInventory); + handlers.add(this.connectedInventory); return this.combinedInventory = new ItemHandlerList(handlers); } From 45def9168425b5dce24a8f37b60a6652835bbfbc Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 3 Feb 2024 13:56:41 -0700 Subject: [PATCH 049/147] don't call change on init --- .../common/metatileentities/storage/MetaTileEntityCrate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java index 11f209a86e2..3e00c251170 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java @@ -152,7 +152,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) widgets.get(i).add(new ItemSlot().slot(SyncHandlers.itemSlot(inventory, index) .slotGroup("item_inv") .changeListener((newItem, onlyAmountChanged, client, init) -> { - if (!onlyAmountChanged && !client) { + if (!onlyAmountChanged && !client && !init) { for (var facing : EnumFacing.VALUES) { var neighbor = getNeighbor(facing); if (neighbor instanceof IGregTechTileEntity gregTechTileEntity) { From b5ceb78f15fd147c1c00c5d8be37b715e4e6fbac Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 4 Feb 2024 14:24:44 -0700 Subject: [PATCH 050/147] start work on recipe memorization --- .../MemorizedRecipeWidget.java | 2 +- .../storage/CraftingRecipeMemory.java | 18 ++- .../storage/MetaTileEntityWorkbench.java | 127 +++++++++++++++--- 3 files changed, 124 insertions(+), 23 deletions(-) diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java index 4bbf93311b8..0aef242f630 100644 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java @@ -88,7 +88,7 @@ public ItemStack slotClick(int dragType, ClickType clickTypeIn, EntityPlayer pla MemorizedRecipe recipe = recipeMemory.getRecipeAtIndex(recipeIndex); if (recipe != null && !recipe.getRecipeResult().isEmpty()) { if (clickTypeIn == ClickType.PICKUP) { - recipeMemory.loadRecipe(recipeIndex, craftingGrid); +// recipeMemory.loadRecipe(recipeIndex, craftingGrid); player.openContainer.detectAndSendChanges(); } else if (clickTypeIn == ClickType.QUICK_MOVE) { recipe.setRecipeLocked(!recipe.isRecipeLocked()); diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index daa4ff85b3c..74d4ee0ce65 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -13,15 +13,17 @@ public class CraftingRecipeMemory { private final MemorizedRecipe[] memorizedRecipes; + private final IItemHandlerModifiable craftingMatrix; - public CraftingRecipeMemory(int memorySize) { + public CraftingRecipeMemory(IItemHandlerModifiable craftingMatrix, int memorySize) { + this.craftingMatrix = craftingMatrix; this.memorizedRecipes = new MemorizedRecipe[memorySize]; } - public void loadRecipe(int index, IItemHandlerModifiable craftingGrid) { + public void loadRecipe(int index) { MemorizedRecipe recipe = memorizedRecipes[index]; if (recipe != null) { - copyInventoryItems(recipe.craftingMatrix, craftingGrid); + copyInventoryItems(recipe.craftingMatrix, this.craftingMatrix); } } @@ -112,6 +114,16 @@ private static void copyInventoryItems(IItemHandler src, IItemHandlerModifiable } } + public final void removeRecipe(int index) { + if (hasRecipe(index)) { + memorizedRecipes[index] = null; + } + } + + public final boolean hasRecipe(int index) { + return memorizedRecipes[index] != null; + } + public static class MemorizedRecipe { private final ItemStackHandler craftingMatrix = new ItemStackHandler(9); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index f5ea18bd8b9..932ab56d97e 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,6 +1,19 @@ package gregtech.common.metatileentities.storage; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.core.mixin.GuiContainerAccessor; +import com.cleanroommc.modularui.drawable.GuiDraw; +import com.cleanroommc.modularui.drawable.TextRenderer; +import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.utils.NumberFormat; +import com.cleanroommc.modularui.widget.Widget; + import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.IFilter; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; @@ -12,16 +25,19 @@ import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -96,7 +112,7 @@ protected void onContentsChanged(int slot) { private IItemHandlerModifiable combinedInventory; private IItemHandlerModifiable connectedInventory; - private final CraftingRecipeMemory recipeMemory = new CraftingRecipeMemory(9); + private final CraftingRecipeMemory recipeMemory = new CraftingRecipeMemory(this.craftingGrid, 9); private CraftingRecipeLogic recipeLogic = null; private int itemsCrafted = 0; @@ -338,13 +354,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .alignment(Alignment.Center) .asWidget().widthRel(1f))) // recipe memory - .child(SlotGroupWidget.builder() - .matrix(craftingGrid) - .key(key, i -> new ItemSlot() - // todo recipe memory - .slot(SyncHandlers.phantomItemSlot(new ItemStackHandler(9), i) - .accessibility(false, false))) - .build().right(0))) + .child(createRecipeMemory(guiSyncManager))) // tool inventory .child(SlotGroupWidget.builder() .row(nineSlot) @@ -399,6 +409,15 @@ public IWidget createInventoryList(GuiSyncManager syncManager) { .mapTo(8, list, (index, value) -> value); } + public IWidget createRecipeMemory(GuiSyncManager syncManager) { + return SlotGroupWidget.builder() + .matrix("XXX", + "XXX", + "XXX") + .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) + .build().right(0); + } + @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); @@ -423,6 +442,87 @@ public void setItemsCrafted(int itemsCrafted) { this.itemsCrafted = itemsCrafted; } + private static class RecipeMemorySlot extends Widget implements Interactable { + + private final CraftingRecipeMemory memory; + private final int index; + private static final TextRenderer textRenderer = new TextRenderer(); + public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { + this.memory = memory; + this.index = index; + } + + @Override + public void onInit() { + size(ItemSlot.SIZE); + background(GTGuiTextures.SLOT); + } + + @Override + public void draw(GuiContext context, WidgetTheme widgetTheme) { + super.draw(context, widgetTheme); + drawStack(); + } + + public void drawStack() { + GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); + var recipe = memory.getRecipeAtIndex(index); + if (recipe == null) return; + ItemStack itemstack = recipe.getRecipeResult(); + + guiScreen.setZ(100f); + guiScreen.getItemRenderer().zLevel = 100.0F; + +// GuiDraw.drawRect(1, 1, 16, 16, -2130706433); + + if (!itemstack.isEmpty()) { + GlStateManager.enableDepth(); + // render the item itself + guiScreen.getItemRenderer().renderItemAndEffectIntoGUI(guiScreen.mc.player, itemstack, 1, 1); + + // render the amount overlay +// String amountText = NumberFormat.formatWithMaxDigits(1); +// textRenderer.setShadow(true); +// textRenderer.setColor(Color.WHITE.main); +// textRenderer.setAlignment(Alignment.BottomRight, getArea().width - 1, getArea().height - 1); +// textRenderer.setPos(1, 1); +// GlStateManager.disableLighting(); +// GlStateManager.disableDepth(); +// GlStateManager.disableBlend(); +// textRenderer.draw(amountText); +// GlStateManager.enableLighting(); +// GlStateManager.enableDepth(); +// GlStateManager.enableBlend(); + + int cachedCount = itemstack.getCount(); + itemstack.setCount(1); // required to not render the amount overlay + // render other overlays like durability bar + guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, null); + itemstack.setCount(cachedCount); + GlStateManager.disableDepth(); + } + + guiScreen.getItemRenderer().zLevel = 0.0F; + guiScreen.setZ(0f); + } + + @NotNull + @Override + public Result onMousePressed(int mouseButton) { + var data = MouseData.create(mouseButton); + if (data.shift && data.mouseButton == 0 && memory.hasRecipe(index)) { + var recipe = memory.getRecipeAtIndex(index); + recipe.setRecipeLocked(!recipe.isRecipeLocked()); + } else if (data.mouseButton == 0) { + memory.loadRecipe(index); + } else if (data.mouseButton == 1) { + if (memory.hasRecipe(index) && !memory.getRecipeAtIndex(index).isRecipeLocked()) + memory.removeRecipe(index); + } + return Result.ACCEPT; + } + } + private class CraftingOutputSlot extends ModularSlot { IntSyncValue syncValue; @@ -547,17 +647,6 @@ public void addInformation(ItemStack stack, @Nullable World world, List tooltip.add(I18n.format("gregtech.machine.workbench.tooltip2")); } -// public void discardRecipeResolver(EntityPlayer entityPlayer) { -// this.listeners.remove(entityPlayer); -// if (listeners.isEmpty()) { -// if (recipeLogic != null) { -// itemsCrafted = recipeLogic.getItemsCraftedAmount(); -// this.markDirty(); -// } -// recipeLogic = null; -// } -// } - public ItemStackHandler getCraftingGrid() { return craftingGrid; } From c8206a1d9687b3592a0916260c52ac3f384f87e9 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:05:18 -0700 Subject: [PATCH 051/147] small work --- .../storage/MetaTileEntityWorkbench.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 932ab56d97e..c20d71a466d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -354,7 +354,12 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .alignment(Alignment.Center) .asWidget().widthRel(1f))) // recipe memory - .child(createRecipeMemory(guiSyncManager))) + .child(SlotGroupWidget.builder() + .matrix("XXX", + "XXX", + "XXX") + .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) + .build().right(0))) // tool inventory .child(SlotGroupWidget.builder() .row(nineSlot) @@ -390,6 +395,7 @@ public IWidget createInventoryList(GuiSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 9, true); syncManager.registerSlotGroup(connected); + //todo this needs to handle when inventories are removed/added List list = new ArrayList<>(this.connectedInventory.getSlots()); for (int i = 0; i < this.connectedInventory.getSlots(); i++) { if (i < this.connectedInventory.getSlots()) { @@ -409,15 +415,6 @@ public IWidget createInventoryList(GuiSyncManager syncManager) { .mapTo(8, list, (index, value) -> value); } - public IWidget createRecipeMemory(GuiSyncManager syncManager) { - return SlotGroupWidget.builder() - .matrix("XXX", - "XXX", - "XXX") - .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) - .build().right(0); - } - @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); @@ -446,7 +443,7 @@ private static class RecipeMemorySlot extends Widget implement private final CraftingRecipeMemory memory; private final int index; - private static final TextRenderer textRenderer = new TextRenderer(); + public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.memory = memory; this.index = index; @@ -460,7 +457,6 @@ public void onInit() { @Override public void draw(GuiContext context, WidgetTheme widgetTheme) { - super.draw(context, widgetTheme); drawStack(); } From ab9c9a114241234045eeb2a83b10f09b61a04e71 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 22 Feb 2024 19:44:57 -0700 Subject: [PATCH 052/147] add handler wrapper to handle incorrect slot gracefully --- .../storage/MetaTileEntityWorkbench.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index c20d71a466d..955960d43c1 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -234,13 +234,13 @@ public IItemHandlerModifiable getAvailableHandlers() { var handler = neighbor.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()); if (handler != null) handlers.add(handler); } - this.connectedInventory = new ItemHandlerList(handlers); + this.connectedInventory = new HandlerListWrapper(handlers); handlers.clear(); handlers.add(this.internalInventory); handlers.add(this.toolInventory); handlers.add(this.connectedInventory); - return this.combinedInventory = new ItemHandlerList(handlers); + return this.combinedInventory = new HandlerListWrapper(handlers); } @Override @@ -617,6 +617,47 @@ public void setStackInSlot(int slot, ItemStack stack) { } } + private static class HandlerListWrapper extends ItemHandlerList { + + public HandlerListWrapper(List itemHandlerList) { + super(itemHandlerList); + } + + @Override + public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + if (validSlot(slot)) + return super.insertItem(slot, stack, simulate); + + return stack; + } + + @Override + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { + if (validSlot(slot)) + return super.extractItem(slot, amount, simulate); + + return ItemStack.EMPTY; + } + + @Override + public void setStackInSlot(int slot, @NotNull ItemStack stack) { + if (validSlot(slot)) + super.setStackInSlot(slot, stack); + } + + @Override + public @NotNull ItemStack getStackInSlot(int slot) { + if (validSlot(slot)) + return super.getStackInSlot(slot); + + return ItemStack.EMPTY; + } + + private boolean validSlot(int slot) { + return slot >= 0 || slot < this.getSlots(); + } + } + // @Override // protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { // From f1bc27192ccab4e8fee5e4fb0d5e056317e15dbb Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:10:35 -0700 Subject: [PATCH 053/147] spotless --- .../api/mui/GregTechGuiTransferHandler.java | 10 +- .../craftingstation/CraftingSlotWidget.java | 135 ++++++------ .../MemorizedRecipeWidget.java | 2 +- .../storage/CachedRecipeData.java | 1 + .../storage/CraftingRecipeLogic.java | 39 ++-- .../storage/MetaTileEntityWorkbench.java | 205 +++++++++--------- .../jei/JustEnoughItemsModule.java | 3 +- 7 files changed, 196 insertions(+), 199 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index d8e219783c9..802e3acb279 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -1,21 +1,14 @@ package gregtech.api.mui; -import gregtech.api.recipes.category.RecipeCategories; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; -import mezz.jei.api.recipe.IRecipeCategory; - -import mezz.jei.plugins.vanilla.crafting.CraftingRecipeCategory; - import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; -import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.screen.ModularContainer; import com.cleanroommc.modularui.value.sync.GuiSyncManager; -import com.cleanroommc.modularui.widgets.slot.ModularSlot; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; @@ -23,8 +16,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Objects; - public class GregTechGuiTransferHandler implements IRecipeTransferHandler { private final IRecipeTransferHandlerHelper handlerHelper; @@ -33,6 +24,7 @@ public class GregTechGuiTransferHandler implements IRecipeTransferHandler getContainerClass() { return ModularContainer.class; diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java index 3820187d641..e8bf56f0b4a 100644 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java @@ -11,7 +11,6 @@ import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; -import net.minecraftforge.items.wrapper.PlayerMainInvWrapper; import com.google.common.base.Preconditions; import mezz.jei.api.gui.IGuiIngredient; @@ -52,73 +51,73 @@ public void handleClientAction(int id, PacketBuffer buffer) { } recipeResolver.fillCraftingGrid(ingredients); } -// if (id == 2) { -// if (recipeResolver.isRecipeValid()) { -// ClickData clickData = ClickData.readFromBuf(buffer); -// boolean isShiftDown = clickData.isShiftClick; -// boolean isLeftClick = clickData.button == 0; -// boolean isRightClick = clickData.button == 1; -// EntityPlayer player = gui.entityPlayer; -// if (isShiftDown) { -// OverlayedItemHandler playerInventory = new OverlayedItemHandler( -// new PlayerMainInvWrapper(gui.entityPlayer.inventory)); -// ItemStack toMerge = slotReference.getStack(); -// int crafts = this.slotReference.getStack().getCount(); -// if (isLeftClick) { -// if (crafts != 0) { -// // limit shift click to one stack at a time -// int totalCrafts = 0; -// int maxCrafts = toMerge.getMaxStackSize() / crafts; -// for (int i = 0; i < maxCrafts; i++) { -// if (canMergeToInv(playerInventory, toMerge, crafts) && -// recipeResolver.performRecipe(gui.entityPlayer)) { -// this.recipeResolver.refreshOutputSlot(); -// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); -// totalCrafts += crafts; -// } -// } -// ItemStack toAdd = this.slotReference.getStack().copy(); -// toAdd.setCount(totalCrafts); -// player.inventory.addItemStackToInventory(toAdd); -// } -// } else if (isRightClick) { -// int totalCrafts = 0; -// while (canMergeToInv(playerInventory, toMerge, crafts) && -// recipeResolver.performRecipe(gui.entityPlayer)) { -// this.recipeResolver.refreshOutputSlot(); -// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); -// totalCrafts += crafts; -// } -// ItemStack toAdd = this.slotReference.getStack().copy(); -// toAdd.setCount(totalCrafts); -// player.inventory.addItemStackToInventory(toAdd); -// } -// } else { -// if (isLeftClick) { -// if (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && -// recipeResolver.performRecipe(gui.entityPlayer)) { -// this.recipeResolver.refreshOutputSlot(); -// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); -// // send slot changes now, both of consumed items in inventory and result slot -// ItemStack result = this.slotReference.getStack(); -// mergeToHand(result); -// } -// } else if (isRightClick) { -// while (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && -// recipeResolver.performRecipe(gui.entityPlayer)) { -// this.recipeResolver.refreshOutputSlot(); -// recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); -// ItemStack result = this.slotReference.getStack(); -// mergeToHand(result); -// } -// } -// } -// uiAccess.sendHeldItemUpdate(); -// // send slot changes now, both of consumed items in inventory and result slot -// gui.entityPlayer.openContainer.detectAndSendChanges(); -// uiAccess.sendSlotUpdate(this); -// } -// } + // if (id == 2) { + // if (recipeResolver.isRecipeValid()) { + // ClickData clickData = ClickData.readFromBuf(buffer); + // boolean isShiftDown = clickData.isShiftClick; + // boolean isLeftClick = clickData.button == 0; + // boolean isRightClick = clickData.button == 1; + // EntityPlayer player = gui.entityPlayer; + // if (isShiftDown) { + // OverlayedItemHandler playerInventory = new OverlayedItemHandler( + // new PlayerMainInvWrapper(gui.entityPlayer.inventory)); + // ItemStack toMerge = slotReference.getStack(); + // int crafts = this.slotReference.getStack().getCount(); + // if (isLeftClick) { + // if (crafts != 0) { + // // limit shift click to one stack at a time + // int totalCrafts = 0; + // int maxCrafts = toMerge.getMaxStackSize() / crafts; + // for (int i = 0; i < maxCrafts; i++) { + // if (canMergeToInv(playerInventory, toMerge, crafts) && + // recipeResolver.performRecipe(gui.entityPlayer)) { + // this.recipeResolver.refreshOutputSlot(); + // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); + // totalCrafts += crafts; + // } + // } + // ItemStack toAdd = this.slotReference.getStack().copy(); + // toAdd.setCount(totalCrafts); + // player.inventory.addItemStackToInventory(toAdd); + // } + // } else if (isRightClick) { + // int totalCrafts = 0; + // while (canMergeToInv(playerInventory, toMerge, crafts) && + // recipeResolver.performRecipe(gui.entityPlayer)) { + // this.recipeResolver.refreshOutputSlot(); + // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); + // totalCrafts += crafts; + // } + // ItemStack toAdd = this.slotReference.getStack().copy(); + // toAdd.setCount(totalCrafts); + // player.inventory.addItemStackToInventory(toAdd); + // } + // } else { + // if (isLeftClick) { + // if (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && + // recipeResolver.performRecipe(gui.entityPlayer)) { + // this.recipeResolver.refreshOutputSlot(); + // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); + // // send slot changes now, both of consumed items in inventory and result slot + // ItemStack result = this.slotReference.getStack(); + // mergeToHand(result); + // } + // } else if (isRightClick) { + // while (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && + // recipeResolver.performRecipe(gui.entityPlayer)) { + // this.recipeResolver.refreshOutputSlot(); + // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); + // ItemStack result = this.slotReference.getStack(); + // mergeToHand(result); + // } + // } + // } + // uiAccess.sendHeldItemUpdate(); + // // send slot changes now, both of consumed items in inventory and result slot + // gui.entityPlayer.openContainer.detectAndSendChanges(); + // uiAccess.sendSlotUpdate(this); + // } + // } } private static boolean canMerge(ItemStack stack, ItemStack stack1) { diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java index 0aef242f630..dbdddd41bd4 100644 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java @@ -88,7 +88,7 @@ public ItemStack slotClick(int dragType, ClickType clickTypeIn, EntityPlayer pla MemorizedRecipe recipe = recipeMemory.getRecipeAtIndex(recipeIndex); if (recipe != null && !recipe.getRecipeResult().isEmpty()) { if (clickTypeIn == ClickType.PICKUP) { -// recipeMemory.loadRecipe(recipeIndex, craftingGrid); + // recipeMemory.loadRecipe(recipeIndex, craftingGrid); player.openContainer.detectAndSendChanges(); } else if (clickTypeIn == ClickType.QUICK_MOVE) { recipe.setRecipeLocked(!recipe.isRecipeLocked()); diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 1db38a93ca0..aec49e23665 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -14,6 +14,7 @@ public class CachedRecipeData { public CachedRecipeData() { this(null); } + public CachedRecipeData(@Nullable IRecipe recipe) { this.recipe = recipe; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index daec9148562..791ffdee7be 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -21,7 +21,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.value.sync.GuiSyncManager; @@ -39,21 +38,22 @@ import java.util.List; import java.util.Map; -@SuppressWarnings("OverrideOnly") //stupid annotations conflicting with each other +@SuppressWarnings("OverrideOnly") // stupid annotations conflicting with each other public class CraftingRecipeLogic extends SyncHandler { private final World world; private IItemHandlerModifiable availableHandlers; /** Used to lookup a list of slots for a given stack */ - private final Object2ObjectOpenCustomHashMap> stackLookupMap = - new Object2ObjectOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); + private final Object2ObjectOpenCustomHashMap> stackLookupMap = new Object2ObjectOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount()); - /** List of items needed to complete the crafting recipe, + /** + * List of items needed to complete the crafting recipe, * filled by {@link CraftingRecipeLogic#getIngredientEquivalent(int)} **/ - private final Map requiredItems = - new Object2IntOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); + private final Map requiredItems = new Object2IntOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount()); private final Map> replaceAttemptMap = new Int2ObjectArrayMap<>(); private final InventoryCrafting craftingMatrix; @@ -98,6 +98,7 @@ public void fillCraftingGrid(Map ingredients) { /** * Attempts to match the crafting matrix against all available inventories + * * @return true if all items matched */ public boolean attemptMatchRecipe() { @@ -112,6 +113,7 @@ public boolean attemptMatchRecipe() { /** * Searches all available inventories for an ingredient equivalent for a stack in the crafting matrix + * * @param slot index of the crafting matrix * @return true if a valid substitute exists for the stack in the slot */ @@ -144,7 +146,8 @@ public boolean getIngredientEquivalent(int slot) { } else { // cant return here before checking if: // The item is available for extraction - // The recipe output is still the same, as depending on the ingredient, the output NBT may change + // The recipe output is still the same, as depending on the ingredient, the output NBT may + // change matchedPreviously = true; } } @@ -187,6 +190,7 @@ public boolean getIngredientEquivalent(int slot) { /** * Attempts to extract the given stack from connected inventories + * * @param itemStack - stack from the crafting matrix * @return true if the item exists in available inventories */ @@ -227,11 +231,11 @@ public void performRecipe() { continue; } -// ItemStack current = craftingMatrix.getStackInSlot(i); -// craftingMatrix.setInventorySlotContents(i, itemStack); -// if (!cachedRecipe.matches(craftingMatrix, this.world)) { -// craftingMatrix.setInventorySlotContents(i, current); -// } + // ItemStack current = craftingMatrix.getStackInSlot(i); + // craftingMatrix.setInventorySlotContents(i, itemStack); + // if (!cachedRecipe.matches(craftingMatrix, this.world)) { + // craftingMatrix.setInventorySlotContents(i, current); + // } int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, true).getCount(); if (remainingAmount > 0) { @@ -312,8 +316,8 @@ public IRecipe getCachedRecipe() { public void update() { if (getCachedRecipeData().getRecipe() != null) { - //todo fix tint location -// tintLocation = getCachedRecipeData().attemptMatchRecipe(); + // todo fix tint location + // tintLocation = getCachedRecipeData().attemptMatchRecipe(); } else { tintLocation = ALL_INGREDIENTS_PRESENT; } @@ -327,7 +331,6 @@ public CachedRecipeData getCachedRecipeData() { return this.cachedRecipeData; } - public void writeAvailableStacks(PacketBuffer buffer) { this.collectAvailableItems(); Map written = new Int2ObjectArrayMap<>(); @@ -415,7 +418,7 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { try { var tag = buffer.readCompoundTag(); if (tag == null) throw new IOException(); -// GTLog.logger.warn(String.format("Received: %s", tag)); + // GTLog.logger.warn(String.format("Received: %s", tag)); stack = new ItemStack(tag); } catch (IOException ignore) { GTLog.logger.warn("A stack was read incorrectly, something is seriously wrong!"); @@ -425,7 +428,7 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { var tag = stack.serializeNBT(); -// GTLog.logger.warn(String.format("Sent: %s", tag)); + // GTLog.logger.warn(String.format("Sent: %s", tag)); buffer.writeCompoundTag(tag); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 955960d43c1..0ad84f663d7 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,19 +1,6 @@ package gregtech.common.metatileentities.storage; -import com.cleanroommc.modularui.api.widget.Interactable; -import com.cleanroommc.modularui.core.mixin.GuiContainerAccessor; -import com.cleanroommc.modularui.drawable.GuiDraw; -import com.cleanroommc.modularui.drawable.TextRenderer; -import com.cleanroommc.modularui.screen.GuiScreenWrapper; -import com.cleanroommc.modularui.screen.viewport.GuiContext; -import com.cleanroommc.modularui.theme.WidgetTheme; -import com.cleanroommc.modularui.utils.Color; -import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.utils.NumberFormat; -import com.cleanroommc.modularui.widget.Widget; - import gregtech.api.capability.GregtechDataCodes; -import gregtech.api.capability.IFilter; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; @@ -30,14 +17,12 @@ import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -53,14 +38,20 @@ import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.GuiScreenWrapper; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.PageButton; @@ -100,6 +91,7 @@ protected void onContentsChanged(int slot) { } }; private final ItemStackHandler toolInventory = new ToolItemStackHandler(9) { + @Override protected void onContentsChanged(int slot) { super.onContentsChanged(slot); @@ -120,47 +112,53 @@ public MetaTileEntityWorkbench(ResourceLocation metaTileEntityId) { super(metaTileEntityId); } -// public static gregtech.api.gui.widgets.AbstractWidgetGroup createWorkbenchTab(CraftingRecipeLogic craftingRecipeLogic, -// ItemStackHandler craftingGrid, -// CraftingRecipeMemory recipeMemory, -// ItemStackHandler toolInventory, -// ItemStackHandler internalInventory) { -// gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); -// widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(88 - 13, 44 - 14, 26, 26, gregtech.api.gui.GuiTextures.SLOT)); -// widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.CraftingSlotWidget(craftingRecipeLogic, 0, 88 - 9, 44 - 9)); -// -// // crafting grid -// widgetGroup.addWidget(new gregtech.api.gui.widgets.CraftingStationInputWidgetGroup(4, 7, craftingGrid, craftingRecipeLogic)); -// -// Supplier textSupplier = () -> Integer.toString(craftingRecipeLogic.getItemsCraftedAmount()); -// widgetGroup.addWidget(new gregtech.api.gui.widgets.SimpleTextWidget(88, 44 + 19, "", textSupplier)); -// -// Consumer clearAction = (clickData) -> craftingRecipeLogic.clearCraftingGrid(); -// widgetGroup.addWidget(new gregtech.api.gui.widgets.ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction) -// .setButtonTexture(gregtech.api.gui.GuiTextures.BUTTON_CLEAR_GRID)); -// -// widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, -// gregtech.api.gui.resources.TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); -// for (int i = 0; i < 3; ++i) { -// for (int j = 0; j < 3; ++j) { -// widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget(recipeMemory, j + i * 3, craftingGrid, -// 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); -// } -// } -// // tool inventory -// for (int i = 0; i < 9; i++) { -// widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(toolInventory, i, 7 + i * 18, 75) -// .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, gregtech.api.gui.GuiTextures.TOOL_SLOT_OVERLAY)); -// } -// // internal inventory -// for (int i = 0; i < 2; ++i) { -// for (int j = 0; j < 9; ++j) { -// widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * 18) -// .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); -// } -// } -// return widgetGroup; -// } + // public static gregtech.api.gui.widgets.AbstractWidgetGroup createWorkbenchTab(CraftingRecipeLogic + // craftingRecipeLogic, + // ItemStackHandler craftingGrid, + // CraftingRecipeMemory recipeMemory, + // ItemStackHandler toolInventory, + // ItemStackHandler internalInventory) { + // gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); + // widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(88 - 13, 44 - 14, 26, 26, + // gregtech.api.gui.GuiTextures.SLOT)); + // widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.CraftingSlotWidget(craftingRecipeLogic, 0, + // 88 - 9, 44 - 9)); + // + // // crafting grid + // widgetGroup.addWidget(new gregtech.api.gui.widgets.CraftingStationInputWidgetGroup(4, 7, craftingGrid, + // craftingRecipeLogic)); + // + // Supplier textSupplier = () -> Integer.toString(craftingRecipeLogic.getItemsCraftedAmount()); + // widgetGroup.addWidget(new gregtech.api.gui.widgets.SimpleTextWidget(88, 44 + 19, "", textSupplier)); + // + // Consumer clearAction = (clickData) -> craftingRecipeLogic.clearCraftingGrid(); + // widgetGroup.addWidget(new gregtech.api.gui.widgets.ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction) + // .setButtonTexture(gregtech.api.gui.GuiTextures.BUTTON_CLEAR_GRID)); + // + // widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, + // gregtech.api.gui.resources.TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); + // for (int i = 0; i < 3; ++i) { + // for (int j = 0; j < 3; ++j) { + // widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget(recipeMemory, j + i * + // 3, craftingGrid, + // 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); + // } + // } + // // tool inventory + // for (int i = 0; i < 9; i++) { + // widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(toolInventory, i, 7 + i * 18, 75) + // .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, gregtech.api.gui.GuiTextures.TOOL_SLOT_OVERLAY)); + // } + // // internal inventory + // for (int i = 0; i < 2; ++i) { + // for (int j = 0; j < 9; ++j) { + // widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * + // 18) + // .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); + // } + // } + // return widgetGroup; + // } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { @@ -236,7 +234,7 @@ public IItemHandlerModifiable getAvailableHandlers() { } this.connectedInventory = new HandlerListWrapper(handlers); handlers.clear(); - + handlers.add(this.internalInventory); handlers.add(this.toolInventory); handlers.add(this.connectedInventory); @@ -282,7 +280,7 @@ public boolean usesMui2() { @Override public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { final String nineSlot = "XXXXXXXXX"; - final String[] craftingGrid = new String[] {"XXX", "XXX", "XXX"}; + final String[] craftingGrid = new String[] { "XXX", "XXX", "XXX" }; final char key = 'X'; var toolSlots = new SlotGroup("tool_slots", 9, true); @@ -334,11 +332,12 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .matrix(craftingGrid) .key(key, i -> new ItemSlot() .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) - .changeListener((newItem, onlyAmountChanged, client, init) -> { - if (!init) { - this.recipeLogic.updateCurrentRecipe(); - } - }))) + .changeListener( + (newItem, onlyAmountChanged, client, init) -> { + if (!init) { + this.recipeLogic.updateCurrentRecipe(); + } + }))) .build()) .child(new Column() .size(54) @@ -395,14 +394,14 @@ public IWidget createInventoryList(GuiSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 9, true); syncManager.registerSlotGroup(connected); - //todo this needs to handle when inventories are removed/added + // todo this needs to handle when inventories are removed/added List list = new ArrayList<>(this.connectedInventory.getSlots()); for (int i = 0; i < this.connectedInventory.getSlots(); i++) { if (i < this.connectedInventory.getSlots()) { list.add(new ItemSlot() - .slot(SyncHandlers.itemSlot(this.connectedInventory, i) - .slotGroup(connected))); - //todo maybe show what inventory a slot belongs to? + .slot(SyncHandlers.itemSlot(this.connectedInventory, i) + .slotGroup(connected))); + // todo maybe show what inventory a slot belongs to? continue; } list.add(GuiTextures.DISABLED.asWidget().size(18)); @@ -469,7 +468,7 @@ public void drawStack() { guiScreen.setZ(100f); guiScreen.getItemRenderer().zLevel = 100.0F; -// GuiDraw.drawRect(1, 1, 16, 16, -2130706433); + // GuiDraw.drawRect(1, 1, 16, 16, -2130706433); if (!itemstack.isEmpty()) { GlStateManager.enableDepth(); @@ -477,23 +476,24 @@ public void drawStack() { guiScreen.getItemRenderer().renderItemAndEffectIntoGUI(guiScreen.mc.player, itemstack, 1, 1); // render the amount overlay -// String amountText = NumberFormat.formatWithMaxDigits(1); -// textRenderer.setShadow(true); -// textRenderer.setColor(Color.WHITE.main); -// textRenderer.setAlignment(Alignment.BottomRight, getArea().width - 1, getArea().height - 1); -// textRenderer.setPos(1, 1); -// GlStateManager.disableLighting(); -// GlStateManager.disableDepth(); -// GlStateManager.disableBlend(); -// textRenderer.draw(amountText); -// GlStateManager.enableLighting(); -// GlStateManager.enableDepth(); -// GlStateManager.enableBlend(); + // String amountText = NumberFormat.formatWithMaxDigits(1); + // textRenderer.setShadow(true); + // textRenderer.setColor(Color.WHITE.main); + // textRenderer.setAlignment(Alignment.BottomRight, getArea().width - 1, getArea().height - 1); + // textRenderer.setPos(1, 1); + // GlStateManager.disableLighting(); + // GlStateManager.disableDepth(); + // GlStateManager.disableBlend(); + // textRenderer.draw(amountText); + // GlStateManager.enableLighting(); + // GlStateManager.enableDepth(); + // GlStateManager.enableBlend(); int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay // render other overlays like durability bar - guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, null); + guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, + null); itemstack.setCount(cachedCount); GlStateManager.disableDepth(); } @@ -520,6 +520,7 @@ public Result onMousePressed(int mouseButton) { } private class CraftingOutputSlot extends ModularSlot { + IntSyncValue syncValue; public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { @@ -565,7 +566,7 @@ public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { if (cachedRecipe != null) { ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, false); -// itemsCrafted += resultStack.getCount(); + // itemsCrafted += resultStack.getCount(); recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); } } @@ -658,25 +659,27 @@ private boolean validSlot(int slot) { } } -// @Override -// protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { -// -// gregtech.api.gui.ModularUI.Builder builder = gregtech.api.gui.ModularUI.builder(gregtech.api.gui.GuiTextures.BACKGROUND, 176, 221) -// .bindPlayerInventory(entityPlayer.inventory, 138); -// builder.label(5, 5, getMetaFullName()); -// -// gregtech.api.gui.widgets.TabGroup tabGroup = new gregtech.api.gui.widgets.TabGroup<>( -// gregtech.api.gui.widgets.TabGroup.TabLocation.HORIZONTAL_TOP_LEFT, Position.ORIGIN); -// tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.workbench", -// new ItemStack(Blocks.CRAFTING_TABLE)), -// createWorkbenchTab(recipeLogic, craftingGrid, recipeMemory, toolInventory, internalInventory)); -// tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.item_list", -// new ItemStack(Blocks.CHEST)), createItemListTab()); -// builder.widget(tabGroup); -// builder.bindCloseListener(() -> discardRecipeResolver(entityPlayer)); -// -// return builder.build(getHolder(), entityPlayer); -// } + // @Override + // protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { + // + // gregtech.api.gui.ModularUI.Builder builder = + // gregtech.api.gui.ModularUI.builder(gregtech.api.gui.GuiTextures.BACKGROUND, 176, 221) + // .bindPlayerInventory(entityPlayer.inventory, 138); + // builder.label(5, 5, getMetaFullName()); + // + // gregtech.api.gui.widgets.TabGroup tabGroup = new + // gregtech.api.gui.widgets.TabGroup<>( + // gregtech.api.gui.widgets.TabGroup.TabLocation.HORIZONTAL_TOP_LEFT, Position.ORIGIN); + // tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.workbench", + // new ItemStack(Blocks.CRAFTING_TABLE)), + // createWorkbenchTab(recipeLogic, craftingGrid, recipeMemory, toolInventory, internalInventory)); + // tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.item_list", + // new ItemStack(Blocks.CHEST)), createItemListTab()); + // builder.widget(tabGroup); + // builder.bindCloseListener(() -> discardRecipeResolver(entityPlayer)); + // + // return builder.build(getHolder(), entityPlayer); + // } @Override public void addInformation(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 8a715fb86a2..812f175f6fa 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -172,8 +172,7 @@ public void register(IModRegistry registry) { registry.getRecipeTransferRegistry().addRecipeTransferHandler(craftingStationGuiHandler, VanillaRecipeCategoryUid.CRAFTING); registry.getRecipeTransferRegistry().addRecipeTransferHandler(new GregTechGuiTransferHandler( - jeiHelpers.recipeTransferHandlerHelper() - ), VanillaRecipeCategoryUid.CRAFTING); + jeiHelpers.recipeTransferHandlerHelper()), VanillaRecipeCategoryUid.CRAFTING); for (RecipeMap recipeMap : RecipeMap.getRecipeMaps()) { if (recipeMap.getRecipeMapUI().isJEIVisible()) { From ea1ee98b1641aca9d342c0dbed2a03e197eb5481 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:36:19 -0700 Subject: [PATCH 054/147] add bogosorter as api --- dependencies.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/dependencies.gradle b/dependencies.gradle index 91d6a5d5c7e..9bd08ad39a0 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -42,6 +42,7 @@ dependencies { api("codechicken:codechickenlib:3.2.3.358") api("com.cleanroommc:modularui:2.5.0-rc2") { transitive = false } api("com.cleanroommc:groovyscript:1.2.0-hotfix1") { transitive = false } + api("curse.maven:inventory-bogosorter-632327:4951607-deobf-4951608-sources-4951609") api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.700") api("appeng:ae2-uel:v0.56.4") { transitive = false } api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 From e2d9cbf81d14c27ec359abb9651fa24e80899176 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 16 Apr 2024 19:12:49 -0700 Subject: [PATCH 055/147] remove commented out code --- .../storage/MetaTileEntityWorkbench.java | 70 ------------------- 1 file changed, 70 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 0ad84f663d7..252e5e41c29 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -112,54 +112,6 @@ public MetaTileEntityWorkbench(ResourceLocation metaTileEntityId) { super(metaTileEntityId); } - // public static gregtech.api.gui.widgets.AbstractWidgetGroup createWorkbenchTab(CraftingRecipeLogic - // craftingRecipeLogic, - // ItemStackHandler craftingGrid, - // CraftingRecipeMemory recipeMemory, - // ItemStackHandler toolInventory, - // ItemStackHandler internalInventory) { - // gregtech.api.gui.widgets.WidgetGroup widgetGroup = new gregtech.api.gui.widgets.WidgetGroup(); - // widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(88 - 13, 44 - 14, 26, 26, - // gregtech.api.gui.GuiTextures.SLOT)); - // widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.CraftingSlotWidget(craftingRecipeLogic, 0, - // 88 - 9, 44 - 9)); - // - // // crafting grid - // widgetGroup.addWidget(new gregtech.api.gui.widgets.CraftingStationInputWidgetGroup(4, 7, craftingGrid, - // craftingRecipeLogic)); - // - // Supplier textSupplier = () -> Integer.toString(craftingRecipeLogic.getItemsCraftedAmount()); - // widgetGroup.addWidget(new gregtech.api.gui.widgets.SimpleTextWidget(88, 44 + 19, "", textSupplier)); - // - // Consumer clearAction = (clickData) -> craftingRecipeLogic.clearCraftingGrid(); - // widgetGroup.addWidget(new gregtech.api.gui.widgets.ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction) - // .setButtonTexture(gregtech.api.gui.GuiTextures.BUTTON_CLEAR_GRID)); - // - // widgetGroup.addWidget(new gregtech.api.gui.widgets.ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, - // gregtech.api.gui.resources.TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); - // for (int i = 0; i < 3; ++i) { - // for (int j = 0; j < 3; ++j) { - // widgetGroup.addWidget(new gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget(recipeMemory, j + i * - // 3, craftingGrid, - // 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); - // } - // } - // // tool inventory - // for (int i = 0; i < 9; i++) { - // widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(toolInventory, i, 7 + i * 18, 75) - // .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT, gregtech.api.gui.GuiTextures.TOOL_SLOT_OVERLAY)); - // } - // // internal inventory - // for (int i = 0; i < 2; ++i) { - // for (int j = 0; j < 9; ++j) { - // widgetGroup.addWidget(new gregtech.api.gui.widgets.SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * - // 18) - // .setBackgroundTexture(gregtech.api.gui.GuiTextures.SLOT)); - // } - // } - // return widgetGroup; - // } - @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { return new MetaTileEntityWorkbench(metaTileEntityId); @@ -659,28 +611,6 @@ private boolean validSlot(int slot) { } } - // @Override - // protected gregtech.api.gui.ModularUI createUI(EntityPlayer entityPlayer) { - // - // gregtech.api.gui.ModularUI.Builder builder = - // gregtech.api.gui.ModularUI.builder(gregtech.api.gui.GuiTextures.BACKGROUND, 176, 221) - // .bindPlayerInventory(entityPlayer.inventory, 138); - // builder.label(5, 5, getMetaFullName()); - // - // gregtech.api.gui.widgets.TabGroup tabGroup = new - // gregtech.api.gui.widgets.TabGroup<>( - // gregtech.api.gui.widgets.TabGroup.TabLocation.HORIZONTAL_TOP_LEFT, Position.ORIGIN); - // tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.workbench", - // new ItemStack(Blocks.CRAFTING_TABLE)), - // createWorkbenchTab(recipeLogic, craftingGrid, recipeMemory, toolInventory, internalInventory)); - // tabGroup.addTab(new gregtech.api.gui.widgets.tab.ItemTabInfo("gregtech.machine.workbench.tab.item_list", - // new ItemStack(Blocks.CHEST)), createItemListTab()); - // builder.widget(tabGroup); - // builder.bindCloseListener(() -> discardRecipeResolver(entityPlayer)); - // - // return builder.build(getHolder(), entityPlayer); - // } - @Override public void addInformation(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { tooltip.add(I18n.format("gregtech.machine.workbench.tooltip1")); From 706c75c2104e6c8219d6c5818d90646e85784037 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 17 Apr 2024 17:05:52 -0700 Subject: [PATCH 056/147] ui testing something wrong with grid --- .../storage/MetaTileEntityWorkbench.java | 168 +++++++++++------- 1 file changed, 101 insertions(+), 67 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 252e5e41c29..cad7389e698 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,5 +1,7 @@ package gregtech.common.metatileentities.storage; +import com.cleanroommc.modularui.api.drawable.IDrawable; + import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; @@ -12,6 +14,12 @@ import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; +import gregtech.common.items.MetaItem1; + +import gregtech.common.items.MetaItems; + +import gregtech.common.metatileentities.MetaTileEntities; + import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; @@ -79,6 +87,12 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { public static final int UPDATE_CLIENT_STACKS = GregtechDataCodes.assignId(); public static final int UPDATE_CLIENT_HANDLER = GregtechDataCodes.assignId(); + private static final IDrawable CHEST = new ItemDrawable(new ItemStack(Blocks.CHEST)) + .asIcon().size(16); + + private final IDrawable WORKSTATION = new ItemDrawable(getStackForm()) + .asIcon().size(16); + private final ItemStackHandler craftingGrid = new SingleItemStackHandler(9); private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18) { @@ -231,42 +245,30 @@ public boolean usesMui2() { @Override public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { - final String nineSlot = "XXXXXXXXX"; - final String[] craftingGrid = new String[] { "XXX", "XXX", "XXX" }; - final char key = 'X'; - - var toolSlots = new SlotGroup("tool_slots", 9, true); - var inventory = new SlotGroup("inventory", 9, true); - guiSyncManager.registerSlotGroup(toolSlots); - guiSyncManager.registerSlotGroup(inventory); - getCraftingRecipeLogic().updateCurrentRecipe(); if (!guiSyncManager.isClient()) { writeCustomData(UPDATE_CLIENT_STACKS, getCraftingRecipeLogic()::writeAvailableStacks); } - var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); - guiSyncManager.syncValue("amount_crafted", amountCrafted); guiSyncManager.syncValue("recipe_logic", this.recipeLogic); - amountCrafted.updateCacheFromSource(true); var controller = new PagedWidget.Controller(); return GTGuis.createPanel(this, 176, 224) - .child(new Row().widthRel(1f) + .child(new Row() + .widthRel(1f) .leftRel(0.5f) .margin(3, 0) .coverChildrenHeight() .topRel(0f, 3, 1f) .child(new PageButton(0, controller) .tab(GuiTextures.TAB_TOP, 0) - .overlay(new ItemDrawable(getStackForm()) - .asIcon().size(16))) + .overlay(WORKSTATION)) .child(new PageButton(1, controller) .tab(GuiTextures.TAB_TOP, 0) - .overlay(new ItemDrawable(new ItemStack(Blocks.CHEST)) - .asIcon().size(16)))) - .child(IKey.lang(getMetaFullName()).asWidget() + .overlay(CHEST))) + .child(IKey.lang(getMetaFullName()) + .asWidget() .top(7).left(7)) .child(new PagedWidget<>() .top(22) @@ -275,65 +277,36 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .controller(controller) // workstation page .addPage(new Column() - .coverChildren() - .child(new Row().coverChildrenHeight() + .debugName("crafting section") + .coverChildrenWidth() + .child(new Row() + .debugName("crafting row") + .coverChildrenHeight() .widthRel(1f) - .marginBottom(2) // crafting grid - .child(SlotGroupWidget.builder() - .matrix(craftingGrid) - .key(key, i -> new ItemSlot() - .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) - .changeListener( - (newItem, onlyAmountChanged, client, init) -> { - if (!init) { - this.recipeLogic.updateCurrentRecipe(); - } - }))) - .build()) - .child(new Column() - .size(54) - // crafting output slot - .child(new ItemSlot().marginTop(18) - // todo figure this shit (recipe output slot) out - .slot(new CraftingOutputSlot(new InventoryWrapper( - this.recipeLogic.getCraftingResultInventory(), - guiData.getPlayer()), amountCrafted)) - .background(GTGuiTextures.SLOT.asIcon().size(22)) - .marginBottom(4)) - .child(IKey.dynamic(amountCrafted::getStringValue) - .alignment(Alignment.Center) - .asWidget().widthRel(1f))) + .child(createCraftingGrid()) + .child(createCraftingOutput(guiData, guiSyncManager)) // recipe memory .child(SlotGroupWidget.builder() .matrix("XXX", "XXX", "XXX") .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) - .build().right(0))) + .build().right(0)) + ) // tool inventory - .child(SlotGroupWidget.builder() - .row(nineSlot) - .key(key, i -> new ItemSlot() - .background(GTGuiTextures.SLOT, GTGuiTextures.INGOT_OVERLAY) - .slot(SyncHandlers.itemSlot(this.toolInventory, i) - .slotGroup(toolSlots))) - .build().marginBottom(2)) + .child(createToolInventory(guiSyncManager)) // internal inventory - .child(SlotGroupWidget.builder() - .row(nineSlot) - .row(nineSlot) - .key(key, i -> new ItemSlot() - .slot(SyncHandlers.itemSlot(this.internalInventory, i) - .slotGroup(inventory))) - .build())) + .child(createInternalInventory(guiSyncManager))) // storage page .addPage(new Column() + .debugName("inventory section") .margin(7, 0) .background(GTGuiTextures.DISPLAY) .coverChildren() .padding(2) - .child(createInventoryList(guiSyncManager)))) + .child(createInventoryList(guiSyncManager)) + )) .bindPlayerInventory(); } @@ -342,6 +315,66 @@ public void sendHandlerToClient(PacketBuffer buffer) { getCraftingRecipeLogic().writeAvailableStacks(buffer); } + public IWidget createToolInventory(GuiSyncManager syncManager) { + var toolSlots = new SlotGroup("tool_slots", 9, true); + syncManager.registerSlotGroup(toolSlots); + + return SlotGroupWidget.builder() + .row("XXXXXXXXX") + .key('X', i -> new ItemSlot() + .background(GTGuiTextures.SLOT, GTGuiTextures.INGOT_OVERLAY) + .slot(SyncHandlers.itemSlot(this.toolInventory, i) + .slotGroup(toolSlots))) + .build().marginTop(2); + } + + public IWidget createInternalInventory(GuiSyncManager syncManager) { + var inventory = new SlotGroup("inventory", 9, true); + syncManager.registerSlotGroup(inventory); + + return SlotGroupWidget.builder() + .row("XXXXXXXXX") + .row("XXXXXXXXX") + .key('X', i -> new ItemSlot() + .slot(SyncHandlers.itemSlot(this.internalInventory, i) + .slotGroup(inventory))) + .build().marginTop(2); + } + + public IWidget createCraftingGrid() { + return SlotGroupWidget.builder() + .matrix("XXX", "XXX", "XXX") + .key('X', i -> new ItemSlot() + .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) + .changeListener( + (newItem, onlyAmountChanged, client, init) -> { + if (!init) { + this.recipeLogic.updateCurrentRecipe(); + } + }))) + .build(); + } + + public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManager) { + var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); + syncManager.syncValue("amount_crafted", amountCrafted); + amountCrafted.updateCacheFromSource(true); + + return new Column() + .size(54) + // crafting output slot + .child(new ItemSlot().marginTop(18) + // todo figure this shit (recipe output slot) out + .slot(new CraftingOutputSlot(new InventoryWrapper( + this.recipeLogic.getCraftingResultInventory(), + guiData.getPlayer()), amountCrafted)) + .background(GTGuiTextures.SLOT.asIcon().size(22)) + .marginBottom(4)) + .child(IKey.dynamic(amountCrafted::getStringValue) + .alignment(Alignment.Center) + .asWidget().widthRel(1f)); + } + public IWidget createInventoryList(GuiSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 9, true); syncManager.registerSlotGroup(connected); @@ -358,12 +391,13 @@ public IWidget createInventoryList(GuiSyncManager syncManager) { } list.add(GuiTextures.DISABLED.asWidget().size(18)); } - return new Grid() - .coverChildrenWidth() - .height(18 * 6) - .scrollable(new VerticalScrollData(), null) - .minElementMargin(0, 0) - .mapTo(8, list, (index, value) -> value); + return new Column().size(64); +// return new Grid(); +// .coverChildrenWidth() +// .height(18 * 6); +// .scrollable(new VerticalScrollData(), null) +// .minElementMargin(0, 0) +// .mapTo(8, list, (index, value) -> value); } @Override From 037ab097ffc334075b18f1ce83da484afbf97efc Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 17 Apr 2024 18:05:43 -0700 Subject: [PATCH 057/147] more ui testing --- .../storage/MetaTileEntityWorkbench.java | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index cad7389e698..88dcf3c6393 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -14,12 +14,6 @@ import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; -import gregtech.common.items.MetaItem1; - -import gregtech.common.items.MetaItems; - -import gregtech.common.metatileentities.MetaTileEntities; - import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; @@ -299,14 +293,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { // internal inventory .child(createInternalInventory(guiSyncManager))) // storage page - .addPage(new Column() - .debugName("inventory section") - .margin(7, 0) - .background(GTGuiTextures.DISPLAY) - .coverChildren() - .padding(2) - .child(createInventoryList(guiSyncManager)) - )) + .addPage(createInventoryPage(guiSyncManager))) .bindPlayerInventory(); } @@ -375,7 +362,7 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag .asWidget().widthRel(1f)); } - public IWidget createInventoryList(GuiSyncManager syncManager) { + public IWidget createInventoryPage(GuiSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 9, true); syncManager.registerSlotGroup(connected); @@ -391,13 +378,16 @@ public IWidget createInventoryList(GuiSyncManager syncManager) { } list.add(GuiTextures.DISABLED.asWidget().size(18)); } - return new Column().size(64); -// return new Grid(); -// .coverChildrenWidth() -// .height(18 * 6); -// .scrollable(new VerticalScrollData(), null) -// .minElementMargin(0, 0) -// .mapTo(8, list, (index, value) -> value); + return new Column() + .debugName("inventory page") + .padding(2) + .background(GTGuiTextures.DISPLAY) + .height(18 * 6) + // todo for some reason mui has an issue with grids in paged widgets + .child(new Grid() + .scrollable(new VerticalScrollData(), null) + .minElementMargin(0, 0) + .mapTo(8, list, (index, value) -> value)); } @Override From e529cf0e42f505a1023ce1d3cb034b6e86dc2e48 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:38:21 -0700 Subject: [PATCH 058/147] fixed(?) the grid --- .../storage/MetaTileEntityWorkbench.java | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 88dcf3c6393..b1c95398d3a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -74,6 +74,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; public class MetaTileEntityWorkbench extends MetaTileEntity { @@ -267,7 +268,8 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(new PagedWidget<>() .top(22) .margin(7) - .coverChildren() + .widthRel(0.9f) +// .bottom(100) .controller(controller) // workstation page .addPage(new Column() @@ -363,29 +365,35 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag } public IWidget createInventoryPage(GuiSyncManager syncManager) { - var connected = new SlotGroup("connected_inventory", 9, true); + var connected = new SlotGroup("connected_inventory", 8, true); syncManager.registerSlotGroup(connected); // todo this needs to handle when inventories are removed/added List list = new ArrayList<>(this.connectedInventory.getSlots()); + Predicate checkSlotValid = itemSlot -> { + int slot = itemSlot.getSlot().getSlotIndex(); + return slot < this.connectedInventory.getSlots(); + }; + for (int i = 0; i < this.connectedInventory.getSlots(); i++) { - if (i < this.connectedInventory.getSlots()) { - list.add(new ItemSlot() - .slot(SyncHandlers.itemSlot(this.connectedInventory, i) - .slotGroup(connected))); - // todo maybe show what inventory a slot belongs to? - continue; - } - list.add(GuiTextures.DISABLED.asWidget().size(18)); + // todo maybe show what inventory a slot belongs to? + var widget = new ItemSlot() + .setEnabledIf(checkSlotValid) + .slot(SyncHandlers.itemSlot(this.connectedInventory, i) + .slotGroup(connected)); + widget.setEnabled(checkSlotValid.test(widget)); + list.add(widget); } return new Column() .debugName("inventory page") .padding(2) + .leftRel(0.5f) + .coverChildren() .background(GTGuiTextures.DISPLAY) - .height(18 * 6) - // todo for some reason mui has an issue with grids in paged widgets .child(new Grid() .scrollable(new VerticalScrollData(), null) + .coverChildrenWidth() + .height(18 * 6) .minElementMargin(0, 0) .mapTo(8, list, (index, value) -> value)); } From f5d2a30b6fb0391448e87bac33cc57590022bb0d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:12:30 -0700 Subject: [PATCH 059/147] grid fixed fix syncing issues --- .../storage/MetaTileEntityWorkbench.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index b1c95398d3a..df3c7c08a43 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -2,6 +2,8 @@ import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.widget.ParentWidget; + import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; @@ -73,6 +75,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.function.Predicate; @@ -299,11 +302,6 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .bindPlayerInventory(); } - public void sendHandlerToClient(PacketBuffer buffer) { - buffer.writeVarInt(this.combinedInventory.getSlots()); - getCraftingRecipeLogic().writeAvailableStacks(buffer); - } - public IWidget createToolInventory(GuiSyncManager syncManager) { var toolSlots = new SlotGroup("tool_slots", 9, true); syncManager.registerSlotGroup(toolSlots); @@ -375,6 +373,10 @@ public IWidget createInventoryPage(GuiSyncManager syncManager) { return slot < this.connectedInventory.getSlots(); }; + if (this.connectedInventory.getSlots() == 0) { + return new ParentWidget<>(); + } + for (int i = 0; i < this.connectedInventory.getSlots(); i++) { // todo maybe show what inventory a slot belongs to? var widget = new ItemSlot() @@ -398,6 +400,15 @@ public IWidget createInventoryPage(GuiSyncManager syncManager) { .mapTo(8, list, (index, value) -> value)); } + public void sendHandlerToClient(PacketBuffer buffer) { + int combined = this.combinedInventory.getSlots(), + connected = this.connectedInventory.getSlots(); + + buffer.writeVarInt(connected); + buffer.writeVarInt(combined - connected); + getCraftingRecipeLogic().writeAvailableStacks(buffer); + } + @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); @@ -406,8 +417,16 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { .updateClientStacks(buf); } else if (dataId == UPDATE_CLIENT_HANDLER) { + int connected = buf.readVarInt(), internal = buf.readVarInt(); + + // set connected inventory + this.connectedInventory = new ItemStackHandler(connected); + + // set combined inventory + this.combinedInventory = new ItemHandlerList(Arrays.asList(this.connectedInventory, new ItemStackHandler(internal))); + getCraftingRecipeLogic() - .updateInventory(new ItemStackHandler(buf.readVarInt())); + .updateInventory(this.combinedInventory); getCraftingRecipeLogic() .updateClientStacks(buf); From e10a62091c61aefb63fec19e5d22ed5651e76cd0 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:44:21 -0700 Subject: [PATCH 060/147] more work on syncing and recipe logic --- .../storage/CraftingRecipeLogic.java | 18 +++++++++++++----- .../storage/MetaTileEntityWorkbench.java | 7 +++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 791ffdee7be..60c92c2eb8c 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -215,7 +215,7 @@ public void performRecipe() { if (!getSyncManager().isClient()) syncToClient(1, this::writeAvailableStacks); - if (!attemptMatchRecipe() || !consumeRecipeItems()) { + if (!attemptMatchRecipe() || !consumeRecipeItems(false)) { return; } @@ -247,7 +247,7 @@ public void performRecipe() { } } - protected boolean consumeRecipeItems() { + protected boolean consumeRecipeItems(boolean simulate) { if (requiredItems.isEmpty()) { return false; } @@ -284,9 +284,9 @@ protected boolean consumeRecipeItems() { if (stack.getItem() instanceof IGTTool gtTool) { damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); } - stack.damageItem(damage, getSyncManager().getPlayer()); + if (!simulate) stack.damageItem(damage, getSyncManager().getPlayer()); } else { - availableHandlers.extractItem(slot, stack.getCount(), false); + availableHandlers.extractItem(slot, stack.getCount(), simulate); } extracted = true; } @@ -365,6 +365,8 @@ public void readOnClient(int id, PacketBuffer buf) { updateClientStacks(buf); } else if (id == 3) { syncToServer(3); + } else if (id == 4) { + getSyncManager().setCursorItem(readStackSafe(buf)); } else if (id == 5) { int slot = buf.readVarInt(); var stack = readStackSafe(buf); @@ -384,7 +386,13 @@ public void readOnServer(int id, PacketBuffer buf) { } else if (id == 1) { syncToClient(1, this::writeAvailableStacks); } else if (id == 3) { - syncToClient(1, this::writeAvailableStacks); +// syncToClient(1, this::writeAvailableStacks); + var curStack = getSyncManager().getCursorItem(); + var outStack = getCachedRecipe().getRecipeOutput(); + if (ItemStack.areItemStacksEqual(curStack, outStack)) { + curStack.grow(outStack.getCount()); + syncToClient(4, buffer -> writeStackSafe(buffer, curStack)); + } } else if (id == 4) { int slot = buf.readVarInt(); syncToClient(5, buffer -> { diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index df3c7c08a43..40dd4137f41 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -533,8 +533,11 @@ public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { @Override public boolean canTakeStack(EntityPlayer playerIn) { - if (recipeLogic.getSyncManager().isClient()) recipeLogic.syncToServer(3); - return recipeLogic.isRecipeValid(); + if (recipeLogic.getSyncManager().isClient()) { + recipeLogic.syncToServer(3); + return false; + } + return recipeLogic.isRecipeValid() && recipeLogic.consumeRecipeItems(true); } @Override From f93e80e3bc6de1b4c95cede3a8ee882428ea10b1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:34:22 -0700 Subject: [PATCH 061/147] more work on syncing and recipe logic part 2 + spotless --- .../storage/CraftingRecipeLogic.java | 23 ++++--- .../storage/MetaTileEntityWorkbench.java | 68 +++++++++---------- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 60c92c2eb8c..fcf897028b6 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -219,6 +219,9 @@ public void performRecipe() { return; } + // updateClientCraft(); + syncToClient(4, buffer -> writeStackSafe(buffer, getSyncManager().getCursorItem())); + var cachedRecipe = cachedRecipeData.getRecipe(); var player = getSyncManager().getPlayer(); ForgeHooks.setCraftingPlayer(player); @@ -362,7 +365,7 @@ public void collectAvailableItems() { @Override public void readOnClient(int id, PacketBuffer buf) { if (id == 1) { - updateClientStacks(buf); + // updateClientStacks(buf); } else if (id == 3) { syncToServer(3); } else if (id == 4) { @@ -386,13 +389,7 @@ public void readOnServer(int id, PacketBuffer buf) { } else if (id == 1) { syncToClient(1, this::writeAvailableStacks); } else if (id == 3) { -// syncToClient(1, this::writeAvailableStacks); - var curStack = getSyncManager().getCursorItem(); - var outStack = getCachedRecipe().getRecipeOutput(); - if (ItemStack.areItemStacksEqual(curStack, outStack)) { - curStack.grow(outStack.getCount()); - syncToClient(4, buffer -> writeStackSafe(buffer, curStack)); - } + // syncToClient(1, this::writeAvailableStacks); } else if (id == 4) { int slot = buf.readVarInt(); syncToClient(5, buffer -> { @@ -434,6 +431,16 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { return stack; } + // public void updateClientCraft() { + // var curStack = getSyncManager().getCursorItem(); + // var outStack = getCachedRecipe().getRecipeOutput(); + // if (curStack.isEmpty()) { + // getSyncManager().setCursorItem(outStack); + // } else if (ItemStack.areItemStacksEqual(curStack, outStack)) { + // curStack.grow(outStack.getCount()); + // } + // } + private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { var tag = stack.serializeNBT(); // GTLog.logger.warn(String.format("Sent: %s", tag)); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 40dd4137f41..b66eb9129f5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,9 +1,5 @@ package gregtech.common.metatileentities.storage; -import com.cleanroommc.modularui.api.drawable.IDrawable; - -import com.cleanroommc.modularui.widget.ParentWidget; - import gregtech.api.capability.GregtechDataCodes; import gregtech.api.capability.impl.ItemHandlerList; import gregtech.api.items.itemhandlers.GTItemStackHandler; @@ -40,6 +36,7 @@ import codechicken.lib.render.pipeline.ColourMultiplier; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.api.widget.Interactable; @@ -55,6 +52,7 @@ import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandlers; +import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; import com.cleanroommc.modularui.widgets.ItemSlot; @@ -244,9 +242,9 @@ public boolean usesMui2() { @Override public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); - if (!guiSyncManager.isClient()) { - writeCustomData(UPDATE_CLIENT_STACKS, getCraftingRecipeLogic()::writeAvailableStacks); - } + // if (!guiSyncManager.isClient()) { + // writeCustomData(UPDATE_CLIENT_STACKS, getCraftingRecipeLogic()::writeAvailableStacks); + // } guiSyncManager.syncValue("recipe_logic", this.recipeLogic); @@ -272,7 +270,6 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .top(22) .margin(7) .widthRel(0.9f) -// .bottom(100) .controller(controller) // workstation page .addPage(new Column() @@ -286,13 +283,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .child(createCraftingGrid()) .child(createCraftingOutput(guiData, guiSyncManager)) // recipe memory - .child(SlotGroupWidget.builder() - .matrix("XXX", - "XXX", - "XXX") - .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) - .build().right(0)) - ) + .child(createRecipeMemoryGrid(guiSyncManager))) // tool inventory .child(createToolInventory(guiSyncManager)) // internal inventory @@ -362,6 +353,15 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag .asWidget().widthRel(1f)); } + public IWidget createRecipeMemoryGrid(GuiSyncManager syncManager) { + return SlotGroupWidget.builder() + .matrix("XXX", + "XXX", + "XXX") + .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) + .build().right(0); + } + public IWidget createInventoryPage(GuiSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 8, true); syncManager.registerSlotGroup(connected); @@ -401,35 +401,26 @@ public IWidget createInventoryPage(GuiSyncManager syncManager) { } public void sendHandlerToClient(PacketBuffer buffer) { - int combined = this.combinedInventory.getSlots(), - connected = this.connectedInventory.getSlots(); - - buffer.writeVarInt(connected); - buffer.writeVarInt(combined - connected); - getCraftingRecipeLogic().writeAvailableStacks(buffer); + buffer.writeVarInt(this.connectedInventory.getSlots()); } @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); - if (dataId == UPDATE_CLIENT_STACKS) { - getCraftingRecipeLogic() - .updateClientStacks(buf); + if (dataId == UPDATE_CLIENT_HANDLER) { + int connected = buf.readVarInt(); - } else if (dataId == UPDATE_CLIENT_HANDLER) { - int connected = buf.readVarInt(), internal = buf.readVarInt(); + // check if sizes have changed, and keep any existing items // set connected inventory this.connectedInventory = new ItemStackHandler(connected); // set combined inventory - this.combinedInventory = new ItemHandlerList(Arrays.asList(this.connectedInventory, new ItemStackHandler(internal))); + this.combinedInventory = new ItemHandlerList( + Arrays.asList(this.connectedInventory, this.internalInventory)); getCraftingRecipeLogic() .updateInventory(this.combinedInventory); - - getCraftingRecipeLogic() - .updateClientStacks(buf); } } @@ -534,10 +525,14 @@ public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { @Override public boolean canTakeStack(EntityPlayer playerIn) { if (recipeLogic.getSyncManager().isClient()) { - recipeLogic.syncToServer(3); + // recipeLogic.syncToServer(3); return false; } - return recipeLogic.isRecipeValid() && recipeLogic.consumeRecipeItems(true); + + if (recipeLogic.isRecipeValid()) + recipeLogic.collectAvailableItems(); + + return recipeLogic.attemptMatchRecipe(); } @Override @@ -549,16 +544,16 @@ public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { @Override public void putStack(@NotNull ItemStack stack) { - super.putStack(recipeLogic.getCachedRecipeData().getRecipeOutput()); + super.putStack(getStack()); } @Override - public ItemStack decrStackSize(int amount) { + public @NotNull ItemStack decrStackSize(int amount) { return getStack(); } public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { - itemStack.onCrafting(getWorld(), player, 1); + itemStack.onCrafting(player.world, player, 1); var inventoryCrafting = recipeLogic.getCraftingMatrix(); @@ -571,10 +566,11 @@ public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { } if (cachedRecipe != null) { ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); - this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, false); + this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, true); // itemsCrafted += resultStack.getCount(); recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); } + // call method from recipe logic to sync to client } } From 7977dbc6f15513b3e79b640b6f1696e08fe11029 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:49:29 -0700 Subject: [PATCH 062/147] simplify client syncing --- .../storage/CraftingRecipeLogic.java | 64 +------------------ .../storage/MetaTileEntityWorkbench.java | 12 ++-- 2 files changed, 10 insertions(+), 66 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index fcf897028b6..e9702d91e1f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -212,8 +212,8 @@ private boolean simulateExtractItem(ItemStack itemStack) { public void performRecipe() { if (!isRecipeValid()) return; - if (!getSyncManager().isClient()) - syncToClient(1, this::writeAvailableStacks); + // if (!getSyncManager().isClient()) + // syncToClient(1, this::writeAvailableStacks); if (!attemptMatchRecipe() || !consumeRecipeItems(false)) { return; @@ -234,12 +234,6 @@ public void performRecipe() { continue; } - // ItemStack current = craftingMatrix.getStackInSlot(i); - // craftingMatrix.setInventorySlotContents(i, itemStack); - // if (!cachedRecipe.matches(craftingMatrix, this.world)) { - // craftingMatrix.setInventorySlotContents(i, current); - // } - int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, true).getCount(); if (remainingAmount > 0) { itemStack.setCount(remainingAmount); @@ -334,23 +328,6 @@ public CachedRecipeData getCachedRecipeData() { return this.cachedRecipeData; } - public void writeAvailableStacks(PacketBuffer buffer) { - this.collectAvailableItems(); - Map written = new Int2ObjectArrayMap<>(); - for (var slots : this.stackLookupMap.entrySet()) { - for (var slot : slots.getValue()) { - var stack = this.availableHandlers.getStackInSlot(slot); - written.put(slot, stack); - } - } - - buffer.writeInt(written.size()); - for (var entry : written.entrySet()) { - buffer.writeInt(entry.getKey()); - writeStackSafe(buffer, entry.getValue()); - } - } - public void collectAvailableItems() { this.stackLookupMap.clear(); for (int i = 0; i < this.availableHandlers.getSlots(); i++) { @@ -364,9 +341,7 @@ public void collectAvailableItems() { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == 1) { - // updateClientStacks(buf); - } else if (id == 3) { + if (id == 3) { syncToServer(3); } else if (id == 4) { getSyncManager().setCursorItem(readStackSafe(buf)); @@ -386,10 +361,6 @@ public void readOnServer(int id, PacketBuffer buf) { this.craftingMatrix.setInventorySlotContents(i, buf.readItemStack()); } catch (IOException ignore) {} } - } else if (id == 1) { - syncToClient(1, this::writeAvailableStacks); - } else if (id == 3) { - // syncToClient(1, this::writeAvailableStacks); } else if (id == 4) { int slot = buf.readVarInt(); syncToClient(5, buffer -> { @@ -399,25 +370,6 @@ public void readOnServer(int id, PacketBuffer buf) { } } - public void updateClientStacks(PacketBuffer buffer) { - this.stackLookupMap.clear(); - int size = buffer.readInt(); - for (int i = 0; i < size; i++) { - int slot = buffer.readInt(); - var serverStack = readStackSafe(buffer); - var clientStack = this.availableHandlers.extractItem(slot, Integer.MAX_VALUE, true); - - if (clientStack.isEmpty() || !ItemStack.areItemStacksEqual(clientStack, serverStack)) { - this.availableHandlers.extractItem(slot, Integer.MAX_VALUE, false); - this.availableHandlers.insertItem(slot, serverStack.copy(), false); - } - - this.stackLookupMap - .computeIfAbsent(serverStack, k -> new IntArrayList()) - .add(slot); - } - } - private static ItemStack readStackSafe(PacketBuffer buffer) { var stack = ItemStack.EMPTY; try { @@ -431,16 +383,6 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { return stack; } - // public void updateClientCraft() { - // var curStack = getSyncManager().getCursorItem(); - // var outStack = getCachedRecipe().getRecipeOutput(); - // if (curStack.isEmpty()) { - // getSyncManager().setCursorItem(outStack); - // } else if (ItemStack.areItemStacksEqual(curStack, outStack)) { - // curStack.grow(outStack.getCount()); - // } - // } - private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { var tag = stack.serializeNBT(); // GTLog.logger.warn(String.format("Sent: %s", tag)); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index b66eb9129f5..38c96ef6d04 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -80,7 +80,6 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { // todo move these to GregtechDataCodes - public static final int UPDATE_CLIENT_STACKS = GregtechDataCodes.assignId(); public static final int UPDATE_CLIENT_HANDLER = GregtechDataCodes.assignId(); private static final IDrawable CHEST = new ItemDrawable(new ItemStack(Blocks.CHEST)) @@ -252,6 +251,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { return GTGuis.createPanel(this, 176, 224) .child(new Row() + .debugName("tab row") .widthRel(1f) .leftRel(0.5f) .margin(3, 0) @@ -273,7 +273,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .controller(controller) // workstation page .addPage(new Column() - .debugName("crafting section") + .debugName("crafting page") .coverChildrenWidth() .child(new Row() .debugName("crafting row") @@ -281,6 +281,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .widthRel(1f) // crafting grid .child(createCraftingGrid()) + // crafting output slot .child(createCraftingOutput(guiData, guiSyncManager)) // recipe memory .child(createRecipeMemoryGrid(guiSyncManager))) @@ -340,12 +341,11 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag return new Column() .size(54) - // crafting output slot .child(new ItemSlot().marginTop(18) // todo figure this shit (recipe output slot) out .slot(new CraftingOutputSlot(new InventoryWrapper( this.recipeLogic.getCraftingResultInventory(), - guiData.getPlayer()), amountCrafted)) + guiData.getPlayer()), amountCrafted, getCraftingRecipeLogic())) .background(GTGuiTextures.SLOT.asIcon().size(22)) .marginBottom(4)) .child(IKey.dynamic(amountCrafted::getStringValue) @@ -516,10 +516,12 @@ public Result onMousePressed(int mouseButton) { private class CraftingOutputSlot extends ModularSlot { IntSyncValue syncValue; + private final CraftingRecipeLogic recipeLogic; - public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue) { + public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue, CraftingRecipeLogic recipeLogic) { super(itemHandler, 0, false); this.syncValue = syncValue; + this.recipeLogic = recipeLogic; } @Override From 708a839efab532e54844889241ccf8ce0dcef0e8 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:08:05 -0700 Subject: [PATCH 063/147] move crafting output slot into own class --- .../storage/MetaTileEntityWorkbench.java | 6 +- .../widget/workbench/CraftingOutputSlot.java | 123 ++++++++++++++++++ 2 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 38c96ef6d04..d3dc550fd62 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -9,6 +9,7 @@ import gregtech.api.mui.GTGuis; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; +import gregtech.client.utils.TooltipHelper; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; @@ -218,7 +219,7 @@ public void onNeighborChanged() { writeCustomData(UPDATE_CLIENT_HANDLER, this::sendHandlerToClient); } - private @NotNull CraftingRecipeLogic getCraftingRecipeLogic() { + public @NotNull CraftingRecipeLogic getCraftingRecipeLogic() { Preconditions.checkState(getWorld() != null, "getRecipeResolver called too early"); if (this.recipeLogic == null) { this.recipeLogic = new CraftingRecipeLogic(getWorld(), getAvailableHandlers(), getCraftingGrid()); @@ -519,7 +520,7 @@ private class CraftingOutputSlot extends ModularSlot { private final CraftingRecipeLogic recipeLogic; public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue, CraftingRecipeLogic recipeLogic) { - super(itemHandler, 0, false); + super(itemHandler, 0, true); this.syncValue = syncValue; this.recipeLogic = recipeLogic; } @@ -527,7 +528,6 @@ public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue, Craf @Override public boolean canTakeStack(EntityPlayer playerIn) { if (recipeLogic.getSyncManager().isClient()) { - // recipeLogic.syncToServer(3); return false; } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java new file mode 100644 index 00000000000..29d8f3308bf --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -0,0 +1,123 @@ +package gregtech.common.mui.widget.workbench; + +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.ItemSlotSH; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import com.google.common.collect.Lists; + +import gregtech.common.metatileentities.storage.CraftingRecipeLogic; + +import gregtech.common.metatileentities.storage.CraftingRecipeMemory; + +import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.items.IItemHandler; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class CraftingOutputSlot extends ItemSlot { + + private CraftingSlotSH syncHandler; + + public CraftingOutputSlot slot(CraftingOutputModularSlot slot) { + this.syncHandler = new CraftingSlotSH(slot); + setSyncHandler(this.syncHandler); + return this; + } + + @SuppressWarnings("UnstableApiUsage") + protected static class CraftingSlotSH extends ItemSlotSH { + + public CraftingSlotSH(CraftingOutputModularSlot slot) { + super(slot); + } + + @Override + public CraftingOutputModularSlot getSlot() { + return (CraftingOutputModularSlot) super.getSlot(); + } + + @Override + public void readOnServer(int id, PacketBuffer buf) throws IOException { + if (id == 2) { + getSlot().recipeLogic.performRecipe(); + getSlot().handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); + } else { + super.readOnServer(id, buf); + } + } + } + + public static class CraftingOutputModularSlot extends ModularSlot { + + IntSyncValue syncValue; + private final CraftingRecipeLogic recipeLogic; + private final CraftingRecipeMemory recipeMemory; + private final IItemHandler craftingGrid; + + public CraftingOutputModularSlot(IItemHandler itemHandler, IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { + super(itemHandler, 0, true); + this.syncValue = syncValue; + this.recipeLogic = workbench.getCraftingRecipeLogic(); + this.recipeMemory = workbench.getRecipeMemory(); + this.craftingGrid = workbench.getCraftingGrid(); + } + + @Override + public boolean canTakeStack(EntityPlayer playerIn) { + if (recipeLogic.getSyncManager().isClient()) { + return false; + } + + if (recipeLogic.isRecipeValid()) + recipeLogic.collectAvailableItems(); + + return recipeLogic.attemptMatchRecipe(); + } + + @Override + public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { + recipeLogic.performRecipe(); + handleItemCraft(stack, thePlayer); + return super.onTake(thePlayer, stack); + } + + @Override + public void putStack(@NotNull ItemStack stack) { + super.putStack(getStack()); + } + + @Override + public @NotNull ItemStack decrStackSize(int amount) { + return getStack(); + } + + public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { + itemStack.onCrafting(player.world, player, 1); + + var inventoryCrafting = recipeLogic.getCraftingMatrix(); + + // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds + FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); + + var cachedRecipe = recipeLogic.getCachedRecipe(); + if (cachedRecipe != null && !cachedRecipe.isDynamic()) { + player.unlockRecipes(Lists.newArrayList(cachedRecipe)); + } + if (cachedRecipe != null) { + ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); + this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, true); + // itemsCrafted += resultStack.getCount(); + recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); + } + // call method from recipe logic to sync to client + } + } +} From 4ba7bb81038e4a90ba34f0ae3575b8f839c4922b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:43:55 -0700 Subject: [PATCH 064/147] we do a little refactoring make crafting output slot phantom --- .../storage/CraftingRecipeLogic.java | 52 ++++++--- .../storage/MetaTileEntityWorkbench.java | 80 ++------------ .../widget/workbench/CraftingOutputSlot.java | 100 +++++++++++------- 3 files changed, 105 insertions(+), 127 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index e9702d91e1f..9ddac0fedd8 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -11,6 +11,7 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.inventory.ItemStackHelper; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; @@ -84,6 +85,7 @@ public InventoryCrafting getCraftingMatrix() { public void updateInventory(IItemHandlerModifiable handler) { this.availableHandlers = handler; + collectAvailableItems(); } public void clearCraftingGrid() { @@ -212,15 +214,30 @@ private boolean simulateExtractItem(ItemStack itemStack) { public void performRecipe() { if (!isRecipeValid()) return; - // if (!getSyncManager().isClient()) - // syncToClient(1, this::writeAvailableStacks); - if (!attemptMatchRecipe() || !consumeRecipeItems(false)) { return; } - // updateClientCraft(); - syncToClient(4, buffer -> writeStackSafe(buffer, getSyncManager().getCursorItem())); + // sync crafted stack to client + syncToClient(4, buffer -> { + ItemStack curStack = getSyncManager().getCursorItem(); + ItemStack outStack = getCachedRecipe().getRecipeOutput(); + ItemStack toSync = outStack.copy(); + if (curStack.getItem() == outStack.getItem() && + curStack.getMetadata() == outStack.getMetadata() && + ItemStack.areItemStackTagsEqual(curStack, outStack)) { + + int combined = curStack.getCount() + outStack.getCount(); + if (combined <= outStack.getMaxStackSize()) { + toSync.setCount(curStack.getCount() + outStack.getCount()); + } else { + toSync.setCount(outStack.getMaxStackSize()); + } + } else if (!curStack.isEmpty()) { + toSync = curStack; + } + writeStackSafe(buffer, toSync); + }); var cachedRecipe = cachedRecipeData.getRecipe(); var player = getSyncManager().getPlayer(); @@ -261,6 +278,10 @@ protected boolean consumeRecipeItems(boolean simulate) { int extractedAmount = 0; for (int slot : slotList) { var extracted = availableHandlers.extractItem(slot, requestedAmount, true); + if (extracted.isEmpty()) { + stackLookupMap.get(stack).remove(slot); + continue; + } gatheredItems.put(extracted, slot); extractedAmount += extracted.getCount(); requestedAmount -= extractedAmount; @@ -273,20 +294,17 @@ protected boolean consumeRecipeItems(boolean simulate) { for (var gathered : gatheredItems.entrySet()) { var stack = gathered.getKey(); int slot = gathered.getValue(); - if (stack.isEmpty()) { - stackLookupMap.get(stack).remove(slot); - } else { - if (stack.getItem().hasContainerItem(stack) && stack.isItemStackDamageable()) { - int damage = 1; - if (stack.getItem() instanceof IGTTool gtTool) { - damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); - } - if (!simulate) stack.damageItem(damage, getSyncManager().getPlayer()); - } else { - availableHandlers.extractItem(slot, stack.getCount(), simulate); + + if (stack.getItem().hasContainerItem(stack) && stack.isItemStackDamageable()) { + int damage = 1; + if (stack.getItem() instanceof IGTTool gtTool) { + damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); } - extracted = true; + if (!simulate) stack.damageItem(damage, getSyncManager().getPlayer()); + } else { + availableHandlers.extractItem(slot, stack.getCount(), simulate); } + extracted = true; } return extracted; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index d3dc550fd62..0c03d35b321 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -13,6 +13,8 @@ import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; +import gregtech.common.mui.widget.workbench.CraftingOutputSlot; + import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; @@ -242,9 +244,7 @@ public boolean usesMui2() { @Override public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); - // if (!guiSyncManager.isClient()) { - // writeCustomData(UPDATE_CLIENT_STACKS, getCraftingRecipeLogic()::writeAvailableStacks); - // } + getCraftingRecipeLogic().collectAvailableItems(); guiSyncManager.syncValue("recipe_logic", this.recipeLogic); @@ -342,11 +342,11 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag return new Column() .size(54) - .child(new ItemSlot().marginTop(18) - // todo figure this shit (recipe output slot) out - .slot(new CraftingOutputSlot(new InventoryWrapper( - this.recipeLogic.getCraftingResultInventory(), - guiData.getPlayer()), amountCrafted, getCraftingRecipeLogic())) + .child(new CraftingOutputSlot() + .slot(new CraftingOutputSlot.CraftingOutputModularSlot( + new InventoryWrapper(getCraftingRecipeLogic().getCraftingResultInventory(), guiData.getPlayer()), + amountCrafted, this)) + .marginTop(18) .background(GTGuiTextures.SLOT.asIcon().size(22)) .marginBottom(4)) .child(IKey.dynamic(amountCrafted::getStringValue) @@ -411,7 +411,7 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { if (dataId == UPDATE_CLIENT_HANDLER) { int connected = buf.readVarInt(); - // check if sizes have changed, and keep any existing items + // resize and keep any existing items // set connected inventory this.connectedInventory = new ItemStackHandler(connected); @@ -514,68 +514,6 @@ public Result onMousePressed(int mouseButton) { } } - private class CraftingOutputSlot extends ModularSlot { - - IntSyncValue syncValue; - private final CraftingRecipeLogic recipeLogic; - - public CraftingOutputSlot(IItemHandler itemHandler, IntSyncValue syncValue, CraftingRecipeLogic recipeLogic) { - super(itemHandler, 0, true); - this.syncValue = syncValue; - this.recipeLogic = recipeLogic; - } - - @Override - public boolean canTakeStack(EntityPlayer playerIn) { - if (recipeLogic.getSyncManager().isClient()) { - return false; - } - - if (recipeLogic.isRecipeValid()) - recipeLogic.collectAvailableItems(); - - return recipeLogic.attemptMatchRecipe(); - } - - @Override - public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { - recipeLogic.performRecipe(); - handleItemCraft(stack, thePlayer); - return super.onTake(thePlayer, stack); - } - - @Override - public void putStack(@NotNull ItemStack stack) { - super.putStack(getStack()); - } - - @Override - public @NotNull ItemStack decrStackSize(int amount) { - return getStack(); - } - - public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { - itemStack.onCrafting(player.world, player, 1); - - var inventoryCrafting = recipeLogic.getCraftingMatrix(); - - // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds - FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); - - var cachedRecipe = recipeLogic.getCachedRecipe(); - if (cachedRecipe != null && !cachedRecipe.isDynamic()) { - player.unlockRecipes(Lists.newArrayList(cachedRecipe)); - } - if (cachedRecipe != null) { - ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); - this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, true); - // itemsCrafted += resultStack.getCount(); - recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); - } - // call method from recipe logic to sync to client - } - } - private class InventoryWrapper implements IItemHandlerModifiable { IInventory inventory; diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 29d8f3308bf..86e9b69b489 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -26,17 +26,32 @@ public class CraftingOutputSlot extends ItemSlot { private CraftingSlotSH syncHandler; - public CraftingOutputSlot slot(CraftingOutputModularSlot slot) { - this.syncHandler = new CraftingSlotSH(slot); - setSyncHandler(this.syncHandler); + @Override + public ItemSlot slot(ModularSlot slot) { + if (slot instanceof CraftingOutputModularSlot craftingSlot) { + this.syncHandler = new CraftingSlotSH(craftingSlot); + if (isValidSyncHandler(this.syncHandler)) + setSyncHandler(this.syncHandler); + } else { + super.slot(slot); + } return this; } @SuppressWarnings("UnstableApiUsage") protected static class CraftingSlotSH extends ItemSlotSH { + private final CraftingRecipeLogic recipeLogic; + private final IntSyncValue syncValue; + private final CraftingRecipeMemory recipeMemory; + private final IItemHandler craftingGrid; + public CraftingSlotSH(CraftingOutputModularSlot slot) { super(slot); + this.recipeLogic = slot.recipeLogic; + this.syncValue = slot.syncValue; + this.recipeMemory = slot.recipeMemory; + this.craftingGrid = slot.craftingGrid; } @Override @@ -47,17 +62,40 @@ public CraftingOutputModularSlot getSlot() { @Override public void readOnServer(int id, PacketBuffer buf) throws IOException { if (id == 2) { - getSlot().recipeLogic.performRecipe(); - getSlot().handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); + if (recipeLogic.isRecipeValid() && getSlot().canTakeStack(getSyncManager().getPlayer())) { + recipeLogic.performRecipe(); + handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); + } } else { super.readOnServer(id, buf); } } + + public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { + itemStack.onCrafting(player.world, player, 1); + + var inventoryCrafting = recipeLogic.getCraftingMatrix(); + + // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds + FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); + + var cachedRecipe = recipeLogic.getCachedRecipe(); + if (cachedRecipe != null && !cachedRecipe.isDynamic()) { + player.unlockRecipes(Lists.newArrayList(cachedRecipe)); + } + if (cachedRecipe != null) { + ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); + this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, true); + // itemsCrafted += resultStack.getCount(); + recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); + } + // call method from recipe logic to sync to client + } } public static class CraftingOutputModularSlot extends ModularSlot { - IntSyncValue syncValue; + private final IntSyncValue syncValue; private final CraftingRecipeLogic recipeLogic; private final CraftingRecipeMemory recipeMemory; private final IItemHandler craftingGrid; @@ -72,22 +110,27 @@ public CraftingOutputModularSlot(IItemHandler itemHandler, IntSyncValue syncValu @Override public boolean canTakeStack(EntityPlayer playerIn) { - if (recipeLogic.getSyncManager().isClient()) { - return false; - } + ItemStack curStack = playerIn.inventory.getItemStack(); + if (curStack.isEmpty()) return true; - if (recipeLogic.isRecipeValid()) - recipeLogic.collectAvailableItems(); + ItemStack outStack = recipeLogic.getCachedRecipe().getRecipeOutput(); + if (curStack.getItem() == outStack.getItem() && + curStack.getMetadata() == outStack.getMetadata() && + ItemStack.areItemStackTagsEqual(curStack, outStack)) { - return recipeLogic.attemptMatchRecipe(); + int combined = curStack.getCount() + outStack.getCount(); + return combined <= outStack.getMaxStackSize(); + } else { + return false; + } } - @Override - public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { - recipeLogic.performRecipe(); - handleItemCraft(stack, thePlayer); - return super.onTake(thePlayer, stack); - } +// @Override +// public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { +// recipeLogic.performRecipe(); +// handleItemCraft(stack, thePlayer); +// return super.onTake(thePlayer, stack); +// } @Override public void putStack(@NotNull ItemStack stack) { @@ -98,26 +141,5 @@ public void putStack(@NotNull ItemStack stack) { public @NotNull ItemStack decrStackSize(int amount) { return getStack(); } - - public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { - itemStack.onCrafting(player.world, player, 1); - - var inventoryCrafting = recipeLogic.getCraftingMatrix(); - - // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds - FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); - - var cachedRecipe = recipeLogic.getCachedRecipe(); - if (cachedRecipe != null && !cachedRecipe.isDynamic()) { - player.unlockRecipes(Lists.newArrayList(cachedRecipe)); - } - if (cachedRecipe != null) { - ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); - this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, true); - // itemsCrafted += resultStack.getCount(); - recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); - } - // call method from recipe logic to sync to client - } } } From bf2bb217c3c4c410945a946b3708d0bedd43103f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:46:07 -0700 Subject: [PATCH 065/147] remove unused class --- .../craftingstation/CraftingSlotWidget.java | 207 ------------------ .../widget/workbench/CraftingOutputSlot.java | 7 - .../jei/JustEnoughItemsModule.java | 3 +- 3 files changed, 1 insertion(+), 216 deletions(-) delete mode 100644 src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java deleted file mode 100644 index e8bf56f0b4a..00000000000 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java +++ /dev/null @@ -1,207 +0,0 @@ -package gregtech.common.gui.widget.craftingstation; - -import gregtech.api.gui.impl.ModularUIContainer; -import gregtech.api.gui.ingredient.IRecipeTransferHandlerWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.util.OverlayedItemHandler; -import gregtech.common.metatileentities.storage.CraftingRecipeLogic; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.InventoryCraftResult; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; - -import com.google.common.base.Preconditions; -import mezz.jei.api.gui.IGuiIngredient; -import mezz.jei.api.gui.IRecipeLayout; -import org.lwjgl.input.Mouse; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -public class CraftingSlotWidget extends SlotWidget implements IRecipeTransferHandlerWidget { - - private final CraftingRecipeLogic recipeResolver; - private boolean canTakeStack = false; - - public CraftingSlotWidget(CraftingRecipeLogic recipeResolver, int slotIndex, int xPosition, int yPosition) { - super(createInventory(recipeResolver), slotIndex, xPosition, yPosition, false, false); - this.recipeResolver = recipeResolver; - } - - private static IInventory createInventory(CraftingRecipeLogic resolver) { - return resolver == null ? new InventoryCraftResult() : resolver.getCraftingResultInventory(); - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - super.handleClientAction(id, buffer); - if (id == 1) { - HashMap ingredients = new HashMap<>(); - int ingredientAmount = buffer.readVarInt(); - try { - for (int i = 0; i < ingredientAmount; i++) { - ingredients.put(buffer.readVarInt(), buffer.readItemStack()); - } - } catch (IOException exception) { - throw new RuntimeException(exception); - } - recipeResolver.fillCraftingGrid(ingredients); - } - // if (id == 2) { - // if (recipeResolver.isRecipeValid()) { - // ClickData clickData = ClickData.readFromBuf(buffer); - // boolean isShiftDown = clickData.isShiftClick; - // boolean isLeftClick = clickData.button == 0; - // boolean isRightClick = clickData.button == 1; - // EntityPlayer player = gui.entityPlayer; - // if (isShiftDown) { - // OverlayedItemHandler playerInventory = new OverlayedItemHandler( - // new PlayerMainInvWrapper(gui.entityPlayer.inventory)); - // ItemStack toMerge = slotReference.getStack(); - // int crafts = this.slotReference.getStack().getCount(); - // if (isLeftClick) { - // if (crafts != 0) { - // // limit shift click to one stack at a time - // int totalCrafts = 0; - // int maxCrafts = toMerge.getMaxStackSize() / crafts; - // for (int i = 0; i < maxCrafts; i++) { - // if (canMergeToInv(playerInventory, toMerge, crafts) && - // recipeResolver.performRecipe(gui.entityPlayer)) { - // this.recipeResolver.refreshOutputSlot(); - // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - // totalCrafts += crafts; - // } - // } - // ItemStack toAdd = this.slotReference.getStack().copy(); - // toAdd.setCount(totalCrafts); - // player.inventory.addItemStackToInventory(toAdd); - // } - // } else if (isRightClick) { - // int totalCrafts = 0; - // while (canMergeToInv(playerInventory, toMerge, crafts) && - // recipeResolver.performRecipe(gui.entityPlayer)) { - // this.recipeResolver.refreshOutputSlot(); - // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - // totalCrafts += crafts; - // } - // ItemStack toAdd = this.slotReference.getStack().copy(); - // toAdd.setCount(totalCrafts); - // player.inventory.addItemStackToInventory(toAdd); - // } - // } else { - // if (isLeftClick) { - // if (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && - // recipeResolver.performRecipe(gui.entityPlayer)) { - // this.recipeResolver.refreshOutputSlot(); - // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - // // send slot changes now, both of consumed items in inventory and result slot - // ItemStack result = this.slotReference.getStack(); - // mergeToHand(result); - // } - // } else if (isRightClick) { - // while (canMerge(player.inventory.getItemStack(), this.slotReference.getStack()) && - // recipeResolver.performRecipe(gui.entityPlayer)) { - // this.recipeResolver.refreshOutputSlot(); - // recipeResolver.handleItemCraft(this.slotReference.getStack(), gui.entityPlayer); - // ItemStack result = this.slotReference.getStack(); - // mergeToHand(result); - // } - // } - // } - // uiAccess.sendHeldItemUpdate(); - // // send slot changes now, both of consumed items in inventory and result slot - // gui.entityPlayer.openContainer.detectAndSendChanges(); - // uiAccess.sendSlotUpdate(this); - // } - // } - } - - private static boolean canMerge(ItemStack stack, ItemStack stack1) { - if (stack.isEmpty()) return true; - if (ItemStack.areItemsEqual(stack, stack1) && ItemStack.areItemStackTagsEqual(stack, stack1)) { - return stack.getCount() + stack1.getCount() <= stack.getMaxStackSize(); - } - return false; - } - - private static boolean canMergeToInv(OverlayedItemHandler inventory, ItemStack stack, int crafts) { - return inventory.insertStackedItemStack(stack, crafts) == 0; - } - - private void mergeToHand(ItemStack toMerge) { - EntityPlayer player = gui.entityPlayer; - ItemStack itemInHand = gui.entityPlayer.inventory.getItemStack(); - if (itemInHand.isEmpty()) { - itemInHand = toMerge; - player.inventory.setItemStack(itemInHand); - } else - if (ItemStack.areItemsEqual(itemInHand, toMerge) && ItemStack.areItemStackTagsEqual(itemInHand, toMerge)) { - // if the hand is not empty, try to merge the result with the hand - if (itemInHand.getCount() + toMerge.getCount() <= itemInHand.getMaxStackSize()) { - // if the result of the merge is smaller than the max stack size, merge - itemInHand.grow(toMerge.getCount()); - player.inventory.setItemStack(itemInHand); - } - } - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - if (recipeResolver == null) { - return; - } - boolean isRecipeValid = recipeResolver.isRecipeValid(); - if (isRecipeValid != canTakeStack) { - this.canTakeStack = isRecipeValid; - writeUpdateInfo(1, buf -> buf.writeBoolean(canTakeStack)); - } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - super.readUpdateInfo(id, buffer); - if (id == 1) { - this.canTakeStack = buffer.readBoolean(); - } - } - - @Override - public boolean canMergeSlot(ItemStack stack) { - return false; - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY) && gui != null) { - ClickData clickData = new ClickData(Mouse.getEventButton(), isShiftDown(), isCtrlDown()); - writeClientAction(2, clickData::writeToBuf); - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public String transferRecipe(ModularUIContainer container, IRecipeLayout recipeLayout, EntityPlayer player, - boolean maxTransfer, boolean doTransfer) { - if (!doTransfer) { - return null; - } - Map> ingredients = new HashMap<>( - recipeLayout.getItemStacks().getGuiIngredients()); - ingredients.values().removeIf(it -> it.getAllIngredients().isEmpty() || !it.isInput()); - writeClientAction(1, buf -> { - buf.writeVarInt(ingredients.size()); - for (Entry> entry : ingredients.entrySet()) { - buf.writeVarInt(entry.getKey()); - ItemStack itemStack = entry.getValue().getDisplayedIngredient(); - Preconditions.checkNotNull(itemStack); - buf.writeItemStack(itemStack); - } - }); - return null; - } -} diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 86e9b69b489..a8438d418bc 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -125,13 +125,6 @@ public boolean canTakeStack(EntityPlayer playerIn) { } } -// @Override -// public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { -// recipeLogic.performRecipe(); -// handleItemCraft(stack, thePlayer); -// return super.onTake(thePlayer, stack); -// } - @Override public void putStack(@NotNull ItemStack stack) { super.putStack(getStack()); diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 812f175f6fa..a08f67e8dff 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -28,7 +28,6 @@ import gregtech.api.worldgen.config.OreDepositDefinition; import gregtech.api.worldgen.config.WorldGenRegistry; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.gui.widget.craftingstation.CraftingSlotWidget; import gregtech.common.items.MetaItems; import gregtech.common.items.ToolItems; import gregtech.common.metatileentities.MetaTileEntities; @@ -155,7 +154,7 @@ public void register(IModRegistry registry) { // register transfer handler for all categories, but not for the crafting station ModularUIGuiHandler modularUIGuiHandler = new ModularUIGuiHandler(jeiHelpers.recipeTransferHandlerHelper()); - modularUIGuiHandler.setValidHandlers(widget -> !(widget instanceof CraftingSlotWidget)); +// modularUIGuiHandler.setValidHandlers(widget -> !(widget instanceof CraftingSlotWidget)); modularUIGuiHandler.blacklistCategory( IntCircuitCategory.UID, GTValues.MODID + ":material_tree", From e29f3158d62dde0b7b0414b64d85472ad76cede5 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 22 Apr 2024 12:59:07 -0700 Subject: [PATCH 066/147] move inventory wrapper class --- .../storage/MetaTileEntityWorkbench.java | 48 +---------------- .../widget/workbench/CraftingOutputSlot.java | 53 ++++++++++++++++++- 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 0c03d35b321..57e25c5eb35 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -344,7 +344,7 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag .size(54) .child(new CraftingOutputSlot() .slot(new CraftingOutputSlot.CraftingOutputModularSlot( - new InventoryWrapper(getCraftingRecipeLogic().getCraftingResultInventory(), guiData.getPlayer()), + getCraftingRecipeLogic().getCraftingResultInventory(), amountCrafted, this)) .marginTop(18) .background(GTGuiTextures.SLOT.asIcon().size(22)) @@ -514,52 +514,6 @@ public Result onMousePressed(int mouseButton) { } } - private class InventoryWrapper implements IItemHandlerModifiable { - - IInventory inventory; - EntityPlayer player; - - private InventoryWrapper(IInventory inventory, EntityPlayer player) { - this.inventory = inventory; - this.player = player; - } - - @Override - public int getSlots() { - return inventory.getSizeInventory(); - } - - @Override - public ItemStack getStackInSlot(int slot) { - return inventory.getStackInSlot(slot).copy(); - } - - @Override - public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { - return stack; - } - - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - return inventory.getStackInSlot(slot); - } - - @Override - public int getSlotLimit(int slot) { - return inventory.getInventoryStackLimit(); - } - - @Override - public void setStackInSlot(int slot, ItemStack stack) { - if (!recipeLogic.isRecipeValid()) { - inventory.setInventorySlotContents(slot, ItemStack.EMPTY); - } - - if (!stack.isEmpty()) - inventory.setInventorySlotContents(slot, stack); - } - } - private static class HandlerListWrapper extends ItemHandlerList { public HandlerListWrapper(List itemHandlerList) { diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index a8438d418bc..9d4ad4f2dc1 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -13,11 +13,14 @@ import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.IItemHandlerModifiable; + import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -100,8 +103,8 @@ public static class CraftingOutputModularSlot extends ModularSlot { private final CraftingRecipeMemory recipeMemory; private final IItemHandler craftingGrid; - public CraftingOutputModularSlot(IItemHandler itemHandler, IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { - super(itemHandler, 0, true); + public CraftingOutputModularSlot(IInventory craftingInventory, IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { + super(new InventoryWrapper(craftingInventory, workbench.getCraftingRecipeLogic()), 0, true); this.syncValue = syncValue; this.recipeLogic = workbench.getCraftingRecipeLogic(); this.recipeMemory = workbench.getRecipeMemory(); @@ -135,4 +138,50 @@ public void putStack(@NotNull ItemStack stack) { return getStack(); } } + + private static class InventoryWrapper implements IItemHandlerModifiable { + + private final IInventory inventory; + private final CraftingRecipeLogic recipeLogic; + + private InventoryWrapper(IInventory inventory, CraftingRecipeLogic recipeLogic) { + this.inventory = inventory; + this.recipeLogic = recipeLogic; + } + + @Override + public int getSlots() { + return inventory.getSizeInventory(); + } + + @Override + public ItemStack getStackInSlot(int slot) { + return inventory.getStackInSlot(slot).copy(); + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + return stack; + } + + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + return inventory.getStackInSlot(slot); + } + + @Override + public int getSlotLimit(int slot) { + return inventory.getInventoryStackLimit(); + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + if (!recipeLogic.isRecipeValid()) { + inventory.setInventorySlotContents(slot, ItemStack.EMPTY); + } + + if (!stack.isEmpty()) + inventory.setInventorySlotContents(slot, stack); + } + } } From eff13d0877b54a96a7d2d6b5f30be9c42b5844bd Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:11:01 -0700 Subject: [PATCH 067/147] collect items before each craft --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 3 +-- .../metatileentities/storage/MetaTileEntityWorkbench.java | 1 - .../common/mui/widget/workbench/CraftingOutputSlot.java | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 9ddac0fedd8..ecfcc942b14 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -85,7 +85,6 @@ public InventoryCrafting getCraftingMatrix() { public void updateInventory(IItemHandlerModifiable handler) { this.availableHandlers = handler; - collectAvailableItems(); } public void clearCraftingGrid() { @@ -279,7 +278,7 @@ protected boolean consumeRecipeItems(boolean simulate) { for (int slot : slotList) { var extracted = availableHandlers.extractItem(slot, requestedAmount, true); if (extracted.isEmpty()) { - stackLookupMap.get(stack).remove(slot); + stackLookupMap.get(stack).remove((Integer) slot); continue; } gatheredItems.put(extracted, slot); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 57e25c5eb35..5ba21fb4b44 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -244,7 +244,6 @@ public boolean usesMui2() { @Override public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); - getCraftingRecipeLogic().collectAvailableItems(); guiSyncManager.syncValue("recipe_logic", this.recipeLogic); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 9d4ad4f2dc1..71fa38d9e1f 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -66,6 +66,7 @@ public CraftingOutputModularSlot getSlot() { public void readOnServer(int id, PacketBuffer buf) throws IOException { if (id == 2) { if (recipeLogic.isRecipeValid() && getSlot().canTakeStack(getSyncManager().getPlayer())) { + recipeLogic.collectAvailableItems(); recipeLogic.performRecipe(); handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); } From ecd7a1375dea9fdbdf04a00bcd2f46d24700418a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:33:05 -0700 Subject: [PATCH 068/147] small fixes --- .../storage/MetaTileEntityWorkbench.java | 21 ++++++++++++------- .../widget/workbench/CraftingOutputSlot.java | 6 +++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 5ba21fb4b44..1c5066cdfa0 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -322,11 +322,12 @@ public IWidget createInternalInventory(GuiSyncManager syncManager) { public IWidget createCraftingGrid() { return SlotGroupWidget.builder() - .matrix("XXX", "XXX", "XXX") + .matrix("XXX", + "XXX", + "XXX") .key('X', i -> new ItemSlot() .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) - .changeListener( - (newItem, onlyAmountChanged, client, init) -> { + .changeListener((newItem, onlyAmountChanged, client, init) -> { if (!init) { this.recipeLogic.updateCurrentRecipe(); } @@ -342,9 +343,7 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag return new Column() .size(54) .child(new CraftingOutputSlot() - .slot(new CraftingOutputSlot.CraftingOutputModularSlot( - getCraftingRecipeLogic().getCraftingResultInventory(), - amountCrafted, this)) + .slot(CraftingOutputSlot.modular(amountCrafted, this)) .marginTop(18) .background(GTGuiTextures.SLOT.asIcon().size(22)) .marginBottom(4)) @@ -374,7 +373,13 @@ public IWidget createInventoryPage(GuiSyncManager syncManager) { }; if (this.connectedInventory.getSlots() == 0) { - return new ParentWidget<>(); + return new Column() + .debugName("inventory page") + .leftRel(0.5f) + .padding(2) + .height(18 * 6) + .width(18 * 8 + 4) + .background(GTGuiTextures.DISPLAY); } for (int i = 0; i < this.connectedInventory.getSlots(); i++) { @@ -417,7 +422,7 @@ public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { // set combined inventory this.combinedInventory = new ItemHandlerList( - Arrays.asList(this.connectedInventory, this.internalInventory)); + Arrays.asList(this.internalInventory, this.connectedInventory)); getCraftingRecipeLogic() .updateInventory(this.combinedInventory); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 71fa38d9e1f..27582851762 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -41,6 +41,10 @@ public ItemSlot slot(ModularSlot slot) { return this; } + public static ModularSlot modular(IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { + return new CraftingOutputModularSlot(workbench.getCraftingRecipeLogic().getCraftingResultInventory(), syncValue, workbench); + } + @SuppressWarnings("UnstableApiUsage") protected static class CraftingSlotSH extends ItemSlotSH { @@ -97,7 +101,7 @@ public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { } } - public static class CraftingOutputModularSlot extends ModularSlot { + protected static class CraftingOutputModularSlot extends ModularSlot { private final IntSyncValue syncValue; private final CraftingRecipeLogic recipeLogic; From 96e8704ceb39635465cc7c41153fe6ae443eee9d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:58:07 -0700 Subject: [PATCH 069/147] small fixes part 2 --- .../api/mui/GregTechGuiTransferHandler.java | 1 - .../storage/CraftingRecipeLogic.java | 38 ++------------- .../storage/MetaTileEntityWorkbench.java | 2 +- .../widget/workbench/CraftingOutputSlot.java | 47 +++++++++++++++++++ 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 802e3acb279..37d5fccba8d 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -50,7 +50,6 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { } recipeLogic.syncToServer(0, this::writeCraftingMatrix); - recipeLogic.syncToServer(1); recipeLogic.updateCurrentRecipe(); return null; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index ecfcc942b14..2f5d42fd79f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -39,7 +39,6 @@ import java.util.List; import java.util.Map; -@SuppressWarnings("OverrideOnly") // stupid annotations conflicting with each other public class CraftingRecipeLogic extends SyncHandler { private final World world; @@ -70,11 +69,6 @@ public CraftingRecipeLogic(World world, IItemHandlerModifiable handlers, IItemHa this.cachedRecipeData = new CachedRecipeData(); } - @Override - public void init(String key, GuiSyncManager syncManager) { - super.init(key, syncManager); - } - public IInventory getCraftingResultInventory() { return craftingResultInventory; } @@ -213,39 +207,17 @@ private boolean simulateExtractItem(ItemStack itemStack) { public void performRecipe() { if (!isRecipeValid()) return; - if (!attemptMatchRecipe() || !consumeRecipeItems(false)) { + if (!attemptMatchRecipe() || !consumeRecipeItems()) { return; } - // sync crafted stack to client - syncToClient(4, buffer -> { - ItemStack curStack = getSyncManager().getCursorItem(); - ItemStack outStack = getCachedRecipe().getRecipeOutput(); - ItemStack toSync = outStack.copy(); - if (curStack.getItem() == outStack.getItem() && - curStack.getMetadata() == outStack.getMetadata() && - ItemStack.areItemStackTagsEqual(curStack, outStack)) { - - int combined = curStack.getCount() + outStack.getCount(); - if (combined <= outStack.getMaxStackSize()) { - toSync.setCount(curStack.getCount() + outStack.getCount()); - } else { - toSync.setCount(outStack.getMaxStackSize()); - } - } else if (!curStack.isEmpty()) { - toSync = curStack; - } - writeStackSafe(buffer, toSync); - }); - var cachedRecipe = cachedRecipeData.getRecipe(); var player = getSyncManager().getPlayer(); ForgeHooks.setCraftingPlayer(player); // todo right here is where tools get damaged (in UI) NonNullList remainingItems = cachedRecipe.getRemainingItems(craftingMatrix); ForgeHooks.setCraftingPlayer(null); - for (int i = 0; i < remainingItems.size(); i++) { - ItemStack itemStack = remainingItems.get(i); + for (ItemStack itemStack : remainingItems) { if (itemStack.isEmpty()) { continue; } @@ -260,7 +232,7 @@ public void performRecipe() { } } - protected boolean consumeRecipeItems(boolean simulate) { + protected boolean consumeRecipeItems() { if (requiredItems.isEmpty()) { return false; } @@ -299,9 +271,9 @@ protected boolean consumeRecipeItems(boolean simulate) { if (stack.getItem() instanceof IGTTool gtTool) { damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); } - if (!simulate) stack.damageItem(damage, getSyncManager().getPlayer()); + stack.damageItem(damage, getSyncManager().getPlayer()); } else { - availableHandlers.extractItem(slot, stack.getCount(), simulate); + availableHandlers.extractItem(slot, stack.getCount(), false); } extracted = true; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 1c5066cdfa0..ec274ae9ee8 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -374,7 +374,7 @@ public IWidget createInventoryPage(GuiSyncManager syncManager) { if (this.connectedInventory.getSlots() == 0) { return new Column() - .debugName("inventory page") + .debugName("inventory page - empty") .leftRel(0.5f) .padding(2) .height(18 * 6) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 27582851762..4796ebf67ba 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,11 +1,13 @@ package gregtech.common.mui.widget.workbench; +import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.ItemSlotSH; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.google.common.collect.Lists; +import gregtech.api.util.GTLog; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; @@ -69,9 +71,14 @@ public CraftingOutputModularSlot getSlot() { @Override public void readOnServer(int id, PacketBuffer buf) throws IOException { if (id == 2) { + var data = MouseData.readPacket(buf); + // todo handle shift transfer + if (data.shift) return; + if (recipeLogic.isRecipeValid() && getSlot().canTakeStack(getSyncManager().getPlayer())) { recipeLogic.collectAvailableItems(); recipeLogic.performRecipe(); + syncToClient(5, this::syncCraftedStack); handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); } } else { @@ -79,6 +86,46 @@ public void readOnServer(int id, PacketBuffer buf) throws IOException { } } + @Override + public void readOnClient(int id, PacketBuffer buf) { + super.readOnClient(id, buf); + if (id == 5) { + getSyncManager().setCursorItem(readStackSafe(buf)); + } else if (id == 6) { + + } + } + + private static ItemStack readStackSafe(PacketBuffer buffer) { + var stack = ItemStack.EMPTY; + try { + stack = buffer.readItemStack(); + } catch (IOException ignore) { + GTLog.logger.warn("A stack was read incorrectly, something is seriously wrong!"); + } + return stack; + } + + private void syncCraftedStack(PacketBuffer buf) { + ItemStack curStack = getSyncManager().getCursorItem(); + ItemStack outStack = recipeLogic.getCachedRecipe().getRecipeOutput(); + ItemStack toSync = outStack.copy(); + if (curStack.getItem() == outStack.getItem() && + curStack.getMetadata() == outStack.getMetadata() && + ItemStack.areItemStackTagsEqual(curStack, outStack)) { + + int combined = curStack.getCount() + outStack.getCount(); + if (combined <= outStack.getMaxStackSize()) { + toSync.setCount(curStack.getCount() + outStack.getCount()); + } else { + toSync.setCount(outStack.getMaxStackSize()); + } + } else if (!curStack.isEmpty()) { + toSync = curStack; + } + buf.writeItemStack(toSync); + } + public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { itemStack.onCrafting(player.world, player, 1); From 4490b41aacd64f55f7af2961b74b3ec46efef7fb Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:14:22 -0700 Subject: [PATCH 070/147] small fixes part 3 --- .../storage/CraftingRecipeLogic.java | 8 +------ .../storage/MetaTileEntityWorkbench.java | 22 ++----------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 2f5d42fd79f..24938e36119 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -330,14 +330,8 @@ public void collectAvailableItems() { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == 3) { - syncToServer(3); - } else if (id == 4) { + if (id == 4) { getSyncManager().setCursorItem(readStackSafe(buf)); - } else if (id == 5) { - int slot = buf.readVarInt(); - var stack = readStackSafe(buf); - this.availableHandlers.setStackInSlot(slot, stack); } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index ec274ae9ee8..d4929116bd7 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -92,26 +92,8 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { .asIcon().size(16); private final ItemStackHandler craftingGrid = new SingleItemStackHandler(9); - private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18) { - - @Override - protected void onContentsChanged(int slot) { - super.onContentsChanged(slot); - var logic = getCraftingRecipeLogic(); - if (logic.isValid() && logic.getSyncManager().isClient()) - logic.syncToServer(4, buffer -> buffer.writeVarInt(slot)); - } - }; - private final ItemStackHandler toolInventory = new ToolItemStackHandler(9) { - - @Override - protected void onContentsChanged(int slot) { - super.onContentsChanged(slot); - var logic = getCraftingRecipeLogic(); - if (logic.isValid() && logic.getSyncManager().isClient()) - logic.syncToServer(4, buffer -> buffer.writeVarInt(slot)); - } - }; + private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18); + private final ItemStackHandler toolInventory = new ToolItemStackHandler(9); private IItemHandlerModifiable combinedInventory; private IItemHandlerModifiable connectedInventory; From c887610342bdccfb12b8547f4bb043db15386a1e Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 24 Apr 2024 13:06:47 -0700 Subject: [PATCH 071/147] initial work on recipe memory spotless --- .../storage/CraftingRecipeLogic.java | 2 - .../storage/CraftingRecipeMemory.java | 10 +- .../storage/MetaTileEntityWorkbench.java | 114 ++------------ .../widget/workbench/CraftingOutputSlot.java | 22 ++- .../widget/workbench/RecipeMemorySlot.java | 148 ++++++++++++++++++ .../jei/JustEnoughItemsModule.java | 2 +- 6 files changed, 176 insertions(+), 122 deletions(-) create mode 100644 src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 24938e36119..eec478eee60 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -11,7 +11,6 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.inventory.ItemStackHelper; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; @@ -24,7 +23,6 @@ import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.items.IItemHandlerModifiable; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandler; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.IntArrayList; diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 74d4ee0ce65..2c5fd16e683 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -15,9 +15,9 @@ public class CraftingRecipeMemory { private final MemorizedRecipe[] memorizedRecipes; private final IItemHandlerModifiable craftingMatrix; - public CraftingRecipeMemory(IItemHandlerModifiable craftingMatrix, int memorySize) { - this.craftingMatrix = craftingMatrix; + public CraftingRecipeMemory(int memorySize, IItemHandlerModifiable craftingMatrix) { this.memorizedRecipes = new MemorizedRecipe[memorySize]; + this.craftingMatrix = craftingMatrix; } public void loadRecipe(int index) { @@ -32,6 +32,11 @@ public MemorizedRecipe getRecipeAtIndex(int index) { return memorizedRecipes[index]; } + @SuppressWarnings("DataFlowIssue") + public ItemStack getRecipeOutputAtIndex(int index) { + return hasRecipe(index) ? getRecipeAtIndex(index).getRecipeResult() : ItemStack.EMPTY; + } + @Nullable private MemorizedRecipe offsetRecipe(int startIndex) { MemorizedRecipe previousRecipe = memorizedRecipes[startIndex]; @@ -77,6 +82,7 @@ private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { public void notifyRecipePerformed(IItemHandler craftingGrid, ItemStack resultStack) { MemorizedRecipe recipe = findOrCreateRecipe(resultStack); if (recipe != null) { + // notify slot and sync to client recipe.updateCraftingMatrix(craftingGrid); recipe.timesUsed++; } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index d4929116bd7..068451c906d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -9,18 +9,14 @@ import gregtech.api.mui.GTGuis; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; -import gregtech.client.utils.TooltipHelper; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; - import gregtech.common.mui.widget.workbench.CraftingOutputSlot; +import gregtech.common.mui.widget.workbench.RecipeMemorySlot; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -42,21 +38,14 @@ import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.PosGuiData; -import com.cleanroommc.modularui.screen.GuiScreenWrapper; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.screen.viewport.GuiContext; -import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.Alignment; -import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandlers; -import com.cleanroommc.modularui.widget.ParentWidget; -import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.PageButton; @@ -65,10 +54,8 @@ import com.cleanroommc.modularui.widgets.layout.Column; import com.cleanroommc.modularui.widgets.layout.Grid; import com.cleanroommc.modularui.widgets.layout.Row; -import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; @@ -98,7 +85,7 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { private IItemHandlerModifiable combinedInventory; private IItemHandlerModifiable connectedInventory; - private final CraftingRecipeMemory recipeMemory = new CraftingRecipeMemory(this.craftingGrid, 9); + private final CraftingRecipeMemory recipeMemory = new CraftingRecipeMemory(9, this.craftingGrid); private CraftingRecipeLogic recipeLogic = null; private int itemsCrafted = 0; @@ -190,10 +177,8 @@ public IItemHandlerModifiable getAvailableHandlers() { @Override public void update() { super.update(); - if (!getWorld().isRemote) { - if (recipeLogic != null) { - getCraftingRecipeLogic().update(); - } + if (!getWorld().isRemote && recipeLogic != null) { + getCraftingRecipeLogic().update(); } } @@ -310,10 +295,10 @@ public IWidget createCraftingGrid() { .key('X', i -> new ItemSlot() .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) .changeListener((newItem, onlyAmountChanged, client, init) -> { - if (!init) { - this.recipeLogic.updateCurrentRecipe(); - } - }))) + if (!init) { + this.recipeLogic.updateCurrentRecipe(); + } + }))) .build(); } @@ -339,7 +324,7 @@ public IWidget createRecipeMemoryGrid(GuiSyncManager syncManager) { .matrix("XXX", "XXX", "XXX") - .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) + .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i, syncManager)) .build().right(0); } @@ -419,87 +404,6 @@ public void setItemsCrafted(int itemsCrafted) { this.itemsCrafted = itemsCrafted; } - private static class RecipeMemorySlot extends Widget implements Interactable { - - private final CraftingRecipeMemory memory; - private final int index; - - public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { - this.memory = memory; - this.index = index; - } - - @Override - public void onInit() { - size(ItemSlot.SIZE); - background(GTGuiTextures.SLOT); - } - - @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { - drawStack(); - } - - public void drawStack() { - GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); - var recipe = memory.getRecipeAtIndex(index); - if (recipe == null) return; - ItemStack itemstack = recipe.getRecipeResult(); - - guiScreen.setZ(100f); - guiScreen.getItemRenderer().zLevel = 100.0F; - - // GuiDraw.drawRect(1, 1, 16, 16, -2130706433); - - if (!itemstack.isEmpty()) { - GlStateManager.enableDepth(); - // render the item itself - guiScreen.getItemRenderer().renderItemAndEffectIntoGUI(guiScreen.mc.player, itemstack, 1, 1); - - // render the amount overlay - // String amountText = NumberFormat.formatWithMaxDigits(1); - // textRenderer.setShadow(true); - // textRenderer.setColor(Color.WHITE.main); - // textRenderer.setAlignment(Alignment.BottomRight, getArea().width - 1, getArea().height - 1); - // textRenderer.setPos(1, 1); - // GlStateManager.disableLighting(); - // GlStateManager.disableDepth(); - // GlStateManager.disableBlend(); - // textRenderer.draw(amountText); - // GlStateManager.enableLighting(); - // GlStateManager.enableDepth(); - // GlStateManager.enableBlend(); - - int cachedCount = itemstack.getCount(); - itemstack.setCount(1); // required to not render the amount overlay - // render other overlays like durability bar - guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, - null); - itemstack.setCount(cachedCount); - GlStateManager.disableDepth(); - } - - guiScreen.getItemRenderer().zLevel = 0.0F; - guiScreen.setZ(0f); - } - - @NotNull - @Override - public Result onMousePressed(int mouseButton) { - var data = MouseData.create(mouseButton); - if (data.shift && data.mouseButton == 0 && memory.hasRecipe(index)) { - var recipe = memory.getRecipeAtIndex(index); - recipe.setRecipeLocked(!recipe.isRecipeLocked()); - } else if (data.mouseButton == 0) { - memory.loadRecipe(index); - } else if (data.mouseButton == 1) { - if (memory.hasRecipe(index) && !memory.getRecipeAtIndex(index).isRecipeLocked()) - memory.removeRecipe(index); - } - return Result.ACCEPT; - } - } - private static class HandlerListWrapper extends ItemHandlerList { public HandlerListWrapper(List itemHandlerList) { diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 4796ebf67ba..49d005a089b 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,17 +1,8 @@ package gregtech.common.mui.widget.workbench; -import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.value.sync.IntSyncValue; -import com.cleanroommc.modularui.value.sync.ItemSlotSH; -import com.cleanroommc.modularui.widgets.ItemSlot; -import com.cleanroommc.modularui.widgets.slot.ModularSlot; -import com.google.common.collect.Lists; - import gregtech.api.util.GTLog; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; - import gregtech.common.metatileentities.storage.CraftingRecipeMemory; - import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; import net.minecraft.entity.player.EntityPlayer; @@ -20,9 +11,14 @@ import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.items.IItemHandler; - import net.minecraftforge.items.IItemHandlerModifiable; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.ItemSlotSH; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -44,7 +40,8 @@ public ItemSlot slot(ModularSlot slot) { } public static ModularSlot modular(IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { - return new CraftingOutputModularSlot(workbench.getCraftingRecipeLogic().getCraftingResultInventory(), syncValue, workbench); + return new CraftingOutputModularSlot(workbench.getCraftingRecipeLogic().getCraftingResultInventory(), syncValue, + workbench); } @SuppressWarnings("UnstableApiUsage") @@ -155,7 +152,8 @@ protected static class CraftingOutputModularSlot extends ModularSlot { private final CraftingRecipeMemory recipeMemory; private final IItemHandler craftingGrid; - public CraftingOutputModularSlot(IInventory craftingInventory, IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { + public CraftingOutputModularSlot(IInventory craftingInventory, IntSyncValue syncValue, + MetaTileEntityWorkbench workbench) { super(new InventoryWrapper(craftingInventory, workbench.getCraftingRecipeLogic()), 0, true); this.syncValue = syncValue; this.recipeLogic = workbench.getCraftingRecipeLogic(); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java new file mode 100644 index 00000000000..58e23894bfa --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -0,0 +1,148 @@ +package gregtech.common.mui.widget.workbench; + +import gregtech.api.mui.GTGuiTextures; +import gregtech.common.metatileentities.storage.CraftingRecipeMemory; + +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; + +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ItemSlot; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +@SuppressWarnings("DataFlowIssue") +public class RecipeMemorySlot extends Widget implements Interactable { + + private final CraftingRecipeMemory memory; + private final int index; + private final RecipeSyncHandler syncHandler; + + public RecipeMemorySlot(CraftingRecipeMemory memory, int index, GuiSyncManager syncManager) { + this.memory = memory; + this.index = index; + this.syncHandler = new RecipeSyncHandler(this.memory, this.index); + // setSyncHandler(this.syncHandler); + syncManager.syncValue("recipe_memory", this.index, this.syncHandler); + } + + @Override + public void onInit() { + size(ItemSlot.SIZE); + background(GTGuiTextures.SLOT); + } + + @Override + public void afterInit() { + this.syncHandler.syncToServer(1); + } + + @Override + public void draw(GuiContext context, WidgetTheme widgetTheme) { + drawStack(); + } + + public void drawStack() { + GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); + ItemStack itemstack = this.syncHandler.drawableStack; + if (itemstack.isEmpty()) return; + + guiScreen.setZ(100f); + guiScreen.getItemRenderer().zLevel = 100.0F; + + // GuiDraw.drawRect(1, 1, 16, 16, -2130706433); + + GlStateManager.enableDepth(); + // render the item itself + guiScreen.getItemRenderer().renderItemAndEffectIntoGUI(guiScreen.mc.player, itemstack, 1, 1); + + // render the amount overlay + // String amountText = NumberFormat.formatWithMaxDigits(1); + // textRenderer.setShadow(true); + // textRenderer.setColor(Color.WHITE.main); + // textRenderer.setAlignment(Alignment.BottomRight, getArea().width - 1, getArea().height - 1); + // textRenderer.setPos(1, 1); + // GlStateManager.disableLighting(); + // GlStateManager.disableDepth(); + // GlStateManager.disableBlend(); + // textRenderer.draw(amountText); + // GlStateManager.enableLighting(); + // GlStateManager.enableDepth(); + // GlStateManager.enableBlend(); + + int cachedCount = itemstack.getCount(); + itemstack.setCount(1); // required to not render the amount overlay + // render other overlays like durability bar + guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, + null); + itemstack.setCount(cachedCount); + GlStateManager.disableDepth(); + + guiScreen.getItemRenderer().zLevel = 0.0F; + guiScreen.setZ(0f); + } + + @NotNull + @Override + public Result onMousePressed(int mouseButton) { + var data = MouseData.create(mouseButton); + this.syncHandler.syncToServer(2, data::writeToPacket); + return Result.ACCEPT; + } + + private static class RecipeSyncHandler extends SyncHandler { + + public ItemStack drawableStack; + private final CraftingRecipeMemory memory; + private final int index; + + public RecipeSyncHandler(CraftingRecipeMemory memory, int index) { + this.memory = memory; + this.index = index; + this.drawableStack = this.memory.getRecipeOutputAtIndex(this.index); + } + + @Override + public void readOnClient(int id, PacketBuffer buf) { + if (id == 1) { + this.drawableStack = readStackSafe(buf); + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) { + if (id == 1) { + this.syncToClient(1, buffer -> buffer.writeItemStack(this.drawableStack)); + } else if (id == 2) { + // read mouse data + var data = MouseData.readPacket(buf); + if (data.shift && data.mouseButton == 0 && memory.hasRecipe(index)) { + var recipe = memory.getRecipeAtIndex(index); + recipe.setRecipeLocked(!recipe.isRecipeLocked()); + } else if (data.mouseButton == 0) { + memory.loadRecipe(index); + } else if (data.mouseButton == 1) { + if (memory.hasRecipe(index) && !memory.getRecipeAtIndex(index).isRecipeLocked()) + memory.removeRecipe(index); + } + } + } + + private ItemStack readStackSafe(PacketBuffer buffer) { + ItemStack ret = ItemStack.EMPTY; + try { + ret = buffer.readItemStack(); + } catch (IOException ignored) {} + return ret; + } + } +} diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index a08f67e8dff..d7c1be8b2de 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -154,7 +154,7 @@ public void register(IModRegistry registry) { // register transfer handler for all categories, but not for the crafting station ModularUIGuiHandler modularUIGuiHandler = new ModularUIGuiHandler(jeiHelpers.recipeTransferHandlerHelper()); -// modularUIGuiHandler.setValidHandlers(widget -> !(widget instanceof CraftingSlotWidget)); + // modularUIGuiHandler.setValidHandlers(widget -> !(widget instanceof CraftingSlotWidget)); modularUIGuiHandler.blacklistCategory( IntCircuitCategory.UID, GTValues.MODID + ":material_tree", From 819729c08dad84bccb92d538400c35a25e892746 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:04:41 -0700 Subject: [PATCH 072/147] make memory a sync handler remove recipeSH and fix syncing --- .../storage/CraftingRecipeMemory.java | 64 ++++++++++++++++- .../storage/MetaTileEntityWorkbench.java | 3 +- .../widget/workbench/RecipeMemorySlot.java | 68 +++---------------- 3 files changed, 73 insertions(+), 62 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 2c5fd16e683..6113c38cced 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -3,14 +3,22 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.PacketBuffer; import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class CraftingRecipeMemory { +import java.io.IOException; +import java.util.Map; + +public class CraftingRecipeMemory extends SyncHandler { private final MemorizedRecipe[] memorizedRecipes; private final IItemHandlerModifiable craftingMatrix; @@ -33,7 +41,7 @@ public MemorizedRecipe getRecipeAtIndex(int index) { } @SuppressWarnings("DataFlowIssue") - public ItemStack getRecipeOutputAtIndex(int index) { + public @NotNull ItemStack getRecipeOutputAtIndex(int index) { return hasRecipe(index) ? getRecipeAtIndex(index).getRecipeResult() : ItemStack.EMPTY; } @@ -130,6 +138,58 @@ public final boolean hasRecipe(int index) { return memorizedRecipes[index] != null; } + @Override + public void readOnClient(int id, PacketBuffer buf) { + if (id == 1) { + int size = buf.readByte(); + for (int i = 0; i < size; i++) { + int index = buf.readByte(); + if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(); + memorizedRecipes[index].recipeResult = readStackSafe(buf); + } + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) { + if (id == 1) { + syncToClient(1, buffer -> { + Map written = new Int2ObjectOpenHashMap<>(); + for (int i = 0; i < memorizedRecipes.length; i++) { + var stack = getRecipeOutputAtIndex(i); + if (stack.isEmpty()) continue; + written.put(i, stack); + } + buffer.writeByte(written.size()); + for (var entry : written.entrySet()) { + buffer.writeByte(entry.getKey()); + buffer.writeItemStack(entry.getValue()); + } + }); + } else if (id == 2) { + // read mouse data + int index = buf.readByte(); + var data = MouseData.readPacket(buf); + if (data.shift && data.mouseButton == 0 && hasRecipe(index)) { + var recipe = getRecipeAtIndex(index); + recipe.setRecipeLocked(!recipe.isRecipeLocked()); + } else if (data.mouseButton == 0) { + loadRecipe(index); + } else if (data.mouseButton == 1) { + if (hasRecipe(index) && !getRecipeAtIndex(index).isRecipeLocked()) + removeRecipe(index); + } + } + } + + private ItemStack readStackSafe(PacketBuffer buffer) { + ItemStack ret = ItemStack.EMPTY; + try { + ret = buffer.readItemStack(); + } catch (IOException ignored) {} + return ret; + } + public static class MemorizedRecipe { private final ItemStackHandler craftingMatrix = new ItemStackHandler(9); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 068451c906d..b47763553ff 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -213,6 +213,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); guiSyncManager.syncValue("recipe_logic", this.recipeLogic); + guiSyncManager.syncValue("recipe_memory", this.recipeMemory); var controller = new PagedWidget.Controller(); @@ -324,7 +325,7 @@ public IWidget createRecipeMemoryGrid(GuiSyncManager syncManager) { .matrix("XXX", "XXX", "XXX") - .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i, syncManager)) + .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) .build().right(0); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 58e23894bfa..4f280746d6c 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -5,34 +5,28 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.screen.GuiScreenWrapper; import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; -import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.ItemSlot; import org.jetbrains.annotations.NotNull; -import java.io.IOException; - @SuppressWarnings("DataFlowIssue") public class RecipeMemorySlot extends Widget implements Interactable { private final CraftingRecipeMemory memory; private final int index; - private final RecipeSyncHandler syncHandler; - public RecipeMemorySlot(CraftingRecipeMemory memory, int index, GuiSyncManager syncManager) { + public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.memory = memory; this.index = index; - this.syncHandler = new RecipeSyncHandler(this.memory, this.index); + // this.syncHandler = new RecipeSyncHandler(this.memory, this.index); // setSyncHandler(this.syncHandler); - syncManager.syncValue("recipe_memory", this.index, this.syncHandler); + // syncManager.syncValue("recipe_memory", this.index, this.syncHandler); } @Override @@ -43,7 +37,7 @@ public void onInit() { @Override public void afterInit() { - this.syncHandler.syncToServer(1); + this.memory.syncToServer(1); } @Override @@ -53,7 +47,7 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { public void drawStack() { GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); - ItemStack itemstack = this.syncHandler.drawableStack; + ItemStack itemstack = this.memory.getRecipeOutputAtIndex(this.index); if (itemstack.isEmpty()) return; guiScreen.setZ(100f); @@ -95,54 +89,10 @@ public void drawStack() { @Override public Result onMousePressed(int mouseButton) { var data = MouseData.create(mouseButton); - this.syncHandler.syncToServer(2, data::writeToPacket); + this.memory.syncToServer(2, buffer -> { + buffer.writeByte(this.index); + data.writeToPacket(buffer); + }); return Result.ACCEPT; } - - private static class RecipeSyncHandler extends SyncHandler { - - public ItemStack drawableStack; - private final CraftingRecipeMemory memory; - private final int index; - - public RecipeSyncHandler(CraftingRecipeMemory memory, int index) { - this.memory = memory; - this.index = index; - this.drawableStack = this.memory.getRecipeOutputAtIndex(this.index); - } - - @Override - public void readOnClient(int id, PacketBuffer buf) { - if (id == 1) { - this.drawableStack = readStackSafe(buf); - } - } - - @Override - public void readOnServer(int id, PacketBuffer buf) { - if (id == 1) { - this.syncToClient(1, buffer -> buffer.writeItemStack(this.drawableStack)); - } else if (id == 2) { - // read mouse data - var data = MouseData.readPacket(buf); - if (data.shift && data.mouseButton == 0 && memory.hasRecipe(index)) { - var recipe = memory.getRecipeAtIndex(index); - recipe.setRecipeLocked(!recipe.isRecipeLocked()); - } else if (data.mouseButton == 0) { - memory.loadRecipe(index); - } else if (data.mouseButton == 1) { - if (memory.hasRecipe(index) && !memory.getRecipeAtIndex(index).isRecipeLocked()) - memory.removeRecipe(index); - } - } - } - - private ItemStack readStackSafe(PacketBuffer buffer) { - ItemStack ret = ItemStack.EMPTY; - try { - ret = buffer.readItemStack(); - } catch (IOException ignored) {} - return ret; - } - } } From 11e8abccd799ab089fe952485f3ea65e6d6240f0 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 24 Apr 2024 19:09:20 -0700 Subject: [PATCH 073/147] more syncing fixes --- .../storage/CraftingRecipeMemory.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 6113c38cced..ec4bef561ab 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -93,6 +93,7 @@ public void notifyRecipePerformed(IItemHandler craftingGrid, ItemStack resultSta // notify slot and sync to client recipe.updateCraftingMatrix(craftingGrid); recipe.timesUsed++; + syncToClient(1, this::writeRecipes); } } @@ -131,6 +132,7 @@ private static void copyInventoryItems(IItemHandler src, IItemHandlerModifiable public final void removeRecipe(int index) { if (hasRecipe(index)) { memorizedRecipes[index] = null; + syncToClient(2, buffer -> buffer.writeByte(index)); } } @@ -147,25 +149,29 @@ public void readOnClient(int id, PacketBuffer buf) { if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(); memorizedRecipes[index].recipeResult = readStackSafe(buf); } + } else if (id == 2) { + removeRecipe(buf.readByte()); + } + } + + public void writeRecipes(PacketBuffer buffer) { + Map written = new Int2ObjectOpenHashMap<>(); + for (int i = 0; i < memorizedRecipes.length; i++) { + var stack = getRecipeOutputAtIndex(i); + if (stack.isEmpty()) continue; + written.put(i, stack); + } + buffer.writeByte(written.size()); + for (var entry : written.entrySet()) { + buffer.writeByte(entry.getKey()); + buffer.writeItemStack(entry.getValue()); } } @Override public void readOnServer(int id, PacketBuffer buf) { if (id == 1) { - syncToClient(1, buffer -> { - Map written = new Int2ObjectOpenHashMap<>(); - for (int i = 0; i < memorizedRecipes.length; i++) { - var stack = getRecipeOutputAtIndex(i); - if (stack.isEmpty()) continue; - written.put(i, stack); - } - buffer.writeByte(written.size()); - for (var entry : written.entrySet()) { - buffer.writeByte(entry.getKey()); - buffer.writeItemStack(entry.getValue()); - } - }); + syncToClient(1, this::writeRecipes); } else if (id == 2) { // read mouse data int index = buf.readByte(); From 195c39af7111d2e3e18f3e688dc15ab7847972a7 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 25 Apr 2024 13:27:39 -0700 Subject: [PATCH 074/147] just crafting station things --- .../storage/CraftingRecipeLogic.java | 7 +-- .../storage/CraftingRecipeMemory.java | 43 +++++++++++++++---- .../storage/MetaTileEntityWorkbench.java | 3 ++ .../widget/workbench/CraftingOutputSlot.java | 9 ++-- .../widget/workbench/RecipeMemorySlot.java | 8 ---- 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index eec478eee60..82a38d32d61 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -202,11 +202,11 @@ private boolean simulateExtractItem(ItemStack itemStack) { return false; } - public void performRecipe() { - if (!isRecipeValid()) return; + public boolean performRecipe() { + if (!isRecipeValid()) return false; if (!attemptMatchRecipe() || !consumeRecipeItems()) { - return; + return false; } var cachedRecipe = cachedRecipeData.getRecipe(); @@ -228,6 +228,7 @@ public void performRecipe() { } } } + return true; } protected boolean consumeRecipeItems() { diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index ec4bef561ab..5b5cf6887dc 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -71,17 +71,22 @@ private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { for (int i = 0; i < memorizedRecipes.length; i++) { MemorizedRecipe memorizedRecipe; if (memorizedRecipes[i] == null) { - memorizedRecipe = new MemorizedRecipe(); + memorizedRecipe = new MemorizedRecipe(i); } else if (memorizedRecipes[i].recipeLocked) { continue; } else { memorizedRecipe = offsetRecipe(i); if (memorizedRecipe == null) { - memorizedRecipe = new MemorizedRecipe(); + memorizedRecipe = new MemorizedRecipe(i); } } memorizedRecipe.initialize(resultItemStack); memorizedRecipes[i] = memorizedRecipe; + var sync = memorizedRecipes[i]; + syncToClient(3, buffer -> { + buffer.writeByte(sync.index); + buffer.writeItemStack(sync.recipeResult); + }); return memorizedRecipe; } return null; @@ -93,7 +98,6 @@ public void notifyRecipePerformed(IItemHandler craftingGrid, ItemStack resultSta // notify slot and sync to client recipe.updateCraftingMatrix(craftingGrid); recipe.timesUsed++; - syncToClient(1, this::writeRecipes); } } @@ -117,7 +121,7 @@ public void deserializeNBT(NBTTagCompound tagCompound) { for (int i = 0; i < resultList.tagCount(); i++) { NBTTagCompound entryComponent = resultList.getCompoundTagAt(i); int slotIndex = entryComponent.getInteger("Slot"); - MemorizedRecipe recipe = MemorizedRecipe.deserializeNBT(entryComponent.getCompoundTag("Recipe")); + MemorizedRecipe recipe = MemorizedRecipe.deserializeNBT(entryComponent.getCompoundTag("Recipe"), slotIndex); this.memorizedRecipes[slotIndex] = recipe; } } @@ -140,17 +144,36 @@ public final boolean hasRecipe(int index) { return memorizedRecipes[index] != null; } + public void writeInitialSyncData(@NotNull PacketBuffer buf) { + this.writeRecipes(buf); + } + + public void receiveInitialSyncData(@NotNull PacketBuffer buf) { + int size = buf.readByte(); + for (int i = 0; i < size; i++) { + int index = buf.readByte(); + if (!hasRecipe(index)) + memorizedRecipes[index] = new MemorizedRecipe(index); + + memorizedRecipes[index].recipeResult = readStackSafe(buf); + } + } + @Override public void readOnClient(int id, PacketBuffer buf) { if (id == 1) { int size = buf.readByte(); for (int i = 0; i < size; i++) { int index = buf.readByte(); - if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(); + if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(index); memorizedRecipes[index].recipeResult = readStackSafe(buf); } } else if (id == 2) { removeRecipe(buf.readByte()); + } else if (id == 3) { + int index = buf.readByte(); + if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(index); + memorizedRecipes[index].recipeResult = readStackSafe(buf); } } @@ -169,6 +192,7 @@ public void writeRecipes(PacketBuffer buffer) { } @Override + @SuppressWarnings("DataFlowIssue") public void readOnServer(int id, PacketBuffer buf) { if (id == 1) { syncToClient(1, this::writeRecipes); @@ -202,8 +226,11 @@ public static class MemorizedRecipe { private ItemStack recipeResult; private boolean recipeLocked = false; private int timesUsed = 0; + public final int index; - private MemorizedRecipe() {} + private MemorizedRecipe(int index) { + this.index = index; + } private NBTTagCompound serializeNBT() { NBTTagCompound result = new NBTTagCompound(); @@ -214,8 +241,8 @@ private NBTTagCompound serializeNBT() { return result; } - private static MemorizedRecipe deserializeNBT(NBTTagCompound tagCompound) { - MemorizedRecipe recipe = new MemorizedRecipe(); + private static MemorizedRecipe deserializeNBT(NBTTagCompound tagCompound, int index) { + MemorizedRecipe recipe = new MemorizedRecipe(index); recipe.recipeResult = new ItemStack(tagCompound.getCompoundTag("Result")); recipe.craftingMatrix.deserializeNBT(tagCompound.getCompoundTag("Matrix")); recipe.recipeLocked = tagCompound.getBoolean("Locked"); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index b47763553ff..80f192a74f1 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -71,6 +71,7 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { // todo move these to GregtechDataCodes public static final int UPDATE_CLIENT_HANDLER = GregtechDataCodes.assignId(); + public static final int SYNC_MEMORY = GregtechDataCodes.assignId(); private static final IDrawable CHEST = new ItemDrawable(new ItemStack(Blocks.CHEST)) .asIcon().size(16); @@ -123,6 +124,7 @@ public void writeInitialSyncData(@NotNull PacketBuffer buf) { for (int i = 0; i < craftingGrid.getSlots(); i++) { buf.writeItemStack(craftingGrid.getStackInSlot(i)); } + this.recipeMemory.writeInitialSyncData(buf); } @Override @@ -134,6 +136,7 @@ public void receiveInitialSyncData(@NotNull PacketBuffer buf) { craftingGrid.setStackInSlot(i, buf.readItemStack()); } } catch (IOException ignored) {} + this.recipeMemory.receiveInitialSyncData(buf); } @Override diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 49d005a089b..db5c0a07469 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -74,9 +74,10 @@ public void readOnServer(int id, PacketBuffer buf) throws IOException { if (recipeLogic.isRecipeValid() && getSlot().canTakeStack(getSyncManager().getPlayer())) { recipeLogic.collectAvailableItems(); - recipeLogic.performRecipe(); - syncToClient(5, this::syncCraftedStack); - handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); + if (recipeLogic.performRecipe()) { + handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); + syncToClient(5, this::syncCraftedStack); + } } } else { super.readOnServer(id, buf); @@ -105,7 +106,7 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { private void syncCraftedStack(PacketBuffer buf) { ItemStack curStack = getSyncManager().getCursorItem(); - ItemStack outStack = recipeLogic.getCachedRecipe().getRecipeOutput(); + ItemStack outStack = getSlot().getStack(); ItemStack toSync = outStack.copy(); if (curStack.getItem() == outStack.getItem() && curStack.getMetadata() == outStack.getMetadata() && diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 4f280746d6c..619ab0e7093 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -24,9 +24,6 @@ public class RecipeMemorySlot extends Widget implements Intera public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.memory = memory; this.index = index; - // this.syncHandler = new RecipeSyncHandler(this.memory, this.index); - // setSyncHandler(this.syncHandler); - // syncManager.syncValue("recipe_memory", this.index, this.syncHandler); } @Override @@ -35,11 +32,6 @@ public void onInit() { background(GTGuiTextures.SLOT); } - @Override - public void afterInit() { - this.memory.syncToServer(1); - } - @Override public void draw(GuiContext context, WidgetTheme widgetTheme) { drawStack(); From 03184d48b8c87b9181fc1e26b6908e81bdf106a1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 2 May 2024 20:23:18 -0700 Subject: [PATCH 075/147] improve crafting logic --- .../storage/CraftingRecipeLogic.java | 163 +++++++++--------- 1 file changed, 86 insertions(+), 77 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 82a38d32d61..6db4c9d55d1 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -8,6 +8,10 @@ import gregtech.api.util.ItemStackHashStrategy; import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; + import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; @@ -33,6 +37,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -48,7 +53,7 @@ public class CraftingRecipeLogic extends SyncHandler { /** * List of items needed to complete the crafting recipe, - * filled by {@link CraftingRecipeLogic#getIngredientEquivalent(int)} + * filled by {@link CraftingRecipeLogic#getIngredientEquivalent(ItemStack, IntList)} )} **/ private final Map requiredItems = new Object2IntOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); @@ -96,27 +101,36 @@ public void fillCraftingGrid(Map ingredients) { */ public boolean attemptMatchRecipe() { requiredItems.clear(); - short itemsFound = 0; + for (var stack : compressMatrixToList(this.craftingMatrix).entrySet()) { + if (!getIngredientEquivalent(stack.getKey(), stack.getValue())) + return false; + } + return true; + } + + private Map compressMatrixToList(InventoryCrafting craftingMatrix) { + Map map = new Object2ObjectOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { - if (getIngredientEquivalent(i)) - itemsFound += (short) (1 << i); + var stack = craftingMatrix.getStackInSlot(i).copy(); + if (stack.isEmpty()) continue; + IntList slots = map.computeIfAbsent(stack, s -> new IntArrayList()); + slots.add(i); } - return itemsFound == ALL_INGREDIENTS_PRESENT; + return map; } /** * Searches all available inventories for an ingredient equivalent for a stack in the crafting matrix * - * @param slot index of the crafting matrix + * @param currentStack stack to find a substitute for * @return true if a valid substitute exists for the stack in the slot */ - public boolean getIngredientEquivalent(int slot) { - ItemStack currentStack = craftingMatrix.getStackInSlot(slot).copy(); + public boolean getIngredientEquivalent(ItemStack currentStack, IntList slots) { if (currentStack.isEmpty()) { return true; // stack is empty, nothing to return } - if (simulateExtractItem(currentStack)) { + if (simulateExtractItem(currentStack, slots.size())) { return true; } @@ -124,57 +138,60 @@ public boolean getIngredientEquivalent(int slot) { ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); - Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, - (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); - - // iterate stored items to find equivalent - for (var entry : stackLookupMap.entrySet()) { - for (int i : entry.getValue()) { - var itemStack = availableHandlers.getStackInSlot(i); - - boolean matchedPreviously = false; - if (map.containsKey(itemStack)) { - if (!map.get(itemStack)) { - continue; - } else { - // cant return here before checking if: - // The item is available for extraction - // The recipe output is still the same, as depending on the ingredient, the output NBT may - // change - matchedPreviously = true; + for (int slot : slots) { + + Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, + (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); + + // iterate stored items to find equivalent + for (var entry : stackLookupMap.entrySet()) { + for (int i : entry.getValue()) { + var itemStack = availableHandlers.getStackInSlot(i); + + boolean matchedPreviously = false; + if (map.containsKey(itemStack)) { + if (!map.get(itemStack)) { + continue; + } else { + // cant return here before checking if: + // The item is available for extraction + // The recipe output is still the same, as depending on the ingredient, the output NBT may + // change + matchedPreviously = true; + } } - } - if (!matchedPreviously) { - boolean matched = false; - // Matching shapeless recipes actually is very bad for performance, as it checks the entire - // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can - // take the stack - for (Ingredient in : recipe.getIngredients()) { - if (in.apply(itemStack)) { - matched = true; - break; + if (!matchedPreviously) { + boolean matched = false; + // Matching shapeless recipes actually is very bad for performance, as it checks the entire + // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can + // take the stack + for (Ingredient in : recipe.getIngredients()) { + if (in.apply(itemStack)) { + matched = true; + break; + } + } + if (!matched) { + map.put(itemStack.copy(), false); + continue; } } - if (!matched) { - map.put(itemStack.copy(), false); - continue; - } - } - // update item in slot, and check that recipe matches and output item is equal to the expected one - craftingMatrix.setInventorySlotContents(slot, itemStack); - if ((cachedRecipeData.matches(craftingMatrix, world) && - ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack)) || - recipe instanceof ShapedOreEnergyTransferRecipe) { - map.put(itemStack, true); - // ingredient matched, attempt to extract it and return if successful - if (simulateExtractItem(itemStack)) { - return true; + // update item in slot, and check that recipe matches and output item is equal to the expected one + craftingMatrix.setInventorySlotContents(slot, itemStack); + if ((cachedRecipeData.matches(craftingMatrix, world) && + ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack)) || + recipe instanceof ShapedOreEnergyTransferRecipe) { + map.put(itemStack, true); + // ingredient matched, attempt to extract it and return if successful + if (simulateExtractItem(itemStack, slots.size())) { + return true; + } } + map.put(itemStack, false); + craftingMatrix.setInventorySlotContents(slot, currentStack); } - map.put(itemStack, false); - craftingMatrix.setInventorySlotContents(slot, currentStack); } } // nothing matched, so return null @@ -187,16 +204,17 @@ public boolean getIngredientEquivalent(int slot) { * @param itemStack - stack from the crafting matrix * @return true if the item exists in available inventories */ - private boolean simulateExtractItem(ItemStack itemStack) { - int amountToExtract = requiredItems.getOrDefault(itemStack, 0) + 1; + private boolean simulateExtractItem(ItemStack itemStack, int extract) { if (!stackLookupMap.containsKey(itemStack)) return false; - - var extracted = ItemStack.EMPTY; + int remaining = extract; for (int slot : stackLookupMap.get(itemStack)) { - extracted = availableHandlers.extractItem(slot, amountToExtract, true).copy(); - if (extracted.getCount() == amountToExtract) { - requiredItems.put(extracted, amountToExtract); - return true; + var slotStack = availableHandlers.extractItem(slot, remaining, true); + if (slotStack.getCount() <= remaining) { + remaining -= slotStack.getCount(); + if (remaining == 0) { + requiredItems.put(itemStack, extract); + return true; + } } } return false; @@ -235,26 +253,19 @@ protected boolean consumeRecipeItems() { if (requiredItems.isEmpty()) { return false; } - Object2IntMap gatheredItems = new Object2IntOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); + Map gatheredItems = new Int2IntOpenHashMap(); for (var entry : requiredItems.entrySet()) { ItemStack stack = entry.getKey(); int requestedAmount = entry.getValue(); - var slotList = stackLookupMap.getOrDefault(stack, new IntArrayList()); - if (slotList.size() == 0) { - continue; - } + var slotList = stackLookupMap.get(stack); + int extractedAmount = 0; for (int slot : slotList) { var extracted = availableHandlers.extractItem(slot, requestedAmount, true); - if (extracted.isEmpty()) { - stackLookupMap.get(stack).remove((Integer) slot); - continue; - } - gatheredItems.put(extracted, slot); + gatheredItems.put(slot, extracted.getCount()); extractedAmount += extracted.getCount(); - requestedAmount -= extractedAmount; + requestedAmount -= extracted.getCount(); if (requestedAmount == 0) break; } if (extractedAmount < requestedAmount) return false; @@ -262,9 +273,7 @@ protected boolean consumeRecipeItems() { boolean extracted = false; for (var gathered : gatheredItems.entrySet()) { - var stack = gathered.getKey(); - int slot = gathered.getValue(); - + var stack = availableHandlers.getStackInSlot(gathered.getKey()); if (stack.getItem().hasContainerItem(stack) && stack.isItemStackDamageable()) { int damage = 1; if (stack.getItem() instanceof IGTTool gtTool) { @@ -272,7 +281,7 @@ protected boolean consumeRecipeItems() { } stack.damageItem(damage, getSyncManager().getPlayer()); } else { - availableHandlers.extractItem(slot, stack.getCount(), false); + availableHandlers.extractItem(gathered.getKey(), gathered.getValue(), false); } extracted = true; } From 2a8631c5181083986f2cc2a50ae9ee4db1af6def Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 3 May 2024 10:35:40 -0700 Subject: [PATCH 076/147] small rendering changes and other fixes --- .../gregtech/client/utils/RenderUtil.java | 8 +++-- .../widget/workbench/CraftingOutputSlot.java | 3 +- .../widget/workbench/RecipeMemorySlot.java | 31 +++++++------------ 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index f38d5cee0d4..e0e2c0df6fa 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -378,12 +378,16 @@ public static void renderItemOverLay(float x, float y, float z, float scale, Ite GlStateManager.pushMatrix(); GlStateManager.scale(scale, scale, 0.0001f); GlStateManager.translate(x * 16, y * 16, z * 16); - RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); - renderItem.renderItemAndEffectIntoGUI(itemStack, 0, 0); + renderItemGUI(itemStack, 0, 0); GlStateManager.popMatrix(); net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); } + public static void renderItemGUI(ItemStack stack, int x, int y) { + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + renderItem.renderItemAndEffectIntoGUI(stack, x, y); + } + public static void renderFluidOverLay(float x, float y, float width, float height, float z, FluidStack fluidStack, float alpha) { if (fluidStack != null) { diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index db5c0a07469..b392b4268b9 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -23,6 +23,7 @@ import java.io.IOException; +// todo make output slot not extend item slot public class CraftingOutputSlot extends ItemSlot { private CraftingSlotSH syncHandler; @@ -89,8 +90,6 @@ public void readOnClient(int id, PacketBuffer buf) { super.readOnClient(id, buf); if (id == 5) { getSyncManager().setCursorItem(readStackSafe(buf)); - } else if (id == 6) { - } } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 619ab0e7093..22684b75229 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -1,6 +1,7 @@ package gregtech.common.mui.widget.workbench; import gregtech.api.mui.GTGuiTextures; +import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import net.minecraft.client.renderer.GlStateManager; @@ -15,7 +16,6 @@ import com.cleanroommc.modularui.widgets.ItemSlot; import org.jetbrains.annotations.NotNull; -@SuppressWarnings("DataFlowIssue") public class RecipeMemorySlot extends Widget implements Interactable { private final CraftingRecipeMemory memory; @@ -47,31 +47,22 @@ public void drawStack() { // GuiDraw.drawRect(1, 1, 16, 16, -2130706433); - GlStateManager.enableDepth(); +// GlStateManager.enableDepth(); // render the item itself - guiScreen.getItemRenderer().renderItemAndEffectIntoGUI(guiScreen.mc.player, itemstack, 1, 1); - - // render the amount overlay - // String amountText = NumberFormat.formatWithMaxDigits(1); - // textRenderer.setShadow(true); - // textRenderer.setColor(Color.WHITE.main); - // textRenderer.setAlignment(Alignment.BottomRight, getArea().width - 1, getArea().height - 1); - // textRenderer.setPos(1, 1); - // GlStateManager.disableLighting(); - // GlStateManager.disableDepth(); - // GlStateManager.disableBlend(); - // textRenderer.draw(amountText); - // GlStateManager.enableLighting(); - // GlStateManager.enableDepth(); - // GlStateManager.enableBlend(); +// guiScreen.getItemRenderer().renderItemAndEffectIntoGUI(guiScreen.mc.player, itemstack, 1, 1); int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay // render other overlays like durability bar - guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, - null); +// guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, +// null); + net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); + GlStateManager.pushMatrix(); + RenderUtil.renderItemGUI(itemstack, 1, 1); + GlStateManager.popMatrix(); + net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); itemstack.setCount(cachedCount); - GlStateManager.disableDepth(); +// GlStateManager.disableDepth(); guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); From 7c2026596499170ae51ff4f2589d3c0761412b1e Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 3 May 2024 10:57:26 -0700 Subject: [PATCH 077/147] fix rendering issues make output slot not extend itemslot --- .../storage/MetaTileEntityWorkbench.java | 3 +- .../widget/workbench/CraftingOutputSlot.java | 109 +++++++++++------- .../widget/workbench/RecipeMemorySlot.java | 20 +--- 3 files changed, 71 insertions(+), 61 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 80f192a74f1..52e5b9bc538 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -313,8 +313,7 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag return new Column() .size(54) - .child(new CraftingOutputSlot() - .slot(CraftingOutputSlot.modular(amountCrafted, this)) + .child(new CraftingOutputSlot(amountCrafted, this) .marginTop(18) .background(GTGuiTextures.SLOT.asIcon().size(22)) .marginBottom(4)) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index b392b4268b9..163ea1df3cc 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,10 +1,20 @@ package gregtech.common.mui.widget.workbench; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widget.Widget; + import gregtech.api.util.GTLog; +import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -16,78 +26,83 @@ import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.ItemSlotSH; -import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import java.io.IOException; -// todo make output slot not extend item slot -public class CraftingOutputSlot extends ItemSlot { +public class CraftingOutputSlot extends Widget implements Interactable { + + private final CraftingSlotSH syncHandler; - private CraftingSlotSH syncHandler; + public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { + this.syncHandler = new CraftingSlotSH( + new CraftingOutputMS( + workbench.getCraftingRecipeLogic().getCraftingResultInventory(), + syncValue, workbench)); + setSyncHandler(this.syncHandler); + } @Override - public ItemSlot slot(ModularSlot slot) { - if (slot instanceof CraftingOutputModularSlot craftingSlot) { - this.syncHandler = new CraftingSlotSH(craftingSlot); - if (isValidSyncHandler(this.syncHandler)) - setSyncHandler(this.syncHandler); - } else { - super.slot(slot); - } - return this; + public @NotNull Result onMousePressed(int mouseButton) { + MouseData mouseData = MouseData.create(mouseButton); + this.syncHandler.syncToServer(2, mouseData::writeToPacket); + return Result.SUCCESS; } - public static ModularSlot modular(IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { - return new CraftingOutputModularSlot(workbench.getCraftingRecipeLogic().getCraftingResultInventory(), syncValue, - workbench); + @Override + public void draw(GuiContext context, WidgetTheme widgetTheme) { + GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); + ItemStack itemstack = this.syncHandler.getOutputStack(); + if (itemstack.isEmpty()) return; + + guiScreen.setZ(100f); + guiScreen.getItemRenderer().zLevel = 100.0F; + + int cachedCount = itemstack.getCount(); + itemstack.setCount(1); // required to not render the amount overlay + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.pushMatrix(); + RenderUtil.renderItemGUI(itemstack, 1, 1); + GlStateManager.popMatrix(); + RenderHelper.enableStandardItemLighting(); + GlStateManager.disableLighting(); + itemstack.setCount(cachedCount); + + guiScreen.getItemRenderer().zLevel = 0.0F; + guiScreen.setZ(0f); } - @SuppressWarnings("UnstableApiUsage") - protected static class CraftingSlotSH extends ItemSlotSH { + protected static class CraftingSlotSH extends SyncHandler { private final CraftingRecipeLogic recipeLogic; - private final IntSyncValue syncValue; - private final CraftingRecipeMemory recipeMemory; - private final IItemHandler craftingGrid; + private final CraftingOutputMS slot; - public CraftingSlotSH(CraftingOutputModularSlot slot) { - super(slot); + public CraftingSlotSH(CraftingOutputMS slot) { + this.slot = slot; this.recipeLogic = slot.recipeLogic; - this.syncValue = slot.syncValue; - this.recipeMemory = slot.recipeMemory; - this.craftingGrid = slot.craftingGrid; } @Override - public CraftingOutputModularSlot getSlot() { - return (CraftingOutputModularSlot) super.getSlot(); - } - - @Override - public void readOnServer(int id, PacketBuffer buf) throws IOException { + public void readOnServer(int id, PacketBuffer buf) { if (id == 2) { var data = MouseData.readPacket(buf); // todo handle shift transfer if (data.shift) return; - if (recipeLogic.isRecipeValid() && getSlot().canTakeStack(getSyncManager().getPlayer())) { + if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { recipeLogic.collectAvailableItems(); if (recipeLogic.performRecipe()) { - handleItemCraft(getSlot().getStack(), getSyncManager().getPlayer()); + handleItemCraft(this.slot.getStack(), getSyncManager().getPlayer()); syncToClient(5, this::syncCraftedStack); } } - } else { - super.readOnServer(id, buf); } } @Override public void readOnClient(int id, PacketBuffer buf) { - super.readOnClient(id, buf); if (id == 5) { getSyncManager().setCursorItem(readStackSafe(buf)); } @@ -105,7 +120,7 @@ private static ItemStack readStackSafe(PacketBuffer buffer) { private void syncCraftedStack(PacketBuffer buf) { ItemStack curStack = getSyncManager().getCursorItem(); - ItemStack outStack = getSlot().getStack(); + ItemStack outStack = this.slot.getStack(); ItemStack toSync = outStack.copy(); if (curStack.getItem() == outStack.getItem() && curStack.getMetadata() == outStack.getMetadata() && @@ -123,6 +138,10 @@ private void syncCraftedStack(PacketBuffer buf) { buf.writeItemStack(toSync); } + public ItemStack getOutputStack() { + return slot.getStack(); + } + public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { itemStack.onCrafting(player.world, player, 1); @@ -137,23 +156,22 @@ public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { } if (cachedRecipe != null) { ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); - this.syncValue.setValue(this.syncValue.getValue() + resultStack.getCount(), true, true); // itemsCrafted += resultStack.getCount(); - recipeMemory.notifyRecipePerformed(craftingGrid, resultStack); + this.slot.notifyRecipePerformed(resultStack); } // call method from recipe logic to sync to client } } - protected static class CraftingOutputModularSlot extends ModularSlot { + protected static class CraftingOutputMS extends ModularSlot { private final IntSyncValue syncValue; private final CraftingRecipeLogic recipeLogic; private final CraftingRecipeMemory recipeMemory; private final IItemHandler craftingGrid; - public CraftingOutputModularSlot(IInventory craftingInventory, IntSyncValue syncValue, - MetaTileEntityWorkbench workbench) { + public CraftingOutputMS(IInventory craftingInventory, IntSyncValue syncValue, + MetaTileEntityWorkbench workbench) { super(new InventoryWrapper(craftingInventory, workbench.getCraftingRecipeLogic()), 0, true); this.syncValue = syncValue; this.recipeLogic = workbench.getCraftingRecipeLogic(); @@ -178,6 +196,11 @@ public boolean canTakeStack(EntityPlayer playerIn) { } } + public void notifyRecipePerformed(ItemStack stack) { + this.syncValue.setValue(this.syncValue.getValue() + stack.getCount(), true, true); + this.recipeMemory.notifyRecipePerformed(this.craftingGrid, stack); + } + @Override public void putStack(@NotNull ItemStack stack) { super.putStack(getStack()); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 22684b75229..03430acbbd5 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -5,6 +5,7 @@ import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; import net.minecraft.item.ItemStack; import com.cleanroommc.modularui.api.widget.Interactable; @@ -34,10 +35,6 @@ public void onInit() { @Override public void draw(GuiContext context, WidgetTheme widgetTheme) { - drawStack(); - } - - public void drawStack() { GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); ItemStack itemstack = this.memory.getRecipeOutputAtIndex(this.index); if (itemstack.isEmpty()) return; @@ -45,24 +42,15 @@ public void drawStack() { guiScreen.setZ(100f); guiScreen.getItemRenderer().zLevel = 100.0F; - // GuiDraw.drawRect(1, 1, 16, 16, -2130706433); - -// GlStateManager.enableDepth(); - // render the item itself -// guiScreen.getItemRenderer().renderItemAndEffectIntoGUI(guiScreen.mc.player, itemstack, 1, 1); - int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay - // render other overlays like durability bar -// guiScreen.getItemRenderer().renderItemOverlayIntoGUI(guiScreen.getFontRenderer(), itemstack, 1, 1, -// null); - net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); + RenderHelper.enableGUIStandardItemLighting(); GlStateManager.pushMatrix(); RenderUtil.renderItemGUI(itemstack, 1, 1); GlStateManager.popMatrix(); - net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); + RenderHelper.enableStandardItemLighting(); + GlStateManager.disableLighting(); itemstack.setCount(cachedCount); -// GlStateManager.disableDepth(); guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); From d4233dd4bc9582661e788b90a5a4f8027302ec00 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 3 May 2024 11:46:31 -0700 Subject: [PATCH 078/147] add locking rendering to memory slots --- .../java/gregtech/api/mui/GTGuiTextures.java | 2 ++ .../java/gregtech/client/utils/RenderUtil.java | 8 +++++++- .../widget/workbench/CraftingOutputSlot.java | 5 ----- .../mui/widget/workbench/RecipeMemorySlot.java | 17 ++++++++++++----- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index b92acd290b0..04bcd7b0ea3 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -214,6 +214,8 @@ public static class IDs { public static final UITexture MENU_OVERLAY = fullImage("textures/gui/overlay/menu_overlay.png"); + public static final UITexture RECIPE_LOCK = fullImage("textures/gui/widget/lock.png"); + // todo bronze/steel/primitive fluid slots? // SLOT OVERLAYS diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index e0e2c0df6fa..53ffa128ea6 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -378,14 +378,20 @@ public static void renderItemOverLay(float x, float y, float z, float scale, Ite GlStateManager.pushMatrix(); GlStateManager.scale(scale, scale, 0.0001f); GlStateManager.translate(x * 16, y * 16, z * 16); - renderItemGUI(itemStack, 0, 0); + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + renderItem.renderItemAndEffectIntoGUI(itemStack, 0, 0); GlStateManager.popMatrix(); net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); } public static void renderItemGUI(ItemStack stack, int x, int y) { + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.pushMatrix(); RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); renderItem.renderItemAndEffectIntoGUI(stack, x, y); + GlStateManager.popMatrix(); + RenderHelper.enableStandardItemLighting(); + GlStateManager.disableLighting(); } public static void renderFluidOverLay(float x, float y, float width, float height, float z, FluidStack fluidStack, diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 163ea1df3cc..5e0889daee0 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -62,12 +62,7 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay - RenderHelper.enableGUIStandardItemLighting(); - GlStateManager.pushMatrix(); RenderUtil.renderItemGUI(itemstack, 1, 1); - GlStateManager.popMatrix(); - RenderHelper.enableStandardItemLighting(); - GlStateManager.disableLighting(); itemstack.setCount(cachedCount); guiScreen.getItemRenderer().zLevel = 0.0F; diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 03430acbbd5..a81188220fa 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -44,26 +44,33 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay - RenderHelper.enableGUIStandardItemLighting(); - GlStateManager.pushMatrix(); RenderUtil.renderItemGUI(itemstack, 1, 1); - GlStateManager.popMatrix(); - RenderHelper.enableStandardItemLighting(); - GlStateManager.disableLighting(); itemstack.setCount(cachedCount); guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); + + if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) + GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme); } @NotNull @Override public Result onMousePressed(int mouseButton) { + var recipe = memory.getRecipeAtIndex(this.index); + if (recipe == null) + return Result.IGNORE; + var data = MouseData.create(mouseButton); this.memory.syncToServer(2, buffer -> { buffer.writeByte(this.index); data.writeToPacket(buffer); }); + + if (data.shift && data.mouseButton == 0) { + recipe.setRecipeLocked(!recipe.isRecipeLocked()); + } + return Result.ACCEPT; } } From f99dde111e1e0a49ee1f32f16823259af82e54fc Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 3 May 2024 11:51:07 -0700 Subject: [PATCH 079/147] spotless --- .../storage/CraftingRecipeLogic.java | 11 ++++------- .../widget/workbench/CraftingOutputSlot.java | 18 +++++++----------- .../mui/widget/workbench/RecipeMemorySlot.java | 2 -- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 6db4c9d55d1..325c620d58d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -8,10 +8,6 @@ import gregtech.api.util.ItemStackHashStrategy; import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; -import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; -import it.unimi.dsi.fastutil.ints.IntList; -import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; - import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; @@ -28,16 +24,16 @@ import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.value.sync.SyncHandler; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; -import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -109,7 +105,8 @@ public boolean attemptMatchRecipe() { } private Map compressMatrixToList(InventoryCrafting craftingMatrix) { - Map map = new Object2ObjectOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); + Map map = new Object2ObjectOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount()); for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { var stack = craftingMatrix.getStackInSlot(i).copy(); if (stack.isEmpty()) continue; diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 5e0889daee0..1d9db75536e 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,20 +1,11 @@ package gregtech.common.mui.widget.workbench; -import com.cleanroommc.modularui.api.widget.Interactable; -import com.cleanroommc.modularui.screen.GuiScreenWrapper; -import com.cleanroommc.modularui.screen.viewport.GuiContext; -import com.cleanroommc.modularui.theme.WidgetTheme; -import com.cleanroommc.modularui.value.sync.SyncHandler; -import com.cleanroommc.modularui.widget.Widget; - import gregtech.api.util.GTLog; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.RenderHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -23,9 +14,14 @@ import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.IntSyncValue; -import com.cleanroommc.modularui.value.sync.ItemSlotSH; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; @@ -75,7 +71,7 @@ protected static class CraftingSlotSH extends SyncHandler { private final CraftingOutputMS slot; public CraftingSlotSH(CraftingOutputMS slot) { - this.slot = slot; + this.slot = slot; this.recipeLogic = slot.recipeLogic; } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index a81188220fa..0bbd04d0cba 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -4,8 +4,6 @@ import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.RenderHelper; import net.minecraft.item.ItemStack; import com.cleanroommc.modularui.api.widget.Interactable; From e7bed88fe1f2f794743cfb93af3d686dc34ea0f8 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 3 May 2024 13:55:15 -0700 Subject: [PATCH 080/147] add crafting input slot --- .../storage/MetaTileEntityWorkbench.java | 15 +- .../widget/workbench/CraftingInputSlot.java | 144 ++++++++++++++++++ 2 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 52e5b9bc538..56f6f8a8288 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -11,6 +11,7 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; +import gregtech.common.mui.widget.workbench.CraftingInputSlot; import gregtech.common.mui.widget.workbench.CraftingOutputSlot; import gregtech.common.mui.widget.workbench.RecipeMemorySlot; @@ -296,13 +297,13 @@ public IWidget createCraftingGrid() { .matrix("XXX", "XXX", "XXX") - .key('X', i -> new ItemSlot() - .slot(SyncHandlers.phantomItemSlot(this.craftingGrid, i) - .changeListener((newItem, onlyAmountChanged, client, init) -> { - if (!init) { - this.recipeLogic.updateCurrentRecipe(); - } - }))) + .key('X', i -> new CraftingInputSlot(this.craftingGrid, i) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (!init) { + this.recipeLogic.updateCurrentRecipe(); + } + }) + .background(GTGuiTextures.SLOT)) .build(); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java new file mode 100644 index 00000000000..53a2e842ec9 --- /dev/null +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -0,0 +1,144 @@ +package gregtech.common.mui.widget.workbench; + +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widget.Widget; + +import com.cleanroommc.modularui.widgets.slot.IOnSlotChanged; + +import gregtech.client.utils.RenderUtil; + +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.IItemHandlerModifiable; + +import net.minecraftforge.items.ItemHandlerHelper; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class CraftingInputSlot extends Widget implements Interactable { + private final InputSyncHandler syncHandler; + + public CraftingInputSlot(IItemHandlerModifiable handler, int index) { + this.syncHandler = new InputSyncHandler(handler, index); + setSyncHandler(this.syncHandler); + } + + public CraftingInputSlot changeListener(IOnSlotChanged listener) { + this.syncHandler.listener = listener; + return this; + } + + @NotNull + @Override + public Result onMousePressed(int mouseButton) { + if (!this.syncHandler.isValid()) + return Result.IGNORE; + + this.syncHandler.syncStack(); + return Result.SUCCESS; + } + + + + @Override + public void draw(GuiContext context, WidgetTheme widgetTheme) { + GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); + ItemStack itemstack = this.syncHandler.getStack(); + if (itemstack.isEmpty()) return; + + guiScreen.setZ(100f); + guiScreen.getItemRenderer().zLevel = 100.0F; + + RenderUtil.renderItemGUI(itemstack, 1, 1); + + guiScreen.getItemRenderer().zLevel = 0.0F; + guiScreen.setZ(0f); + } + + @SuppressWarnings("OverrideOnly") + protected static class InputSyncHandler extends SyncHandler { + + private final IItemHandlerModifiable handler; + private final int index; + private ItemStack lastStoredItem; + + private IOnSlotChanged listener = IOnSlotChanged.DEFAULT; + + public InputSyncHandler(IItemHandlerModifiable handler, int index) { + this.handler = handler; + this.index = index; + } + + @Override + public void init(String key, GuiSyncManager syncHandler) { + super.init(key, syncHandler); + this.lastStoredItem = this.handler.getStackInSlot(this.index).copy(); + } + + @Override + public void readOnClient(int id, PacketBuffer buf) { + if (id == 1) { + boolean c = buf.readBoolean(); + var s = readStackSafe(buf); + boolean i = buf.readBoolean(); + this.handler.setStackInSlot(this.index, s); + this.listener.onChange(s, c, true, i); + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) { + if (id == 1) { + this.handler.setStackInSlot(this.index, readStackSafe(buf)); + } + } + + @Override + public void detectAndSendChanges(boolean init) { + ItemStack itemStack = getStack(); + if (itemStack.isEmpty() && this.lastStoredItem.isEmpty()) return; + boolean onlyAmountChanged = false; + if (init || + !ItemHandlerHelper.canItemStacksStack(this.lastStoredItem, itemStack) || + (onlyAmountChanged = itemStack.getCount() != this.lastStoredItem.getCount())) { + this.listener.onChange(itemStack, onlyAmountChanged, false, init); + if (onlyAmountChanged) { + this.lastStoredItem.setCount(itemStack.getCount()); + } else { + this.lastStoredItem = itemStack.isEmpty() ? ItemStack.EMPTY : itemStack.copy(); + } + final boolean finalOnlyAmountChanged = onlyAmountChanged; + syncToClient(1, buffer -> { + buffer.writeBoolean(finalOnlyAmountChanged); + buffer.writeItemStack(itemStack); + buffer.writeBoolean(init); + }); + } + } + + public void syncStack() { + var s = getSyncManager().getCursorItem(); + this.handler.setStackInSlot(this.index, s); + syncToServer(1, buffer -> buffer.writeItemStack(s)); + } + + public ItemStack getStack() { + return this.handler.getStackInSlot(this.index); + } + + private ItemStack readStackSafe(PacketBuffer buffer) { + ItemStack ret = ItemStack.EMPTY; + try { + ret = buffer.readItemStack(); + } catch (IOException ignored) {} + return ret; + } + } +} From 9fe4db54c3d3c63104f3044a1f5fef98e2ce65f5 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 4 May 2024 11:50:13 -0700 Subject: [PATCH 081/147] work on various custom slots --- .../gregtech/client/utils/RenderUtil.java | 7 ++++- .../storage/CraftingRecipeMemory.java | 24 +++++++++++---- .../storage/MetaTileEntityWorkbench.java | 3 +- .../widget/workbench/CraftingInputSlot.java | 22 ++++++++++++-- .../widget/workbench/CraftingOutputSlot.java | 2 +- .../widget/workbench/RecipeMemorySlot.java | 30 ++++++++++++++----- 6 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index 53ffa128ea6..6c6328b3eac 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -384,16 +384,21 @@ public static void renderItemOverLay(float x, float y, float z, float scale, Ite net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); } - public static void renderItemGUI(ItemStack stack, int x, int y) { + public static void renderItemInGUI(ItemStack stack, int x, int y, @Nullable String text) { RenderHelper.enableGUIStandardItemLighting(); GlStateManager.pushMatrix(); RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); renderItem.renderItemAndEffectIntoGUI(stack, x, y); + renderItem.renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRenderer, stack, x, y, text); GlStateManager.popMatrix(); RenderHelper.enableStandardItemLighting(); GlStateManager.disableLighting(); } + public static void renderItemInGUI(ItemStack stack, int x, int y) { + renderItemInGUI(stack, x, y, null); + } + public static void renderFluidOverLay(float x, float y, float width, float height, float z, FluidStack fluidStack, float alpha) { if (fluidStack != null) { diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 5b5cf6887dc..d6171ab140a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -53,6 +53,11 @@ private MemorizedRecipe offsetRecipe(int startIndex) { if (recipe != null && recipe.recipeLocked) continue; memorizedRecipes[i] = previousRecipe; if (recipe == null) return null; + recipe.index = i; + syncToClient(3, buffer -> { + buffer.writeByte(recipe.index); + buffer.writeItemStack(recipe.recipeResult); + }); previousRecipe = recipe; } return previousRecipe; @@ -98,6 +103,7 @@ public void notifyRecipePerformed(IItemHandler craftingGrid, ItemStack resultSta // notify slot and sync to client recipe.updateCraftingMatrix(craftingGrid); recipe.timesUsed++; +// syncToClient(5, buffer -> buffer.writeByte(recipe.index)); } } @@ -136,7 +142,7 @@ private static void copyInventoryItems(IItemHandler src, IItemHandlerModifiable public final void removeRecipe(int index) { if (hasRecipe(index)) { memorizedRecipes[index] = null; - syncToClient(2, buffer -> buffer.writeByte(index)); + syncToClient(4, buffer -> buffer.writeByte(index)); } } @@ -165,8 +171,12 @@ public void readOnClient(int id, PacketBuffer buf) { int size = buf.readByte(); for (int i = 0; i < size; i++) { int index = buf.readByte(); - if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(index); + if (!hasRecipe(index)) + memorizedRecipes[index] = new MemorizedRecipe(index); + memorizedRecipes[index].recipeResult = readStackSafe(buf); +// memorizedRecipes[index].timesUsed = buf.readVarInt(); + } } else if (id == 2) { removeRecipe(buf.readByte()); @@ -186,8 +196,10 @@ public void writeRecipes(PacketBuffer buffer) { } buffer.writeByte(written.size()); for (var entry : written.entrySet()) { - buffer.writeByte(entry.getKey()); - buffer.writeItemStack(entry.getValue()); + var recipe = memorizedRecipes[entry.getKey()]; + buffer.writeByte(recipe.index); + buffer.writeItemStack(recipe.recipeResult); +// buffer.writeVarInt(recipe.timesUsed); } } @@ -225,8 +237,8 @@ public static class MemorizedRecipe { private final ItemStackHandler craftingMatrix = new ItemStackHandler(9); private ItemStack recipeResult; private boolean recipeLocked = false; - private int timesUsed = 0; - public final int index; + public int timesUsed = 0; + public int index; private MemorizedRecipe(int index) { this.index = index; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 56f6f8a8288..c87f42287f0 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -328,7 +328,8 @@ public IWidget createRecipeMemoryGrid(GuiSyncManager syncManager) { .matrix("XXX", "XXX", "XXX") - .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i)) + .key('X', i -> new RecipeMemorySlot(this.recipeMemory, i) + .background(GTGuiTextures.SLOT)) .build().right(0); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 53a2e842ec9..35e6447404a 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -2,6 +2,7 @@ import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.value.sync.GuiSyncManager; @@ -28,6 +29,14 @@ public class CraftingInputSlot extends Widget implements Int public CraftingInputSlot(IItemHandlerModifiable handler, int index) { this.syncHandler = new InputSyncHandler(handler, index); setSyncHandler(this.syncHandler); + tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltipBuilder(tooltip -> { + tooltip.excludeArea(getArea()); + if (!isSynced()) return; + ItemStack stack = this.syncHandler.getStack(); + if (stack.isEmpty()) return; + tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); + }); } public CraftingInputSlot changeListener(IOnSlotChanged listener) { @@ -56,12 +65,20 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { guiScreen.setZ(100f); guiScreen.getItemRenderer().zLevel = 100.0F; - RenderUtil.renderItemGUI(itemstack, 1, 1); + RenderUtil.renderItemInGUI(itemstack, 1, 1); guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); } + @Override + public void drawForeground(GuiContext context) { + Tooltip tooltip = getTooltip(); + if (tooltip != null && isHoveringFor(tooltip.getShowUpTimer())) { + tooltip.draw(getContext(), this.syncHandler.getStack()); + } + } + @SuppressWarnings("OverrideOnly") protected static class InputSyncHandler extends SyncHandler { @@ -124,7 +141,8 @@ public void detectAndSendChanges(boolean init) { } public void syncStack() { - var s = getSyncManager().getCursorItem(); + var s = getSyncManager().getCursorItem().copy(); + s.setCount(1); this.handler.setStackInSlot(this.index, s); syncToServer(1, buffer -> buffer.writeItemStack(s)); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 1d9db75536e..33638dde0ec 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -58,7 +58,7 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay - RenderUtil.renderItemGUI(itemstack, 1, 1); + RenderUtil.renderItemInGUI(itemstack, 1, 1); itemstack.setCount(cachedCount); guiScreen.getItemRenderer().zLevel = 0.0F; diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 0bbd04d0cba..b950d320709 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -1,5 +1,11 @@ package gregtech.common.mui.widget.workbench; +import com.cleanroommc.modularui.api.drawable.IDrawable; + +import com.cleanroommc.modularui.api.drawable.IKey; + +import com.cleanroommc.modularui.screen.Tooltip; + import gregtech.api.mui.GTGuiTextures; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; @@ -23,12 +29,14 @@ public class RecipeMemorySlot extends Widget implements Intera public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.memory = memory; this.index = index; - } - - @Override - public void onInit() { - size(ItemSlot.SIZE); - background(GTGuiTextures.SLOT); + tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltipBuilder(tooltip -> { + tooltip.excludeArea(getArea()); + if (!memory.isValid()) return; + var recipe = memory.getRecipeAtIndex(this.index); + if (recipe == null) return; + tooltip.addLine(IKey.lang("Recipe Used: " + recipe.timesUsed)); + }); } @Override @@ -42,7 +50,7 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay - RenderUtil.renderItemGUI(itemstack, 1, 1); + RenderUtil.renderItemInGUI(itemstack, 1, 1); itemstack.setCount(cachedCount); guiScreen.getItemRenderer().zLevel = 0.0F; @@ -52,6 +60,14 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme); } + @Override + public void drawForeground(GuiContext context) { + Tooltip tooltip = getTooltip(); + if (tooltip != null && isHoveringFor(tooltip.getShowUpTimer())) { + tooltip.draw(getContext(), this.memory.getRecipeOutputAtIndex(this.index)); + } + } + @NotNull @Override public Result onMousePressed(int mouseButton) { From c258ff832dc781cd29b84d5a4975325e98e53e0c Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 4 May 2024 12:05:43 -0700 Subject: [PATCH 082/147] display and sync recipe memory times used --- .../storage/CraftingRecipeMemory.java | 48 +++++++++---------- .../widget/workbench/RecipeMemorySlot.java | 2 +- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index d6171ab140a..56c4631baf3 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -103,7 +103,7 @@ public void notifyRecipePerformed(IItemHandler craftingGrid, ItemStack resultSta // notify slot and sync to client recipe.updateCraftingMatrix(craftingGrid); recipe.timesUsed++; -// syncToClient(5, buffer -> buffer.writeByte(recipe.index)); + syncToClient(4, buffer -> buffer.writeByte(recipe.index)); } } @@ -155,51 +155,49 @@ public void writeInitialSyncData(@NotNull PacketBuffer buf) { } public void receiveInitialSyncData(@NotNull PacketBuffer buf) { - int size = buf.readByte(); - for (int i = 0; i < size; i++) { - int index = buf.readByte(); - if (!hasRecipe(index)) - memorizedRecipes[index] = new MemorizedRecipe(index); - - memorizedRecipes[index].recipeResult = readStackSafe(buf); - } + this.readRecipes(buf); } @Override public void readOnClient(int id, PacketBuffer buf) { if (id == 1) { - int size = buf.readByte(); - for (int i = 0; i < size; i++) { - int index = buf.readByte(); - if (!hasRecipe(index)) - memorizedRecipes[index] = new MemorizedRecipe(index); - - memorizedRecipes[index].recipeResult = readStackSafe(buf); -// memorizedRecipes[index].timesUsed = buf.readVarInt(); - - } + this.readRecipes(buf); } else if (id == 2) { - removeRecipe(buf.readByte()); + this.removeRecipe(buf.readByte()); } else if (id == 3) { int index = buf.readByte(); if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(index); memorizedRecipes[index].recipeResult = readStackSafe(buf); + } else if (id == 4) { + memorizedRecipes[buf.readByte()].timesUsed++; } } - public void writeRecipes(PacketBuffer buffer) { + public void writeRecipes(PacketBuffer buf) { Map written = new Int2ObjectOpenHashMap<>(); for (int i = 0; i < memorizedRecipes.length; i++) { var stack = getRecipeOutputAtIndex(i); if (stack.isEmpty()) continue; written.put(i, stack); } - buffer.writeByte(written.size()); + buf.writeByte(written.size()); for (var entry : written.entrySet()) { var recipe = memorizedRecipes[entry.getKey()]; - buffer.writeByte(recipe.index); - buffer.writeItemStack(recipe.recipeResult); -// buffer.writeVarInt(recipe.timesUsed); + buf.writeByte(recipe.index); + buf.writeItemStack(recipe.recipeResult); + buf.writeInt(recipe.timesUsed); + } + } + + public void readRecipes(PacketBuffer buf) { + int size = buf.readByte(); + for (int i = 0; i < size; i++) { + int index = buf.readByte(); + if (!hasRecipe(index)) + memorizedRecipes[index] = new MemorizedRecipe(index); + + memorizedRecipes[index].recipeResult = readStackSafe(buf); + memorizedRecipes[index].timesUsed = buf.readInt(); } } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index b950d320709..0ed680f6e13 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -35,7 +35,7 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { if (!memory.isValid()) return; var recipe = memory.getRecipeAtIndex(this.index); if (recipe == null) return; - tooltip.addLine(IKey.lang("Recipe Used: " + recipe.timesUsed)); + tooltip.addLine(IKey.lang("Times Used: " + recipe.timesUsed)); }); } From a96d5aacd7887af2b3e35df277b20ab4888f2757 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 5 May 2024 12:05:27 -0700 Subject: [PATCH 083/147] fix tooltips for output and memory slots ui fixes --- .../storage/MetaTileEntityWorkbench.java | 1 + .../widget/workbench/CraftingOutputSlot.java | 18 ++++++++++++++++++ .../mui/widget/workbench/RecipeMemorySlot.java | 5 +++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index c87f42287f0..12a3262e40c 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -243,6 +243,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .margin(7) .widthRel(0.9f) .controller(controller) + .coverChildrenHeight() // workstation page .addPage(new Column() .debugName("crafting page") diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 33638dde0ec..0d2183bd3f1 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,5 +1,7 @@ package gregtech.common.mui.widget.workbench; +import com.cleanroommc.modularui.screen.Tooltip; + import gregtech.api.util.GTLog; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; @@ -38,6 +40,14 @@ public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbe workbench.getCraftingRecipeLogic().getCraftingResultInventory(), syncValue, workbench)); setSyncHandler(this.syncHandler); + tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltipBuilder(tooltip -> { + tooltip.excludeArea(getArea()); + if (!isSynced()) return; + ItemStack stack = this.syncHandler.getOutputStack(); + if (stack.isEmpty()) return; + tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); + }); } @Override @@ -65,6 +75,14 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { guiScreen.setZ(0f); } + @Override + public void drawForeground(GuiContext context) { + Tooltip tooltip = getTooltip(); + if (tooltip != null && isHoveringFor(tooltip.getShowUpTimer())) { + tooltip.draw(getContext(), this.syncHandler.getOutputStack()); + } + } + protected static class CraftingSlotSH extends SyncHandler { private final CraftingRecipeLogic recipeLogic; diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 0ed680f6e13..a64d8fc9083 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -32,10 +32,11 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { tooltip().setAutoUpdate(true).setHasTitleMargin(true); tooltipBuilder(tooltip -> { tooltip.excludeArea(getArea()); - if (!memory.isValid()) return; var recipe = memory.getRecipeAtIndex(this.index); if (recipe == null) return; - tooltip.addLine(IKey.lang("Times Used: " + recipe.timesUsed)); + var list = getScreen().getScreenWrapper().getItemToolTip(recipe.getRecipeResult()); + list.add(1, IKey.lang("Times Used: " + recipe.timesUsed).get()); + tooltip.addStringLines(list); }); } From 2498d176bc668a37aefbc5fd9fb929156dc650f2 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 5 May 2024 12:05:46 -0700 Subject: [PATCH 084/147] sbobl --- .../widget/workbench/CraftingInputSlot.java | 20 ++++++++----------- .../widget/workbench/CraftingOutputSlot.java | 3 +-- .../widget/workbench/RecipeMemorySlot.java | 9 ++------- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 35e6447404a..12831e9b48d 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -1,5 +1,12 @@ package gregtech.common.mui.widget.workbench; +import gregtech.client.utils.RenderUtil; + +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemHandlerHelper; + import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.screen.GuiScreenWrapper; import com.cleanroommc.modularui.screen.Tooltip; @@ -8,22 +15,13 @@ import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; - import com.cleanroommc.modularui.widgets.slot.IOnSlotChanged; - -import gregtech.client.utils.RenderUtil; - -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.items.IItemHandlerModifiable; - -import net.minecraftforge.items.ItemHandlerHelper; - import org.jetbrains.annotations.NotNull; import java.io.IOException; public class CraftingInputSlot extends Widget implements Interactable { + private final InputSyncHandler syncHandler; public CraftingInputSlot(IItemHandlerModifiable handler, int index) { @@ -54,8 +52,6 @@ public Result onMousePressed(int mouseButton) { return Result.SUCCESS; } - - @Override public void draw(GuiContext context, WidgetTheme widgetTheme) { GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 0d2183bd3f1..ae5183d0885 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,7 +1,5 @@ package gregtech.common.mui.widget.workbench; -import com.cleanroommc.modularui.screen.Tooltip; - import gregtech.api.util.GTLog; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; @@ -18,6 +16,7 @@ import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index a64d8fc9083..a4061c24180 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -1,24 +1,19 @@ package gregtech.common.mui.widget.workbench; -import com.cleanroommc.modularui.api.drawable.IDrawable; - -import com.cleanroommc.modularui.api.drawable.IKey; - -import com.cleanroommc.modularui.screen.Tooltip; - import gregtech.api.mui.GTGuiTextures; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import net.minecraft.item.ItemStack; +import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.screen.GuiScreenWrapper; +import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.widget.Widget; -import com.cleanroommc.modularui.widgets.ItemSlot; import org.jetbrains.annotations.NotNull; public class RecipeMemorySlot extends Widget implements Interactable { From 37c09793beed316bd8c36d26b531ed63e2d13c0d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 7 May 2024 18:33:11 -0700 Subject: [PATCH 085/147] move changes to item handler list move shift check + misc --- .../api/capability/impl/ItemHandlerList.java | 9 ++++ .../storage/MetaTileEntityWorkbench.java | 45 +------------------ 2 files changed, 11 insertions(+), 43 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java index 762262daa50..95a268c6314 100644 --- a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java +++ b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java @@ -40,6 +40,7 @@ public int getSlots() { @Override public void setStackInSlot(int slot, @NotNull ItemStack stack) { + if (invalidSlot(slot)) return; IItemHandler itemHandler = handlerBySlotIndex.get(slot); if (itemHandler instanceof IItemHandlerModifiable modifiable) { modifiable.setStackInSlot(slot - baseIndexOffset.get(itemHandler), stack); @@ -52,12 +53,14 @@ public void setStackInSlot(int slot, @NotNull ItemStack stack) { @NotNull @Override public ItemStack getStackInSlot(int slot) { + if (invalidSlot(slot)) return ItemStack.EMPTY; IItemHandler itemHandler = handlerBySlotIndex.get(slot); return itemHandler.getStackInSlot(slot - baseIndexOffset.get(itemHandler)); } @Override public int getSlotLimit(int slot) { + if (invalidSlot(slot)) return 0; IItemHandler itemHandler = handlerBySlotIndex.get(slot); return itemHandler.getSlotLimit(slot - baseIndexOffset.get(itemHandler)); } @@ -65,6 +68,7 @@ public int getSlotLimit(int slot) { @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + if (invalidSlot(slot)) return stack; IItemHandler itemHandler = handlerBySlotIndex.get(slot); return itemHandler.insertItem(slot - baseIndexOffset.get(itemHandler), stack, simulate); } @@ -72,6 +76,7 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate @NotNull @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (invalidSlot(slot)) return ItemStack.EMPTY; IItemHandler itemHandler = handlerBySlotIndex.get(slot); return itemHandler.extractItem(slot - baseIndexOffset.get(itemHandler), amount, simulate); } @@ -80,4 +85,8 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) { public Collection getBackingHandlers() { return Collections.unmodifiableCollection(handlerBySlotIndex.values()); } + + private boolean invalidSlot(int slot) { + return slot < 0 && slot >= this.getSlots(); + } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 12a3262e40c..98f40626281 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -169,13 +169,13 @@ public IItemHandlerModifiable getAvailableHandlers() { var handler = neighbor.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()); if (handler != null) handlers.add(handler); } - this.connectedInventory = new HandlerListWrapper(handlers); + this.connectedInventory = new ItemHandlerList(handlers); handlers.clear(); handlers.add(this.internalInventory); handlers.add(this.toolInventory); handlers.add(this.connectedInventory); - return this.combinedInventory = new HandlerListWrapper(handlers); + return this.combinedInventory = new ItemHandlerList(handlers); } @Override @@ -410,47 +410,6 @@ public void setItemsCrafted(int itemsCrafted) { this.itemsCrafted = itemsCrafted; } - private static class HandlerListWrapper extends ItemHandlerList { - - public HandlerListWrapper(List itemHandlerList) { - super(itemHandlerList); - } - - @Override - public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (validSlot(slot)) - return super.insertItem(slot, stack, simulate); - - return stack; - } - - @Override - public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { - if (validSlot(slot)) - return super.extractItem(slot, amount, simulate); - - return ItemStack.EMPTY; - } - - @Override - public void setStackInSlot(int slot, @NotNull ItemStack stack) { - if (validSlot(slot)) - super.setStackInSlot(slot, stack); - } - - @Override - public @NotNull ItemStack getStackInSlot(int slot) { - if (validSlot(slot)) - return super.getStackInSlot(slot); - - return ItemStack.EMPTY; - } - - private boolean validSlot(int slot) { - return slot >= 0 || slot < this.getSlots(); - } - } - @Override public void addInformation(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { tooltip.add(I18n.format("gregtech.machine.workbench.tooltip1")); From 27eeb2c72cfd56161ba91f45027db6f421b5f2ec Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 10 May 2024 19:10:38 -0700 Subject: [PATCH 086/147] collect shift click slots manually fix issues with shift click priority --- .../storage/MetaTileEntityWorkbench.java | 4 +- .../widget/workbench/CraftingOutputSlot.java | 123 +++++++++++++++++- 2 files changed, 121 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 98f40626281..92165d10f44 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -268,7 +268,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { } public IWidget createToolInventory(GuiSyncManager syncManager) { - var toolSlots = new SlotGroup("tool_slots", 9, true); + var toolSlots = new SlotGroup("tool_slots", 9, -120, true); syncManager.registerSlotGroup(toolSlots); return SlotGroupWidget.builder() @@ -281,7 +281,7 @@ public IWidget createToolInventory(GuiSyncManager syncManager) { } public IWidget createInternalInventory(GuiSyncManager syncManager) { - var inventory = new SlotGroup("inventory", 9, true); + var inventory = new SlotGroup("internal_slots", 9, -100, true); syncManager.registerSlotGroup(inventory); return SlotGroupWidget.builder() diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index ae5183d0885..23693000898 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,6 +1,7 @@ package gregtech.common.mui.widget.workbench; import gregtech.api.util.GTLog; +import gregtech.api.util.GTTransferUtils; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; @@ -8,11 +9,13 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemHandlerHelper; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.screen.GuiScreenWrapper; @@ -20,14 +23,20 @@ import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import java.io.IOException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; public class CraftingOutputSlot extends Widget implements Interactable { @@ -87,28 +96,135 @@ protected static class CraftingSlotSH extends SyncHandler { private final CraftingRecipeLogic recipeLogic; private final CraftingOutputMS slot; + private IItemHandlerModifiable shiftclickslots; + public CraftingSlotSH(CraftingOutputMS slot) { this.slot = slot; this.recipeLogic = slot.recipeLogic; } + @Override + @SuppressWarnings("OverrideOnly") + public void init(String key, GuiSyncManager syncManager) { + super.init(key, syncManager); + List list = new ArrayList<>(); + getSyncManager().getSlotGroups().stream() + .sorted(Comparator.comparingInt(SlotGroup::getShiftClickPriority)) + .collect(Collectors.toList()) + .forEach(slotGroup -> list.addAll(slotGroup.getSlots())); + shiftclickslots = listToHandler(list); + } + @Override public void readOnServer(int id, PacketBuffer buf) { if (id == 2) { var data = MouseData.readPacket(buf); - // todo handle shift transfer - if (data.shift) return; if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { recipeLogic.collectAvailableItems(); if (recipeLogic.performRecipe()) { handleItemCraft(this.slot.getStack(), getSyncManager().getPlayer()); - syncToClient(5, this::syncCraftedStack); + if (data.shift) { + // todo handle shift transfer + GTTransferUtils.insertItem(this.shiftclickslots, this.slot.getStack(), false); + } else { + syncToClient(5, this::syncCraftedStack); + } } } } } + private static IItemHandlerModifiable listToHandler(List list) { + return new IItemHandlerModifiable() { + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + list.get(slot).putStack(stack); + } + + @Override + public int getSlots() { + return list.size(); + } + + @Override + public ItemStack getStackInSlot(int slot) { + return list.get(slot).getStack(); + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + if (stack.isEmpty()) + return ItemStack.EMPTY; + + var slot1 = list.get(slot); + ItemStack existing = slot1.getStack(); + + int limit = slot1.getItemStackLimit(stack); + + if (!existing.isEmpty()) { + if (!ItemHandlerHelper.canItemStacksStack(stack, existing)) + return stack; + + limit -= existing.getCount(); + } + + if (limit <= 0) + return stack; + + boolean reachedLimit = stack.getCount() > limit; + + if (!simulate) { + if (existing.isEmpty()) { + ItemStack s = reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, limit) : stack; + slot1.putStack(s); + } else { + existing.grow(reachedLimit ? limit : stack.getCount()); + slot1.putStack(existing); + } + } + + return reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - limit) : + ItemStack.EMPTY; + } + + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (amount == 0) + return ItemStack.EMPTY; + + var slot1 = list.get(slot); + ItemStack existing = slot1.getStack(); + + if (existing.isEmpty()) + return ItemStack.EMPTY; + + int toExtract = Math.min(amount, existing.getMaxStackSize()); + + if (existing.getCount() <= toExtract) { + if (!simulate) { + slot1.putStack(ItemStack.EMPTY); + } + return existing; + } else { + if (!simulate) { + ItemStack s = ItemHandlerHelper.copyStackWithSize(existing, + existing.getCount() - toExtract); + slot1.putStack(s); + } + + return ItemHandlerHelper.copyStackWithSize(existing, toExtract); + } + } + + @Override + public int getSlotLimit(int slot) { + return list.get(slot).getSlotStackLimit(); + } + }; + } + @Override public void readOnClient(int id, PacketBuffer buf) { if (id == 5) { @@ -167,7 +283,6 @@ public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { // itemsCrafted += resultStack.getCount(); this.slot.notifyRecipePerformed(resultStack); } - // call method from recipe logic to sync to client } } From d4598dd37b0e907a3d36583eaa1393910c153be9 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 3 Jun 2024 21:16:06 -0700 Subject: [PATCH 087/147] integrate input slots with JEI render stack amount for output slot use tool overlay for tool slots handle todos --- .../api/capability/GregtechDataCodes.java | 3 ++ .../CraftingStationInputWidgetGroup.java | 1 + .../storage/MetaTileEntityWorkbench.java | 14 ++--- .../widget/workbench/CraftingInputSlot.java | 54 ++++++++++++++++--- .../widget/workbench/CraftingOutputSlot.java | 3 -- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index 19058699a19..b2e7077cc59 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -46,6 +46,9 @@ public static int assignId() { // Misc TEs (Transformer, World Accelerator) public static final int SYNC_TILE_MODE = assignId(); + // Crafting Station + public static final int UPDATE_CLIENT_HANDLER = assignId(); + // Clipboard public static final int CREATE_FAKE_UI = assignId(); public static final int MOUSE_POSITION = assignId(); diff --git a/src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java b/src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java index 0f95c5af62b..b48f5b4e849 100644 --- a/src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java +++ b/src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java @@ -9,6 +9,7 @@ import net.minecraft.network.PacketBuffer; import net.minecraftforge.items.ItemStackHandler; +// todo remove public class CraftingStationInputWidgetGroup extends AbstractWidgetGroup { protected CraftingRecipeLogic recipeResolver; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 92165d10f44..813e4d2c032 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -70,10 +70,6 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { - // todo move these to GregtechDataCodes - public static final int UPDATE_CLIENT_HANDLER = GregtechDataCodes.assignId(); - public static final int SYNC_MEMORY = GregtechDataCodes.assignId(); - private static final IDrawable CHEST = new ItemDrawable(new ItemStack(Blocks.CHEST)) .asIcon().size(16); @@ -189,7 +185,7 @@ public void update() { @Override public void onNeighborChanged() { getCraftingRecipeLogic().updateInventory(getAvailableHandlers()); - writeCustomData(UPDATE_CLIENT_HANDLER, this::sendHandlerToClient); + writeCustomData(GregtechDataCodes.UPDATE_CLIENT_HANDLER, this::sendHandlerToClient); } public @NotNull CraftingRecipeLogic getCraftingRecipeLogic() { @@ -274,7 +270,7 @@ public IWidget createToolInventory(GuiSyncManager syncManager) { return SlotGroupWidget.builder() .row("XXXXXXXXX") .key('X', i -> new ItemSlot() - .background(GTGuiTextures.SLOT, GTGuiTextures.INGOT_OVERLAY) + .background(GTGuiTextures.SLOT, GTGuiTextures.TOOL_SLOT_OVERLAY) .slot(SyncHandlers.itemSlot(this.toolInventory, i) .slotGroup(toolSlots))) .build().marginTop(2); @@ -301,7 +297,7 @@ public IWidget createCraftingGrid() { .key('X', i -> new CraftingInputSlot(this.craftingGrid, i) .changeListener((newItem, onlyAmountChanged, client, init) -> { if (!init) { - this.recipeLogic.updateCurrentRecipe(); + this.recipeLogic.updateCurrentRecipe(); } }) .background(GTGuiTextures.SLOT)) @@ -338,7 +334,6 @@ public IWidget createInventoryPage(GuiSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 8, true); syncManager.registerSlotGroup(connected); - // todo this needs to handle when inventories are removed/added List list = new ArrayList<>(this.connectedInventory.getSlots()); Predicate checkSlotValid = itemSlot -> { int slot = itemSlot.getSlot().getSlotIndex(); @@ -356,7 +351,6 @@ public IWidget createInventoryPage(GuiSyncManager syncManager) { } for (int i = 0; i < this.connectedInventory.getSlots(); i++) { - // todo maybe show what inventory a slot belongs to? var widget = new ItemSlot() .setEnabledIf(checkSlotValid) .slot(SyncHandlers.itemSlot(this.connectedInventory, i) @@ -385,7 +379,7 @@ public void sendHandlerToClient(PacketBuffer buffer) { @Override public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { super.receiveCustomData(dataId, buf); - if (dataId == UPDATE_CLIENT_HANDLER) { + if (dataId == GregtechDataCodes.UPDATE_CLIENT_HANDLER) { int connected = buf.readVarInt(); // resize and keep any existing items diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 12831e9b48d..3281fd1df7f 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -1,5 +1,9 @@ package gregtech.common.mui.widget.workbench; +import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; + +import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; + import gregtech.client.utils.RenderUtil; import net.minecraft.item.ItemStack; @@ -17,10 +21,13 @@ import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.slot.IOnSlotChanged; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; -public class CraftingInputSlot extends Widget implements Interactable { +public class CraftingInputSlot extends Widget implements Interactable, + JeiGhostIngredientSlot, + JeiIngredientProvider { private final InputSyncHandler syncHandler; @@ -37,6 +44,11 @@ public CraftingInputSlot(IItemHandlerModifiable handler, int index) { }); } + @Override + public void onInit() { + getContext().getJeiSettings().addJeiGhostIngredientSlot(this); + } + public CraftingInputSlot changeListener(IOnSlotChanged listener) { this.syncHandler.listener = listener; return this; @@ -75,6 +87,21 @@ public void drawForeground(GuiContext context) { } } + @Override + public void setGhostIngredient(@NotNull ItemStack ingredient) { + syncHandler.setStack(ingredient); + } + + @Override + public @Nullable ItemStack castGhostIngredientIfValid(@NotNull Object ingredient) { + return ingredient instanceof ItemStack ? (ItemStack) ingredient : null; + } + + @Override + public @Nullable Object getIngredient() { + return syncHandler.getStack(); + } + @SuppressWarnings("OverrideOnly") protected static class InputSyncHandler extends SyncHandler { @@ -109,7 +136,10 @@ public void readOnClient(int id, PacketBuffer buf) { @Override public void readOnServer(int id, PacketBuffer buf) { if (id == 1) { - this.handler.setStackInSlot(this.index, readStackSafe(buf)); + var b = buf.readBoolean(); + var s = readStackSafe(buf); + this.handler.setStackInSlot(this.index, s); + this.listener.onChange(s, b, false, false); } } @@ -137,16 +167,28 @@ public void detectAndSendChanges(boolean init) { } public void syncStack() { - var s = getSyncManager().getCursorItem().copy(); - s.setCount(1); - this.handler.setStackInSlot(this.index, s); - syncToServer(1, buffer -> buffer.writeItemStack(s)); + final var cursorStack = getSyncManager().getCursorItem().copy(); + cursorStack.setCount(1); + final var curStack = getStack(); + final boolean onlyAmt = ItemHandlerHelper.canItemStacksStackRelaxed(curStack, cursorStack); + + this.handler.setStackInSlot(this.index, cursorStack); + this.listener.onChange(cursorStack, onlyAmt, true, false); + syncToServer(1, buffer -> { + buffer.writeBoolean(onlyAmt); + buffer.writeItemStack(cursorStack); + }); } public ItemStack getStack() { return this.handler.getStackInSlot(this.index); } + public void setStack(ItemStack stack) { + this.handler.setStackInSlot(this.index, stack); + this.listener.onChange(stack, false, getSyncManager().isClient(), false); + } + private ItemStack readStackSafe(PacketBuffer buffer) { ItemStack ret = ItemStack.EMPTY; try { diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 23693000898..87da655151e 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -74,10 +74,7 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { guiScreen.setZ(100f); guiScreen.getItemRenderer().zLevel = 100.0F; - int cachedCount = itemstack.getCount(); - itemstack.setCount(1); // required to not render the amount overlay RenderUtil.renderItemInGUI(itemstack, 1, 1); - itemstack.setCount(cachedCount); guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); From bbc385d213b8a08c071fe06e259ffb61c9b47268 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 3 Jun 2024 21:18:07 -0700 Subject: [PATCH 088/147] delete unused classes --- .../CraftingStationInputWidgetGroup.java | 69 ----- .../craftingstation/ItemListGridWidget.java | 260 ------------------ .../craftingstation/ItemListSlotWidget.java | 231 ---------------- .../MemorizedRecipeWidget.java | 100 ------- 4 files changed, 660 deletions(-) delete mode 100644 src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java delete mode 100644 src/main/java/gregtech/common/gui/widget/craftingstation/ItemListGridWidget.java delete mode 100644 src/main/java/gregtech/common/gui/widget/craftingstation/ItemListSlotWidget.java delete mode 100644 src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java diff --git a/src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java b/src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java deleted file mode 100644 index b48f5b4e849..00000000000 --- a/src/main/java/gregtech/api/gui/widgets/CraftingStationInputWidgetGroup.java +++ /dev/null @@ -1,69 +0,0 @@ -package gregtech.api.gui.widgets; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.util.Position; -import gregtech.common.metatileentities.storage.CraftingRecipeLogic; - -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.items.ItemStackHandler; - -// todo remove -public class CraftingStationInputWidgetGroup extends AbstractWidgetGroup { - - protected CraftingRecipeLogic recipeResolver; - protected short tintLocations; - public static final int LIGHT_RED = 0x66FF0000; - - public CraftingStationInputWidgetGroup(int x, int y, ItemStackHandler craftingGrid, - CraftingRecipeLogic recipeResolver) { - super(new Position(x, y)); - - // crafting grid - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - this.addWidget(new PhantomSlotWidget(craftingGrid, j + i * 3, x + j * 18, y + i * 18) - .setBackgroundTexture(GuiTextures.SLOT)); - } - } - - this.recipeResolver = recipeResolver; - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - if (this.widgets.size() == 9) { // In case someone added more... - for (int i = 0; i < 9; i++) { - Widget widget = widgets.get(i); - if (widget instanceof PhantomSlotWidget && ((tintLocations >> i) & 1) == 0) { // In other words, is this - // slot usable? - int color = LIGHT_RED; - - PhantomSlotWidget phantomSlotWidget = (PhantomSlotWidget) widget; - drawSolidRect(phantomSlotWidget.getPosition().x + 1, phantomSlotWidget.getPosition().y + 1, - phantomSlotWidget.getSize().getWidth() - 2, phantomSlotWidget.getSize().getWidth() - 2, - color); - } - } - } - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - short newTintLocations = recipeResolver.getTintLocations(); - if (tintLocations != newTintLocations) { - this.tintLocations = newTintLocations; - writeUpdateInfo(2, buffer -> buffer.writeShort(tintLocations)); - } - } - - public void readUpdateInfo(int id, PacketBuffer buffer) { - super.readUpdateInfo(id, buffer); - if (id == 2) { - tintLocations = buffer.readShort(); - } - } -} diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListGridWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListGridWidget.java deleted file mode 100644 index 3dc7f19a512..00000000000 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListGridWidget.java +++ /dev/null @@ -1,260 +0,0 @@ -package gregtech.common.gui.widget.craftingstation; - -import gregtech.api.gui.INativeWidget; -import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.ScrollableListWidget; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.util.ItemStackHashStrategy; -import gregtech.common.inventory.IItemInfo; -import gregtech.common.inventory.IItemList; -import gregtech.common.inventory.IItemList.InsertMode; -import gregtech.common.inventory.SimpleItemInfo; - -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; - -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.util.*; - -public class ItemListGridWidget extends ScrollableListWidget { - - private static final Comparator COMPARATOR = Comparator.comparing( - IItemInfo::getItemStack, - Comparator.comparingInt(it -> Item.REGISTRY.getIDForObject(it.getItem())) - .thenComparing(ItemStack::getItemDamage) - .thenComparing(ItemStack::hasTagCompound) - .thenComparing(it -> -Objects.hashCode(it.getTagCompound())) - .thenComparing(it -> -it.getCount())); - - @Nullable - private final IItemList itemList; - private final int slotAmountX; - private final int slotAmountY; - private int slotRowsAmount = 0; - private final Map cachedItemList = new Object2ObjectOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); - private final List itemsChanged = new ArrayList<>(); - private final List itemsRemoved = new ArrayList<>(); - - private final List displayItemList = new ArrayList<>(); - - public ItemListGridWidget(int x, int y, int slotsX, int slotsY, @Nullable IItemList itemList) { - super(x, y, slotsX * 18 + 10, slotsY * 18); - this.itemList = itemList; - this.slotAmountX = slotsX; - this.slotAmountY = slotsY; - } - - @Nullable - public IItemList getItemList() { - return itemList; - } - - @Nullable - public IItemInfo getItemInfoAt(int index) { - return displayItemList.size() > index ? displayItemList.get(index) : null; - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - boolean result = super.mouseClicked(mouseX, mouseY, button); - if (!result && isShiftDown()) { - INativeWidget hoveredSlot = findHoveredSlot(mouseX, mouseY); - if (hoveredSlot != null) { - dispatchOtherSlotShiftClick(hoveredSlot); - return true; - } - } - return result; - } - - private void dispatchOtherSlotShiftClick(INativeWidget clickedSlot) { - ItemStack stackInSlot = clickedSlot.getHandle().getStack(); - if (!stackInSlot.isEmpty()) { - writeClientAction(4, buf -> buf.writeVarInt(clickedSlot.getHandle().slotNumber)); - } - } - - private void handleSlotShiftClick(INativeWidget clickedSlot) { - ItemStack itemStack = clickedSlot.getHandle().getStack(); - if (clickedSlot.getHandle().canTakeStack(gui.entityPlayer) && !itemStack.isEmpty()) { - itemStack = clickedSlot.onItemTake(gui.entityPlayer, itemStack, true); - int amountInserted = getItemList().insertItem(itemStack, itemStack.getCount(), false, - InsertMode.LOWEST_PRIORITY); - if (amountInserted > 0) { - clickedSlot.onItemTake(gui.entityPlayer, itemStack, false); - itemStack.shrink(amountInserted); - if (!clickedSlot.canMergeSlot(itemStack)) { - gui.entityPlayer.dropItem(itemStack.copy(), false, false); - itemStack.setCount(0); - } - clickedSlot.getHandle().onSlotChanged(); - uiAccess.sendSlotUpdate(clickedSlot); - gui.entityPlayer.openContainer.detectAndSendChanges(); - } - } - } - - private void addSlotRows(int amount) { - for (int i = 0; i < amount; i++) { - int widgetAmount = widgets.size(); - WidgetGroup widgetGroup = new WidgetGroup(); - for (int j = 0; j < slotAmountX; j++) { - Widget widget = new ItemListSlotWidget(j * 18, 0, this, widgetAmount * slotAmountX + j); - widgetGroup.addWidget(widget); - } - addWidget(widgetGroup); - } - } - - private void removeSlotRows(int amount) { - for (int i = 0; i < amount; i++) { - Widget slotWidget = widgets.remove(widgets.size() - 1); - removeWidget(slotWidget); - } - } - - private void modifySlotRows(int delta) { - if (delta > 0) { - addSlotRows(delta); - } else { - removeSlotRows(delta); - } - } - - private void checkItemListForChanges() { - Iterator iterator = cachedItemList.keySet().iterator(); - while (iterator.hasNext()) { - ItemStack itemStack = iterator.next(); - if (!itemList.hasItemStored(itemStack)) { - iterator.remove(); - itemsRemoved.add(itemStack); - } - } - for (ItemStack itemStack : itemList.getStoredItems()) { - IItemInfo itemInfo = itemList.getItemInfo(itemStack); - if (itemInfo == null) - continue; - - if (!cachedItemList.containsKey(itemStack)) { - SimpleItemInfo lookupInfo = new SimpleItemInfo(itemStack); - int totalAmount = itemInfo.getTotalItemAmount(); - - if (totalAmount == 0) { - itemsRemoved.add(itemStack); - } else { - lookupInfo.setTotalItemAmount(totalAmount); - cachedItemList.put(itemStack, lookupInfo); - itemsChanged.add(lookupInfo); - } - } else { - SimpleItemInfo cachedItemInfo = cachedItemList.get(itemStack); - if (cachedItemInfo.getTotalItemAmount() != itemInfo.getTotalItemAmount()) { - cachedItemInfo.setTotalItemAmount(itemInfo.getTotalItemAmount()); - itemsChanged.add(cachedItemInfo); - } - } - } - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - if (itemList == null) return; - int amountOfItemTypes = itemList.getStoredItems().size(); - int slotRowsRequired = Math.max(slotAmountY, (int) Math.ceil(amountOfItemTypes / (slotAmountX * 1.0))); - if (slotRowsAmount != slotRowsRequired) { - int slotsToAdd = slotRowsRequired - slotRowsAmount; - this.slotRowsAmount = slotRowsRequired; - writeUpdateInfo(2, buf -> buf.writeVarInt(slotsToAdd)); - modifySlotRows(slotsToAdd); - } - - this.itemsChanged.clear(); - this.itemsRemoved.clear(); - checkItemListForChanges(); - if (!itemsChanged.isEmpty() || !itemsRemoved.isEmpty()) { - writeUpdateInfo(3, buf -> { - buf.writeVarInt(itemsRemoved.size()); - for (ItemStack stack : itemsRemoved) { - buf.writeItemStack(stack); - } - buf.writeVarInt(itemsChanged.size()); - for (SimpleItemInfo itemInfo : itemsChanged) { - buf.writeItemStack(itemInfo.getItemStack()); - buf.writeVarInt(itemInfo.getTotalItemAmount()); - } - }); - } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - super.readUpdateInfo(id, buffer); - if (id == 2) { - int slotsToAdd = buffer.readVarInt(); - modifySlotRows(slotsToAdd); - } - if (id == 3) { - try { - int itemsRemoved = buffer.readVarInt(); - for (int i = 0; i < itemsRemoved; i++) { - ItemStack itemStack = buffer.readItemStack(); - this.displayItemList.removeIf( - it -> ItemStackHashStrategy.comparingAllButCount().equals(it.getItemStack(), itemStack)); - } - int itemsChanged = buffer.readVarInt(); - for (int i = 0; i < itemsChanged; i++) { - ItemStack itemStack = buffer.readItemStack(); - int newTotalAmount = buffer.readVarInt(); - SimpleItemInfo itemInfo = displayItemList.stream() - .filter(it -> ItemStackHashStrategy.comparingAllButCount().equals(it.getItemStack(), - itemStack)) - .findAny() - .orElse(null); - if (itemInfo == null) { - itemInfo = new SimpleItemInfo(itemStack); - this.displayItemList.add(itemInfo); - } - itemInfo.setTotalItemAmount(newTotalAmount); - } - this.displayItemList.sort(COMPARATOR); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - super.handleClientAction(id, buffer); - if (id == 4) { - INativeWidget clickedSlot = findSlotByNumber(buffer.readVarInt()); - if (clickedSlot != null) { - handleSlotShiftClick(clickedSlot); - } - } - } - - @Nullable - private INativeWidget findHoveredSlot(int mouseX, int mouseY) { - return gui.guiWidgets.values().stream() - .flatMap(it -> it.getNativeWidgets().stream()) - .filter(it -> it.getHandle().isEnabled()) - .filter(it -> it.getHandle().canTakeStack(gui.entityPlayer)) - .filter(it -> ((Widget) it).isMouseOverElement(mouseX, mouseY)) - .findFirst().orElse(null); - } - - @Nullable - private INativeWidget findSlotByNumber(int slotNumber) { - return gui.guiWidgets.values().stream() - .flatMap(it -> it.getNativeWidgets().stream()) - .filter(it -> it.getHandle().slotNumber == slotNumber) - .findFirst().orElse(null); - } -} diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListSlotWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListSlotWidget.java deleted file mode 100644 index f087b3d0708..00000000000 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListSlotWidget.java +++ /dev/null @@ -1,231 +0,0 @@ -package gregtech.common.gui.widget.craftingstation; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.Widget; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.client.utils.TooltipHelper; -import gregtech.common.inventory.IItemInfo; -import gregtech.common.inventory.IItemList; -import gregtech.common.inventory.IItemList.InsertMode; - -import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.text.TextFormatting; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.util.List; - -public class ItemListSlotWidget extends Widget { - - private final ItemListGridWidget gridWidget; - private final int index; - - ItemListSlotWidget(int x, int y, ItemListGridWidget gridWidget, int index) { - super(new Position(x, y), new Size(18, 18)); - this.gridWidget = gridWidget; - this.index = index; - } - - public static String formatItemAmount(int itemAmount) { - return Integer.toString(itemAmount); - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - Position position = getPosition(); - GuiTextures.SLOT.draw(position.x, position.y, 18, 18); - IItemInfo itemInfo = gridWidget.getItemInfoAt(index); - int stackX = position.x + 1; - int stackY = position.y + 1; - if (itemInfo != null) { - ItemStack itemStack = itemInfo.getItemStack(); - // Used to reset the ItemStack count after drawing. Avoids copying the itemStack - int cachedCount = itemStack.getCount(); - // Set the count to 1 to prevent stack size from being drawn in drawItemStack - itemStack.setCount(1); - String itemAmountStr = formatItemAmount(itemInfo.getTotalItemAmount()); - drawItemStack(itemStack, stackX, stackY, null); - drawStringFixedCorner(itemAmountStr, stackX + 17, stackY + 17, 16777215, true, 0.5f); - itemStack.setCount(cachedCount); - } - if (isMouseOverElement(mouseX, mouseY)) { - drawSelectionOverlay(stackX, stackY, 16, 16); - } - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - super.drawInForeground(mouseX, mouseY); - IItemInfo itemInfo = gridWidget.getItemInfoAt(index); - if (itemInfo != null && isMouseOverElement(mouseX, mouseY)) { - ItemStack itemStack = itemInfo.getItemStack(); - List tooltip = getItemToolTip(itemStack); - int totalItemStored = itemInfo.getTotalItemAmount(); - String itemStoredText = I18n.format("gregtech.item_list.item_stored", totalItemStored); - tooltip.add(TextFormatting.GRAY + itemStoredText); - drawHoveringText(itemStack, tooltip, -1, mouseX, mouseY); - } - } - - private void setCreativeHeldItem(@NotNull ItemStack itemStack) { - InventoryPlayer inventory = gui.entityPlayer.inventory; - if (!itemStack.isEmpty() && inventory.getItemStack().isEmpty()) { - itemStack.setCount(itemStack.getMaxStackSize()); - inventory.setItemStack(itemStack); - } - } - - private static int getAmountToTake(@NotNull ItemStack itemStack, int maxAmount, int button) { - int maxStackSize = Math.min(itemStack.getMaxStackSize(), maxAmount); - return button == 0 ? maxStackSize : (maxStackSize >= 2 ? maxStackSize / 2 : 1); - } - - // returns true if something actually happened - private boolean insertHeldItemStack(int button, boolean isClient) { - InventoryPlayer inventory = gui.entityPlayer.inventory; - int amountToInsert = button == 1 ? 1 : Integer.MAX_VALUE; - if (!inventory.getItemStack().isEmpty()) { - if (!isClient) { - // on server, we lookup item list to see how much we can actually insert - ItemStack heldItemStack = inventory.getItemStack(); - IItemList itemList = gridWidget.getItemList(); - int amountInserted = itemList.insertItem(heldItemStack, - Math.min(heldItemStack.getCount(), amountToInsert), false, InsertMode.LOWEST_PRIORITY); - heldItemStack.shrink(amountInserted); - uiAccess.sendHeldItemUpdate(); - gui.entityPlayer.openContainer.detectAndSendChanges(); - return amountInserted > 0; - } else { - // on client we assume we can insert full stack into the network - inventory.getItemStack().shrink(amountToInsert); - return true; - } - } - return false; - } - - private void extractItemStack(ItemStack itemStack, int amount, boolean isClient) { - InventoryPlayer inventory = gui.entityPlayer.inventory; - if (inventory.getItemStack().isEmpty()) { - if (!isClient) { - // on server, we try to extract from the network - IItemList itemList = gridWidget.getItemList(); - int amountExtracted = itemList.extractItem(itemStack, amount, false); - if (amountExtracted > 0) { - ItemStack resultStack = itemStack.copy(); - resultStack.setCount(amountExtracted); - inventory.setItemStack(resultStack); - } - uiAccess.sendHeldItemUpdate(); - } else { - // on client we assume we can extract as much items as user wishes - ItemStack resultStack = itemStack.copy(); - resultStack.setCount(amount); - inventory.setItemStack(resultStack); - } - } - } - - private void handleMouseClick(@Nullable IItemInfo itemInfo, int button, boolean isClient) { - if (button == 2) { - if (itemInfo != null && gui.entityPlayer.isCreative()) { - ItemStack itemStack = itemInfo.getItemStack().copy(); - setCreativeHeldItem(itemStack); - } - } else if (button == 0 || button == 1) { - if (insertHeldItemStack(button, isClient) || - !gui.entityPlayer.inventory.getItemStack().isEmpty()) { - return; - } - if (itemInfo != null) { - ItemStack itemStack = itemInfo.getItemStack(); - int extractAmount = getAmountToTake(itemStack, itemInfo.getTotalItemAmount(), button); - extractItemStack(itemStack, extractAmount, isClient); - } - } - } - - private void handleSelfShiftClick(@NotNull IItemInfo itemInfo) { - ItemStack itemStack = itemInfo.getItemStack().copy(); - itemStack.setCount(itemStack.getMaxStackSize()); - int currentStackSize = itemStack.getCount(); - uiAccess.attemptMergeStack(itemStack, true, true); - int amountToExtract = Math.min(currentStackSize - itemStack.getCount(), itemInfo.getTotalItemAmount()); - if (amountToExtract > 0) { - int extracted = gridWidget.getItemList().extractItem(itemInfo.getItemStack(), amountToExtract, false); - ItemStack resultStack = itemInfo.getItemStack().copy(); - resultStack.setCount(extracted); - if (!resultStack.isEmpty()) { - uiAccess.attemptMergeStack(resultStack, true, false); - gui.entityPlayer.openContainer.detectAndSendChanges(); - if (!resultStack.isEmpty()) { - gui.entityPlayer.dropItem(resultStack, false, false); - } - } - } - } - - @Override - public void handleClientAction(int id, PacketBuffer buffer) { - super.handleClientAction(id, buffer); - if (id == 1) { - try { - ItemStack itemStack = buffer.readItemStack(); - int button = buffer.readVarInt(); - IItemInfo itemInfo = itemStack.isEmpty() ? null : gridWidget.getItemList().getItemInfo(itemStack); - handleMouseClick(itemInfo, button, false); - } catch (IOException e) { - throw new RuntimeException(e); - } - } else if (id == 2) { - try { - ItemStack itemStack = buffer.readItemStack(); - IItemInfo itemInfo = gridWidget.getItemList().getItemInfo(itemStack); - if (itemInfo != null) { - handleSelfShiftClick(itemInfo); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - private void dispatchMouseClick(int button) { - IItemInfo itemInfo = gridWidget.getItemInfoAt(index); - handleMouseClick(itemInfo, button, true); - ItemStack itemStack = itemInfo == null ? ItemStack.EMPTY : itemInfo.getItemStack(); - writeClientAction(1, buf -> { - buf.writeItemStack(itemStack); - buf.writeVarInt(button); - }); - } - - private void dispatchSelfShiftClick() { - IItemInfo itemInfo = gridWidget.getItemInfoAt(index); - if (itemInfo != null) { - writeClientAction(2, buf -> buf.writeItemStack(itemInfo.getItemStack())); - } - } - - @Override - public boolean mouseClicked(int mouseX, int mouseY, int button) { - if (isMouseOverElement(mouseX, mouseY)) { - boolean shiftClick = TooltipHelper.isShiftDown(); - if (!shiftClick) { - dispatchMouseClick(button); - } else { - dispatchSelfShiftClick(); - } - return true; - } - return false; - } -} diff --git a/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java deleted file mode 100644 index dbdddd41bd4..00000000000 --- a/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java +++ /dev/null @@ -1,100 +0,0 @@ -package gregtech.common.gui.widget.craftingstation; - -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.IRenderContext; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.util.Position; -import gregtech.common.metatileentities.storage.CraftingRecipeMemory; -import gregtech.common.metatileentities.storage.CraftingRecipeMemory.MemorizedRecipe; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.ClickType; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.items.IItemHandlerModifiable; -import net.minecraftforge.items.ItemStackHandler; - -import java.util.List; - -public class MemorizedRecipeWidget extends SlotWidget { - - private final CraftingRecipeMemory recipeMemory; - private final int recipeIndex; - private boolean recipeLocked = false; - private final IItemHandlerModifiable craftingGrid; - - public MemorizedRecipeWidget(CraftingRecipeMemory recipeMemory, int index, IItemHandlerModifiable craftingGrid, - int xPosition, int yPosition) { - super(new ItemStackHandler(1), 0, xPosition, yPosition, false, false); - this.recipeMemory = recipeMemory; - this.recipeIndex = index; - this.craftingGrid = craftingGrid; - } - - @Override - public void detectAndSendChanges() { - super.detectAndSendChanges(); - MemorizedRecipe recipe = recipeMemory.getRecipeAtIndex(recipeIndex); - ItemStack resultStack = recipe == null ? ItemStack.EMPTY : recipe.getRecipeResult(); - if (!ItemStack.areItemStacksEqual(resultStack, slotReference.getStack())) { - slotReference.putStack(resultStack); - uiAccess.sendSlotUpdate(this); - } - boolean recipeLocked = recipe != null && recipe.isRecipeLocked(); - if (this.recipeLocked != recipeLocked) { - this.recipeLocked = recipeLocked; - writeUpdateInfo(1, buf -> buf.writeBoolean(recipeLocked)); - } - } - - @Override - public void drawInForeground(int mouseX, int mouseY) { - super.drawInForeground(mouseX, mouseY); - if (isMouseOverElement(mouseX, mouseY) && slotReference.getHasStack()) { - ((ISlotWidget) slotReference).setHover(false); - GlStateManager.disableDepth(); - List tooltip = getItemToolTip(slotReference.getStack()); - tooltip.add(I18n.format("gregtech.recipe_memory_widget.tooltip.1")); - tooltip.add(I18n.format("gregtech.recipe_memory_widget.tooltip.2")); - drawHoveringText(slotReference.getStack(), tooltip, -1, mouseX, mouseY); - GlStateManager.enableDepth(); - } - } - - @Override - public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { - super.drawInBackground(mouseX, mouseY, partialTicks, context); - if (recipeLocked) { - GlStateManager.translate(0, 0, 160); - Position pos = getPosition(); - GlStateManager.disableDepth(); - GuiTextures.LOCK.draw(pos.x, pos.y + 10, 8, 8); - GlStateManager.enableDepth(); - GlStateManager.translate(0, 0, -160); - } - } - - @Override - public void readUpdateInfo(int id, PacketBuffer buffer) { - super.readUpdateInfo(id, buffer); - if (id == 1) this.recipeLocked = buffer.readBoolean(); - } - - @Override - public ItemStack slotClick(int dragType, ClickType clickTypeIn, EntityPlayer player) { - if (!player.world.isRemote) { - MemorizedRecipe recipe = recipeMemory.getRecipeAtIndex(recipeIndex); - if (recipe != null && !recipe.getRecipeResult().isEmpty()) { - if (clickTypeIn == ClickType.PICKUP) { - // recipeMemory.loadRecipe(recipeIndex, craftingGrid); - player.openContainer.detectAndSendChanges(); - } else if (clickTypeIn == ClickType.QUICK_MOVE) { - recipe.setRecipeLocked(!recipe.isRecipeLocked()); - } - } - } - return ItemStack.EMPTY; - } -} From 13fa0a63a8f78cca1f90f66b88630372f9b05f7f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 3 Jun 2024 21:19:11 -0700 Subject: [PATCH 089/147] sboblss --- .../storage/MetaTileEntityWorkbench.java | 2 +- .../common/mui/widget/workbench/CraftingInputSlot.java | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 813e4d2c032..596488f7f63 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -297,7 +297,7 @@ public IWidget createCraftingGrid() { .key('X', i -> new CraftingInputSlot(this.craftingGrid, i) .changeListener((newItem, onlyAmountChanged, client, init) -> { if (!init) { - this.recipeLogic.updateCurrentRecipe(); + this.recipeLogic.updateCurrentRecipe(); } }) .background(GTGuiTextures.SLOT)) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 3281fd1df7f..598496d7217 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -1,9 +1,5 @@ package gregtech.common.mui.widget.workbench; -import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; - -import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; - import gregtech.client.utils.RenderUtil; import net.minecraft.item.ItemStack; @@ -12,6 +8,8 @@ import net.minecraftforge.items.ItemHandlerHelper; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; +import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; import com.cleanroommc.modularui.screen.GuiScreenWrapper; import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.screen.viewport.GuiContext; @@ -26,8 +24,8 @@ import java.io.IOException; public class CraftingInputSlot extends Widget implements Interactable, - JeiGhostIngredientSlot, - JeiIngredientProvider { + JeiGhostIngredientSlot, + JeiIngredientProvider { private final InputSyncHandler syncHandler; From ccd41a44a85dc8c80af10078d5ffbbee8d3b892d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 4 Jun 2024 14:08:04 -0700 Subject: [PATCH 090/147] handle buckets properly --- .../metatileentities/storage/CraftingRecipeLogic.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 325c620d58d..74cd182481a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -270,15 +270,20 @@ protected boolean consumeRecipeItems() { boolean extracted = false; for (var gathered : gatheredItems.entrySet()) { - var stack = availableHandlers.getStackInSlot(gathered.getKey()); - if (stack.getItem().hasContainerItem(stack) && stack.isItemStackDamageable()) { + int slot = gathered.getKey(), amount = gathered.getValue(); + var stack = availableHandlers.getStackInSlot(slot); + + if (stack.isItemStackDamageable()) { int damage = 1; if (stack.getItem() instanceof IGTTool gtTool) { damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); } stack.damageItem(damage, getSyncManager().getPlayer()); + } else if (stack.getItem().hasContainerItem(stack)) { + var newStack = stack.getItem().getContainerItem(stack); + availableHandlers.setStackInSlot(slot, newStack); } else { - availableHandlers.extractItem(gathered.getKey(), gathered.getValue(), false); + availableHandlers.extractItem(slot, amount, false); } extracted = true; } From 4278d0a9437336c7136c99f4a1ac7c172a8f976a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 4 Jun 2024 14:24:07 -0700 Subject: [PATCH 091/147] imrove wrapper and some javadocs --- .../storage/CraftingRecipeLogic.java | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 74cd182481a..ac6e18cffce 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -43,7 +43,10 @@ public class CraftingRecipeLogic extends SyncHandler { private final World world; private IItemHandlerModifiable availableHandlers; - /** Used to lookup a list of slots for a given stack */ + /** + * Used to lookup a list of slots for a given stack + * filled by {@link CraftingRecipeLogic#collectAvailableItems()} + **/ private final Object2ObjectOpenCustomHashMap> stackLookupMap = new Object2ObjectOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); @@ -64,7 +67,7 @@ public class CraftingRecipeLogic extends SyncHandler { public CraftingRecipeLogic(World world, IItemHandlerModifiable handlers, IItemHandlerModifiable craftingMatrix) { this.world = world; this.availableHandlers = handlers; - this.craftingMatrix = new CraftingWrapper(craftingMatrix); + this.craftingMatrix = wrapHandler(craftingMatrix); this.cachedRecipeData = new CachedRecipeData(); } @@ -198,7 +201,8 @@ public boolean getIngredientEquivalent(ItemStack currentStack, IntList slots) { /** * Attempts to extract the given stack from connected inventories * - * @param itemStack - stack from the crafting matrix + * @param itemStack stack from the crafting matrix + * @param extract the amount to extract * @return true if the item exists in available inventories */ private boolean simulateExtractItem(ItemStack itemStack, int extract) { @@ -382,29 +386,23 @@ private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { buffer.writeCompoundTag(tag); } - private static class CraftingWrapper extends InventoryCrafting { - - IItemHandlerModifiable craftingHandler; - - public CraftingWrapper(IItemHandlerModifiable craftingHandler) { - super(new DummyContainer(), 3, 3); - this.craftingHandler = craftingHandler; - } - - @Override - public ItemStack getStackInRowAndColumn(int row, int column) { - int index = row + (3 * column); - return this.craftingHandler.getStackInSlot(index); - } + public static InventoryCrafting wrapHandler(IItemHandlerModifiable handler) { + return new InventoryCrafting(new DummyContainer(), 3, 3) { + @Override + public ItemStack getStackInRowAndColumn(int row, int column) { + int index = row + (3 * column); + return handler.getStackInSlot(index); + } - @Override - public ItemStack getStackInSlot(int index) { - return craftingHandler.getStackInSlot(index); - } + @Override + public ItemStack getStackInSlot(int index) { + return handler.getStackInSlot(index); + } - @Override - public void setInventorySlotContents(int index, ItemStack stack) { - craftingHandler.setStackInSlot(index, GTUtility.copy(1, stack)); - } + @Override + public void setInventorySlotContents(int index, ItemStack stack) { + handler.setStackInSlot(index, GTUtility.copy(1, stack)); + } + }; } } From c45ad6b808e3dfb967b3c9001a9555026ecde973 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Wed, 5 Jun 2024 21:02:37 -0500 Subject: [PATCH 092/147] Tinting (#2) * feat: tinting * fix: forgot to remove --- .../storage/CraftingRecipeLogic.java | 79 +++++++++++-------- .../storage/MetaTileEntityWorkbench.java | 10 +-- .../widget/workbench/CraftingInputSlot.java | 14 +++- .../widget/workbench/CraftingOutputSlot.java | 1 - .../widget/workbench/RecipeMemorySlot.java | 6 +- 5 files changed, 61 insertions(+), 49 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index ac6e18cffce..580537a56aa 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -51,8 +51,8 @@ public class CraftingRecipeLogic extends SyncHandler { ItemStackHashStrategy.comparingAllButCount()); /** - * List of items needed to complete the crafting recipe, - * filled by {@link CraftingRecipeLogic#getIngredientEquivalent(ItemStack, IntList)} )} + * List of items needed to complete the crafting recipe, filled by + * {@link CraftingRecipeLogic#getIngredientEquivalent(ItemStack, IntList)} )} **/ private final Map requiredItems = new Object2IntOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); @@ -62,7 +62,7 @@ public class CraftingRecipeLogic extends SyncHandler { private final IInventory craftingResultInventory = new InventoryCraftResult(); private final CachedRecipeData cachedRecipeData; public static short ALL_INGREDIENTS_PRESENT = 511; - private short tintLocation = ALL_INGREDIENTS_PRESENT; + private short presenceMatrix = ALL_INGREDIENTS_PRESENT; public CraftingRecipeLogic(World world, IItemHandlerModifiable handlers, IItemHandlerModifiable craftingMatrix) { this.world = world; @@ -95,16 +95,19 @@ public void fillCraftingGrid(Map ingredients) { /** * Attempts to match the crafting matrix against all available inventories - * - * @return true if all items matched + * + * @return 511 if all items matched */ - public boolean attemptMatchRecipe() { + public short attemptMatchRecipe() { + short presenceMatrix = 511; requiredItems.clear(); for (var stack : compressMatrixToList(this.craftingMatrix).entrySet()) { - if (!getIngredientEquivalent(stack.getKey(), stack.getValue())) - return false; + int notFound = stack.getValue().size() - getIngredientEquivalent(stack.getKey(), stack.getValue()); + for (int i = notFound - 1; i >= 0; i--) { + presenceMatrix -= (short) (1 << stack.getValue().get(i)); + } } - return true; + return presenceMatrix; } private Map compressMatrixToList(InventoryCrafting craftingMatrix) { @@ -121,23 +124,23 @@ private Map compressMatrixToList(InventoryCrafting craftingM /** * Searches all available inventories for an ingredient equivalent for a stack in the crafting matrix - * + * * @param currentStack stack to find a substitute for - * @return true if a valid substitute exists for the stack in the slot + * @return number of slots for which a valid substitute exists */ - public boolean getIngredientEquivalent(ItemStack currentStack, IntList slots) { + public int getIngredientEquivalent(ItemStack currentStack, IntList slots) { if (currentStack.isEmpty()) { - return true; // stack is empty, nothing to return + return slots.size(); // stack is empty, nothing to return } - if (simulateExtractItem(currentStack, slots.size())) { - return true; + if (simulateExtractItem(currentStack, slots.size()) == 0) { + return slots.size(); } var recipe = getCachedRecipe(); ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); - + int succeeded = 0; for (int slot : slots) { Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, @@ -185,8 +188,9 @@ public boolean getIngredientEquivalent(ItemStack currentStack, IntList slots) { recipe instanceof ShapedOreEnergyTransferRecipe) { map.put(itemStack, true); // ingredient matched, attempt to extract it and return if successful - if (simulateExtractItem(itemStack, slots.size())) { - return true; + succeeded += slots.size() - simulateExtractItem(itemStack, slots.size()); + if (succeeded == slots.size()) { + return slots.size(); } } map.put(itemStack, false); @@ -194,19 +198,18 @@ public boolean getIngredientEquivalent(ItemStack currentStack, IntList slots) { } } } - // nothing matched, so return null - return false; + return succeeded; } /** * Attempts to extract the given stack from connected inventories - * + * * @param itemStack stack from the crafting matrix * @param extract the amount to extract - * @return true if the item exists in available inventories + * @return number of items yet to be extracted */ - private boolean simulateExtractItem(ItemStack itemStack, int extract) { - if (!stackLookupMap.containsKey(itemStack)) return false; + private int simulateExtractItem(ItemStack itemStack, int extract) { + if (!stackLookupMap.containsKey(itemStack)) return extract; int remaining = extract; for (int slot : stackLookupMap.get(itemStack)) { var slotStack = availableHandlers.extractItem(slot, remaining, true); @@ -214,17 +217,17 @@ private boolean simulateExtractItem(ItemStack itemStack, int extract) { remaining -= slotStack.getCount(); if (remaining == 0) { requiredItems.put(itemStack, extract); - return true; + return 0; } } } - return false; + return remaining; } public boolean performRecipe() { if (!isRecipeValid()) return false; - if (!attemptMatchRecipe() || !consumeRecipeItems()) { + if (attemptMatchRecipe() != ALL_INGREDIENTS_PRESENT || !consumeRecipeItems()) { return false; } @@ -314,17 +317,26 @@ public IRecipe getCachedRecipe() { return this.cachedRecipeData.getRecipe(); } - public void update() { + @Override + public void detectAndSendChanges(boolean init) { + super.detectAndSendChanges(init); + this.collectAvailableItems(); + short newMatrix; if (getCachedRecipeData().getRecipe() != null) { - // todo fix tint location - // tintLocation = getCachedRecipeData().attemptMatchRecipe(); + newMatrix = attemptMatchRecipe(); } else { - tintLocation = ALL_INGREDIENTS_PRESENT; + newMatrix = ALL_INGREDIENTS_PRESENT; + } + if (init || newMatrix != this.presenceMatrix) { + this.presenceMatrix = newMatrix; + syncToClient(1, buffer -> { + buffer.writeShort(presenceMatrix); + }); } } public short getTintLocations() { - return tintLocation; + return (short) (ALL_INGREDIENTS_PRESENT - presenceMatrix); } public CachedRecipeData getCachedRecipeData() { @@ -344,6 +356,9 @@ public void collectAvailableItems() { @Override public void readOnClient(int id, PacketBuffer buf) { + if (id == 1) { + this.presenceMatrix = buf.readShort(); + } if (id == 4) { getSyncManager().setCursorItem(readStackSafe(buf)); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 596488f7f63..e2490fb19b3 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -174,14 +174,6 @@ public IItemHandlerModifiable getAvailableHandlers() { return this.combinedInventory = new ItemHandlerList(handlers); } - @Override - public void update() { - super.update(); - if (!getWorld().isRemote && recipeLogic != null) { - getCraftingRecipeLogic().update(); - } - } - @Override public void onNeighborChanged() { getCraftingRecipeLogic().updateInventory(getAvailableHandlers()); @@ -294,7 +286,7 @@ public IWidget createCraftingGrid() { .matrix("XXX", "XXX", "XXX") - .key('X', i -> new CraftingInputSlot(this.craftingGrid, i) + .key('X', i -> new CraftingInputSlot(this.recipeLogic, this.craftingGrid, i) .changeListener((newItem, onlyAmountChanged, client, init) -> { if (!init) { this.recipeLogic.updateCurrentRecipe(); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 598496d7217..ae83120af95 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -2,6 +2,8 @@ import gregtech.client.utils.RenderUtil; +import gregtech.common.metatileentities.storage.CraftingRecipeLogic; + import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.items.IItemHandlerModifiable; @@ -22,14 +24,17 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.util.function.Consumer; public class CraftingInputSlot extends Widget implements Interactable, JeiGhostIngredientSlot, JeiIngredientProvider { private final InputSyncHandler syncHandler; + private final CraftingRecipeLogic logic; - public CraftingInputSlot(IItemHandlerModifiable handler, int index) { + public CraftingInputSlot(CraftingRecipeLogic logic, IItemHandlerModifiable handler, int index) { + this.logic = logic; this.syncHandler = new InputSyncHandler(handler, index); setSyncHandler(this.syncHandler); tooltip().setAutoUpdate(true).setHasTitleMargin(true); @@ -68,10 +73,11 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { ItemStack itemstack = this.syncHandler.getStack(); if (itemstack.isEmpty()) return; - guiScreen.setZ(100f); - guiScreen.getItemRenderer().zLevel = 100.0F; - RenderUtil.renderItemInGUI(itemstack, 1, 1); + int allTints = logic.getTintLocations(); + if ((allTints & 1 << this.syncHandler.index) != 0) { + RenderUtil.renderRect(0, 0, 18, 18, 100, 0x80FF0000); + } guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 87da655151e..6b955dd305a 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -118,7 +118,6 @@ public void readOnServer(int id, PacketBuffer buf) { var data = MouseData.readPacket(buf); if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { - recipeLogic.collectAvailableItems(); if (recipeLogic.performRecipe()) { handleItemCraft(this.slot.getStack(), getSyncManager().getPlayer()); if (data.shift) { diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index a4061c24180..d262c0dd967 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -49,11 +49,11 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { RenderUtil.renderItemInGUI(itemstack, 1, 1); itemstack.setCount(cachedCount); - guiScreen.getItemRenderer().zLevel = 0.0F; - guiScreen.setZ(0f); - if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme); + + guiScreen.getItemRenderer().zLevel = 0.0F; + guiScreen.setZ(0f); } @Override From 06c81a761fda0eca5d061cc42a30089d3884f43f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 5 Jun 2024 19:03:39 -0700 Subject: [PATCH 093/147] fix overlay --- .../common/mui/widget/workbench/CraftingInputSlot.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index ae83120af95..48f6d485046 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -73,12 +73,14 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { ItemStack itemstack = this.syncHandler.getStack(); if (itemstack.isEmpty()) return; - RenderUtil.renderItemInGUI(itemstack, 1, 1); int allTints = logic.getTintLocations(); if ((allTints & 1 << this.syncHandler.index) != 0) { RenderUtil.renderRect(0, 0, 18, 18, 100, 0x80FF0000); } + guiScreen.setZ(100f); + guiScreen.getItemRenderer().zLevel = 100f; + RenderUtil.renderItemInGUI(itemstack, 1, 1); guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); } From 809596c80b08dff8959f5c5d075ab542e513ee18 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 8 Jun 2024 16:53:35 -0700 Subject: [PATCH 094/147] casually rewrite recipe logic a bit :handsom: make the stack lookup map into a cache make recipe logic reference the input slots instead of vice versa improve `detectAndSendChanges()` a bit --- .../storage/CraftingRecipeLogic.java | 322 ++++++++++-------- .../storage/MetaTileEntityWorkbench.java | 3 +- .../widget/workbench/CraftingInputSlot.java | 35 +- 3 files changed, 206 insertions(+), 154 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 580537a56aa..cc3da57bde8 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -7,6 +7,7 @@ import gregtech.api.util.GTUtility; import gregtech.api.util.ItemStackHashStrategy; import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; +import gregtech.common.mui.widget.workbench.CraftingInputSlot; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; @@ -24,10 +25,11 @@ import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.value.sync.SyncHandler; +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.ints.Int2BooleanArrayMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; @@ -42,17 +44,17 @@ public class CraftingRecipeLogic extends SyncHandler { private final World world; private IItemHandlerModifiable availableHandlers; + private final Hash.Strategy strategy = ItemStackHashStrategy.comparingAllButCount(); /** * Used to lookup a list of slots for a given stack - * filled by {@link CraftingRecipeLogic#collectAvailableItems()} + * filled by {@link CraftingRecipeLogic#handleCacheMiss(ItemStack)} **/ - private final Object2ObjectOpenCustomHashMap> stackLookupMap = new Object2ObjectOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); + private final Map> stackLookupMap = new Object2ObjectOpenCustomHashMap<>(this.strategy); /** * List of items needed to complete the crafting recipe, filled by - * {@link CraftingRecipeLogic#getIngredientEquivalent(ItemStack, IntList)} )} + * {@link CraftingRecipeLogic#getIngredientEquivalent(CraftingInputSlot)} )} **/ private final Map requiredItems = new Object2IntOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); @@ -61,8 +63,7 @@ public class CraftingRecipeLogic extends SyncHandler { private final InventoryCrafting craftingMatrix; private final IInventory craftingResultInventory = new InventoryCraftResult(); private final CachedRecipeData cachedRecipeData; - public static short ALL_INGREDIENTS_PRESENT = 511; - private short presenceMatrix = ALL_INGREDIENTS_PRESENT; + private final CraftingInputSlot[] inputSlots = new CraftingInputSlot[9]; public CraftingRecipeLogic(World world, IItemHandlerModifiable handlers, IItemHandlerModifiable craftingMatrix) { this.world = world; @@ -93,163 +94,165 @@ public void fillCraftingGrid(Map ingredients) { } } + public void setInputSlot(CraftingInputSlot slot, int index) { + this.inputSlots[index] = slot; + } + /** * Attempts to match the crafting matrix against all available inventories * * @return 511 if all items matched */ - public short attemptMatchRecipe() { - short presenceMatrix = 511; - requiredItems.clear(); - for (var stack : compressMatrixToList(this.craftingMatrix).entrySet()) { - int notFound = stack.getValue().size() - getIngredientEquivalent(stack.getKey(), stack.getValue()); - for (int i = notFound - 1; i >= 0; i--) { - presenceMatrix -= (short) (1 << stack.getValue().get(i)); + public boolean attemptMatchRecipe() { + this.requiredItems.clear(); + boolean matched = true; + for (CraftingInputSlot slot : this.inputSlots) { + slot.hasIngredients = getIngredientEquivalent(slot); + if (!slot.hasIngredients) { + matched = false; + break; } } - return presenceMatrix; - } - - private Map compressMatrixToList(InventoryCrafting craftingMatrix) { - Map map = new Object2ObjectOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); - for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { - var stack = craftingMatrix.getStackInSlot(i).copy(); - if (stack.isEmpty()) continue; - IntList slots = map.computeIfAbsent(stack, s -> new IntArrayList()); - slots.add(i); - } - return map; + syncToClient(5, buffer -> { + for (CraftingInputSlot slot : this.inputSlots) { + buffer.writeBoolean(slot.hasIngredients); + } + }); + return matched; } /** * Searches all available inventories for an ingredient equivalent for a stack in the crafting matrix * - * @param currentStack stack to find a substitute for + * @param slot slot whose current stack to find a substitute for * @return number of slots for which a valid substitute exists */ - public int getIngredientEquivalent(ItemStack currentStack, IntList slots) { + public boolean getIngredientEquivalent(CraftingInputSlot slot) { + ItemStack currentStack = slot.getStack(); if (currentStack.isEmpty()) { - return slots.size(); // stack is empty, nothing to return + return true; // stack is empty, nothing to return } - if (simulateExtractItem(currentStack, slots.size()) == 0) { - return slots.size(); + if (simulateExtractItem(currentStack)) { + return true; } - var recipe = getCachedRecipe(); + Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot.getIndex(), + (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); - ItemStack previousStack = recipe.getCraftingResult(craftingMatrix); - int succeeded = 0; - for (int slot : slots) { - - Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot, - (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); - - // iterate stored items to find equivalent - for (var entry : stackLookupMap.entrySet()) { - for (int i : entry.getValue()) { - var itemStack = availableHandlers.getStackInSlot(i); - - boolean matchedPreviously = false; - if (map.containsKey(itemStack)) { - if (!map.get(itemStack)) { - continue; - } else { - // cant return here before checking if: - // The item is available for extraction - // The recipe output is still the same, as depending on the ingredient, the output NBT may - // change - matchedPreviously = true; - } - } + // iterate stored items to find equivalent + for (int i = 0; i < this.availableHandlers.getSlots(); i++) { + var itemStack = availableHandlers.getStackInSlot(i); + if (itemStack.isEmpty()) continue; - if (!matchedPreviously) { - boolean matched = false; - // Matching shapeless recipes actually is very bad for performance, as it checks the entire - // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can - // take the stack - for (Ingredient in : recipe.getIngredients()) { - if (in.apply(itemStack)) { - matched = true; - break; - } - } - if (!matched) { - map.put(itemStack.copy(), false); - continue; - } - } + var recipe = getCachedRecipe(); - // update item in slot, and check that recipe matches and output item is equal to the expected one - craftingMatrix.setInventorySlotContents(slot, itemStack); - if ((cachedRecipeData.matches(craftingMatrix, world) && - ItemStack.areItemStacksEqual(recipe.getCraftingResult(craftingMatrix), previousStack)) || - recipe instanceof ShapedOreEnergyTransferRecipe) { - map.put(itemStack, true); - // ingredient matched, attempt to extract it and return if successful - succeeded += slots.size() - simulateExtractItem(itemStack, slots.size()); - if (succeeded == slots.size()) { - return slots.size(); - } + boolean matchedPreviously = false; + if (map.containsKey(itemStack)) { + if (!map.get(itemStack)) { + continue; + } + // cant return here before checking if: + // The item is available for extraction + // The recipe output is still the same, as depending on + // the ingredient, the output NBT may change + matchedPreviously = true; + } + + if (!matchedPreviously) { + boolean matched = false; + // Matching shapeless recipes actually is very bad for performance, as it checks the entire + // recipe ingredients recursively, so we fail early here if none of the recipes ingredients can + // take the stack + for (Ingredient in : recipe.getIngredients()) { + if (in.apply(itemStack)) { + matched = true; + break; } - map.put(itemStack, false); - craftingMatrix.setInventorySlotContents(slot, currentStack); + } + if (!matched) { + map.put(itemStack.copy(), false); + continue; } } + + ItemStack previousResult = recipe.getCraftingResult(craftingMatrix); + + // update item in slot, and check that recipe matches and output item is equal to the expected one + craftingMatrix.setInventorySlotContents(slot.getIndex(), itemStack); + var newResult = recipe.getCraftingResult(craftingMatrix); + if ((cachedRecipeData.matches(craftingMatrix, world) && + ItemStack.areItemStacksEqual(newResult, previousResult)) || + recipe instanceof ShapedOreEnergyTransferRecipe) { + map.put(itemStack.copy(), true); + // ingredient matched, attempt to extract it and return if successful + if (simulateExtractItem(itemStack)) { + craftingMatrix.setInventorySlotContents(slot.getIndex(), currentStack); + return true; + } + } + map.put(itemStack.copy(), false); + craftingMatrix.setInventorySlotContents(slot.getIndex(), currentStack); } - return succeeded; + return false; } /** * Attempts to extract the given stack from connected inventories * * @param itemStack stack from the crafting matrix - * @param extract the amount to extract - * @return number of items yet to be extracted + * @return true if successfully extracted */ - private int simulateExtractItem(ItemStack itemStack, int extract) { - if (!stackLookupMap.containsKey(itemStack)) return extract; - int remaining = extract; - for (int slot : stackLookupMap.get(itemStack)) { - var slotStack = availableHandlers.extractItem(slot, remaining, true); - if (slotStack.getCount() <= remaining) { - remaining -= slotStack.getCount(); - if (remaining == 0) { - requiredItems.put(itemStack, extract); - return 0; + private boolean simulateExtractItem(ItemStack itemStack) { + if (stackLookupMap.containsKey(itemStack)) { + for (int slot : stackLookupMap.get(itemStack)) { + var slotStack = availableHandlers.extractItem(slot, 1, true); + if (slotStack.isEmpty() || !this.strategy.equals(slotStack, itemStack)) { + // cache is not correct + if (!handleCacheMiss(itemStack)) + return false; } + int count = requiredItems.getOrDefault(itemStack, 0); + requiredItems.put(itemStack, ++count); + return true; } } - return remaining; + // todo handle cache miss + if (handleCacheMiss(itemStack)) { + int count = requiredItems.getOrDefault(itemStack, 0); + requiredItems.put(itemStack, ++count); + return true; + } + return false; } public boolean performRecipe() { if (!isRecipeValid()) return false; - if (attemptMatchRecipe() != ALL_INGREDIENTS_PRESENT || !consumeRecipeItems()) { + if (!attemptMatchRecipe() || !consumeRecipeItems()) { return false; } - var cachedRecipe = cachedRecipeData.getRecipe(); - var player = getSyncManager().getPlayer(); - ForgeHooks.setCraftingPlayer(player); - // todo right here is where tools get damaged (in UI) - NonNullList remainingItems = cachedRecipe.getRemainingItems(craftingMatrix); - ForgeHooks.setCraftingPlayer(null); - for (ItemStack itemStack : remainingItems) { - if (itemStack.isEmpty()) { - continue; - } - - int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, true).getCount(); - if (remainingAmount > 0) { - itemStack.setCount(remainingAmount); - if (!player.addItemStackToInventory(itemStack)) { - player.dropItem(itemStack, false, false); - } - } - } + // todo is everything below actually necessary? +// var cachedRecipe = cachedRecipeData.getRecipe(); +// var player = getSyncManager().getPlayer(); +// ForgeHooks.setCraftingPlayer(player); +// // todo right here is where tools get damaged (in UI) +// NonNullList remainingItems = cachedRecipe.getRemainingItems(craftingMatrix); +// ForgeHooks.setCraftingPlayer(null); +// for (ItemStack itemStack : remainingItems) { +// if (itemStack.isEmpty()) { +// continue; +// } +// +// int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, true).getCount(); +// if (remainingAmount > 0) { +// itemStack.setCount(remainingAmount); +// if (!player.addItemStackToInventory(itemStack)) { +// player.dropItem(itemStack, false, false); +// } +// } +// } return true; } @@ -319,45 +322,74 @@ public IRecipe getCachedRecipe() { @Override public void detectAndSendChanges(boolean init) { - super.detectAndSendChanges(init); - this.collectAvailableItems(); - short newMatrix; - if (getCachedRecipeData().getRecipe() != null) { - newMatrix = attemptMatchRecipe(); - } else { - newMatrix = ALL_INGREDIENTS_PRESENT; + var recipe = getCachedRecipe(); + if (recipe == null) return; + + final Map map = new Int2BooleanArrayMap(); + for (CraftingInputSlot slot : this.inputSlots) { + final boolean old = slot.hasIngredients; + slot.hasIngredients = getIngredientEquivalent(slot); + if (old != slot.hasIngredients) + map.put(slot.getIndex(), slot.hasIngredients); } - if (init || newMatrix != this.presenceMatrix) { - this.presenceMatrix = newMatrix; + + if (!map.isEmpty()) { syncToClient(1, buffer -> { - buffer.writeShort(presenceMatrix); + buffer.writeByte(map.size()); + for (var set : map.entrySet()) { + buffer.writeByte(set.getKey()); + buffer.writeBoolean(set.getValue()); + } }); } } - public short getTintLocations() { - return (short) (ALL_INGREDIENTS_PRESENT - presenceMatrix); - } - - public CachedRecipeData getCachedRecipeData() { - return this.cachedRecipeData; - } + /** + * searches available handlers for the stack directly and + * adds the stack and slots the stack lookup map + * + * @param stack stack to check for in available handlers + * @return true if a suitable item was found + */ + public boolean handleCacheMiss(ItemStack stack) { + if (this.stackLookupMap.containsKey(stack)) { + ItemStack check; + List toRemove = new IntArrayList(); + List slots = this.stackLookupMap.get(stack); + for (int slot : slots) { + check = this.availableHandlers.getStackInSlot(slot); + if (!this.strategy.equals(stack, check)) { + toRemove.add(slot); + } + } + if (toRemove.size() == slots.size()) { + this.stackLookupMap.remove(stack); + } else { + toRemove.forEach(slots::remove); + } + } - public void collectAvailableItems() { - this.stackLookupMap.clear(); for (int i = 0; i < this.availableHandlers.getSlots(); i++) { - var stack = this.availableHandlers.getStackInSlot(i); - if (stack.isEmpty()) continue; - this.stackLookupMap - .computeIfAbsent(stack, k -> new IntArrayList()) - .add(i); + var curStack = this.availableHandlers.getStackInSlot(i); + if (curStack.isEmpty()) continue; + // container items like buckets or tools might need special behavior + if (this.strategy.equals(stack, curStack)) { + this.stackLookupMap + .computeIfAbsent(stack, k -> new IntArrayList()) + .add(i); + return true; + } } + return false; } @Override public void readOnClient(int id, PacketBuffer buf) { if (id == 1) { - this.presenceMatrix = buf.readShort(); + int size = buf.readByte(); + for (int i = 0; i < size; i++) { + this.inputSlots[buf.readByte()].hasIngredients = buf.readBoolean(); + } } if (id == 4) { getSyncManager().setCursorItem(readStackSafe(buf)); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index e2490fb19b3..a8f506077b9 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -237,6 +237,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .debugName("crafting page") .coverChildrenWidth() .child(new Row() + // todo add clear crafting grid button .debugName("crafting row") .coverChildrenHeight() .widthRel(1f) @@ -286,7 +287,7 @@ public IWidget createCraftingGrid() { .matrix("XXX", "XXX", "XXX") - .key('X', i -> new CraftingInputSlot(this.recipeLogic, this.craftingGrid, i) + .key('X', i -> CraftingInputSlot.create(this.recipeLogic, this.craftingGrid, i) .changeListener((newItem, onlyAmountChanged, client, init) -> { if (!init) { this.recipeLogic.updateCurrentRecipe(); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 48f6d485046..6d850d86294 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -1,7 +1,6 @@ package gregtech.common.mui.widget.workbench; import gregtech.client.utils.RenderUtil; - import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import net.minecraft.item.ItemStack; @@ -24,17 +23,15 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; -import java.util.function.Consumer; public class CraftingInputSlot extends Widget implements Interactable, JeiGhostIngredientSlot, JeiIngredientProvider { private final InputSyncHandler syncHandler; - private final CraftingRecipeLogic logic; + public boolean hasIngredients = true; - public CraftingInputSlot(CraftingRecipeLogic logic, IItemHandlerModifiable handler, int index) { - this.logic = logic; + public CraftingInputSlot(IItemHandlerModifiable handler, int index) { this.syncHandler = new InputSyncHandler(handler, index); setSyncHandler(this.syncHandler); tooltip().setAutoUpdate(true).setHasTitleMargin(true); @@ -47,6 +44,12 @@ public CraftingInputSlot(CraftingRecipeLogic logic, IItemHandlerModifiable handl }); } + public static CraftingInputSlot create(CraftingRecipeLogic logic, IItemHandlerModifiable handler, int index) { + var slot = new CraftingInputSlot(handler, index); + logic.setInputSlot(slot, index); + return slot; + } + @Override public void onInit() { getContext().getJeiSettings().addJeiGhostIngredientSlot(this); @@ -73,8 +76,7 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { ItemStack itemstack = this.syncHandler.getStack(); if (itemstack.isEmpty()) return; - int allTints = logic.getTintLocations(); - if ((allTints & 1 << this.syncHandler.index) != 0) { + if (!this.hasIngredients) { RenderUtil.renderRect(0, 0, 18, 18, 100, 0x80FF0000); } @@ -104,10 +106,22 @@ public void setGhostIngredient(@NotNull ItemStack ingredient) { } @Override - public @Nullable Object getIngredient() { + public @NotNull ItemStack getIngredient() { + return this.getStack(); + } + + public ItemStack getStack() { return syncHandler.getStack(); } + public int getIndex() { + return syncHandler.index; + } + + public void setStack(ItemStack stack) { + this.syncHandler.setStack(stack); + } + @SuppressWarnings("OverrideOnly") protected static class InputSyncHandler extends SyncHandler { @@ -190,6 +204,11 @@ public ItemStack getStack() { return this.handler.getStackInSlot(this.index); } + /** + * Sets the stack in this slot and calls the onChange listener. + * + * @param stack stack to put into this slot + */ public void setStack(ItemStack stack) { this.handler.setStackInSlot(this.index, stack); this.listener.onChange(stack, false, getSyncManager().isClient(), false); From 1abd515071a86939b0ebf46bd3b8c5e4b9e9b238 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 8 Jun 2024 19:47:42 -0700 Subject: [PATCH 095/147] even more work on recipe logic use set for stack lookup instead of list rearrange methods and add some javadocs fix slot highlighting from changes handle container items (drums, etc) correctly --- .../storage/CraftingRecipeLogic.java | 304 +++++++++--------- 1 file changed, 157 insertions(+), 147 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index cc3da57bde8..b6ad84ea4c5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -9,6 +9,8 @@ import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; import gregtech.common.mui.widget.workbench.CraftingInputSlot; +import it.unimi.dsi.fastutil.ints.IntArrayList; + import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; @@ -17,11 +19,7 @@ import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.Ingredient; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.NonNullList; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.value.sync.SyncHandler; @@ -29,7 +27,7 @@ import it.unimi.dsi.fastutil.ints.Int2BooleanArrayMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; -import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; @@ -39,6 +37,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; public class CraftingRecipeLogic extends SyncHandler { @@ -50,7 +49,7 @@ public class CraftingRecipeLogic extends SyncHandler { * Used to lookup a list of slots for a given stack * filled by {@link CraftingRecipeLogic#handleCacheMiss(ItemStack)} **/ - private final Map> stackLookupMap = new Object2ObjectOpenCustomHashMap<>(this.strategy); + private final Map> stackLookupMap = new Object2ObjectOpenCustomHashMap<>(this.strategy); /** * List of items needed to complete the crafting recipe, filled by @@ -98,34 +97,90 @@ public void setInputSlot(CraftingInputSlot slot, int index) { this.inputSlots[index] = slot; } + public boolean performRecipe() { + return isRecipeValid() && attemptMatchRecipe() && consumeRecipeItems(); + } + + public boolean isRecipeValid() { + return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(craftingMatrix, this.world); + } + /** - * Attempts to match the crafting matrix against all available inventories + * Attempts to match the crafting matrix against all connected inventories * - * @return 511 if all items matched + * @return true if all items matched */ public boolean attemptMatchRecipe() { this.requiredItems.clear(); - boolean matched = true; for (CraftingInputSlot slot : this.inputSlots) { slot.hasIngredients = getIngredientEquivalent(slot); if (!slot.hasIngredients) { - matched = false; - break; + return false; } } - syncToClient(5, buffer -> { - for (CraftingInputSlot slot : this.inputSlots) { - buffer.writeBoolean(slot.hasIngredients); + return true; + } + + protected boolean consumeRecipeItems() { + if (requiredItems.isEmpty()) { + return false; + } + Map gatheredItems = new Int2IntOpenHashMap(); + + for (var entry : requiredItems.entrySet()) { + ItemStack stack = entry.getKey(); + int requestedAmount = entry.getValue(); + var slotList = stackLookupMap.get(stack); + + int extractedAmount = 0; + for (int slot : slotList) { + var extracted = availableHandlers.extractItem(slot, requestedAmount, true); + gatheredItems.put(slot, extracted.getCount()); + extractedAmount += extracted.getCount(); + requestedAmount -= extracted.getCount(); + if (requestedAmount == 0) break; + } + if (extractedAmount < requestedAmount) return false; + } + + boolean extracted = false; + for (var gathered : gatheredItems.entrySet()) { + int slot = gathered.getKey(), amount = gathered.getValue(); + var stack = availableHandlers.getStackInSlot(slot); + + if (stack.isItemStackDamageable()) { + int damage = 1; + if (stack.getItem() instanceof IGTTool gtTool) { + damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); + } + stack.damageItem(damage, getSyncManager().getPlayer()); + } else if (stack.getItem().hasContainerItem(stack)) { + var useStack = stack.splitStack(1); + var newStack = useStack.getItem().getContainerItem(useStack); + if (newStack.isEmpty()) return false; + + GTTransferUtils.insertItem(this.availableHandlers, newStack, false); + } else { + availableHandlers.extractItem(slot, amount, false); } - }); - return matched; + extracted = true; + } + return extracted; } /** - * Searches all available inventories for an ingredient equivalent for a stack in the crafting matrix + *

+ * Searches all connected inventories for the slot's stack, and uses + * {@link CraftingRecipeLogic#findSubstitute(int, ItemStack)} to look for valid substitutes + *

+ *
+ *

+ * This method also fills out {@link CraftingRecipeLogic#requiredItems} for use in + * {@link CraftingRecipeLogic#consumeRecipeItems()} + *

* * @param slot slot whose current stack to find a substitute for - * @return number of slots for which a valid substitute exists + * @return true if the stack in the slot can be extracted or has a valid substitute */ public boolean getIngredientEquivalent(CraftingInputSlot slot) { ItemStack currentStack = slot.getStack(); @@ -133,13 +188,38 @@ public boolean getIngredientEquivalent(CraftingInputSlot slot) { return true; // stack is empty, nothing to return } - if (simulateExtractItem(currentStack)) { + int count = requiredItems.getOrDefault(currentStack, 0); + if (simulateExtractItem(currentStack, count + 1)) { + requiredItems.put(currentStack, ++count); return true; } - Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(slot.getIndex(), + ItemStack substitute = findSubstitute(slot.getIndex(), currentStack); + if (substitute.isEmpty()) return false; + + count = requiredItems.getOrDefault(substitute, 0); + if (simulateExtractItem(substitute, count + 1)) { + requiredItems.put(substitute, ++count); + return true; + } + return false; + } + + /** + *

+ * Searches through all connected inventories for a replacement stack that can be used in the recipe + *

+ * + * @param craftingIndex Index of the current crafting slot + * @param stack The stack to find a substitute for + * @return a valid replacement stack, or {@link ItemStack#EMPTY} if no valid replacements exist + */ + public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { + Object2BooleanMap map = replaceAttemptMap.computeIfAbsent(craftingIndex, (m) -> new Object2BooleanOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount())); + ItemStack substitute = ItemStack.EMPTY; + // iterate stored items to find equivalent for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var itemStack = availableHandlers.getStackInSlot(i); @@ -179,129 +259,53 @@ public boolean getIngredientEquivalent(CraftingInputSlot slot) { ItemStack previousResult = recipe.getCraftingResult(craftingMatrix); // update item in slot, and check that recipe matches and output item is equal to the expected one - craftingMatrix.setInventorySlotContents(slot.getIndex(), itemStack); + craftingMatrix.setInventorySlotContents(craftingIndex, itemStack); var newResult = recipe.getCraftingResult(craftingMatrix); if ((cachedRecipeData.matches(craftingMatrix, world) && ItemStack.areItemStacksEqual(newResult, previousResult)) || recipe instanceof ShapedOreEnergyTransferRecipe) { + // ingredient matched, return the substitute map.put(itemStack.copy(), true); - // ingredient matched, attempt to extract it and return if successful - if (simulateExtractItem(itemStack)) { - craftingMatrix.setInventorySlotContents(slot.getIndex(), currentStack); - return true; - } + substitute = itemStack; + break; } map.put(itemStack.copy(), false); - craftingMatrix.setInventorySlotContents(slot.getIndex(), currentStack); + craftingMatrix.setInventorySlotContents(craftingIndex, stack); } - return false; + return substitute; } /** * Attempts to extract the given stack from connected inventories * * @param itemStack stack from the crafting matrix - * @return true if successfully extracted + * @return true if the stack was successfully extracted or the stack is empty */ - private boolean simulateExtractItem(ItemStack itemStack) { - if (stackLookupMap.containsKey(itemStack)) { - for (int slot : stackLookupMap.get(itemStack)) { - var slotStack = availableHandlers.extractItem(slot, 1, true); - if (slotStack.isEmpty() || !this.strategy.equals(slotStack, itemStack)) { - // cache is not correct - if (!handleCacheMiss(itemStack)) - return false; - } - int count = requiredItems.getOrDefault(itemStack, 0); - requiredItems.put(itemStack, ++count); - return true; - } - } - // todo handle cache miss - if (handleCacheMiss(itemStack)) { - int count = requiredItems.getOrDefault(itemStack, 0); - requiredItems.put(itemStack, ++count); - return true; - } - return false; - } - - public boolean performRecipe() { - if (!isRecipeValid()) return false; - - if (!attemptMatchRecipe() || !consumeRecipeItems()) { - return false; - } - - // todo is everything below actually necessary? -// var cachedRecipe = cachedRecipeData.getRecipe(); -// var player = getSyncManager().getPlayer(); -// ForgeHooks.setCraftingPlayer(player); -// // todo right here is where tools get damaged (in UI) -// NonNullList remainingItems = cachedRecipe.getRemainingItems(craftingMatrix); -// ForgeHooks.setCraftingPlayer(null); -// for (ItemStack itemStack : remainingItems) { -// if (itemStack.isEmpty()) { -// continue; -// } -// -// int remainingAmount = GTTransferUtils.insertItem(this.availableHandlers, itemStack, true).getCount(); -// if (remainingAmount > 0) { -// itemStack.setCount(remainingAmount); -// if (!player.addItemStackToInventory(itemStack)) { -// player.dropItem(itemStack, false, false); -// } -// } -// } - return true; - } - - protected boolean consumeRecipeItems() { - if (requiredItems.isEmpty()) { - return false; - } - Map gatheredItems = new Int2IntOpenHashMap(); - - for (var entry : requiredItems.entrySet()) { - ItemStack stack = entry.getKey(); - int requestedAmount = entry.getValue(); - var slotList = stackLookupMap.get(stack); - - int extractedAmount = 0; - for (int slot : slotList) { - var extracted = availableHandlers.extractItem(slot, requestedAmount, true); - gatheredItems.put(slot, extracted.getCount()); - extractedAmount += extracted.getCount(); - requestedAmount -= extracted.getCount(); - if (requestedAmount == 0) break; - } - if (extractedAmount < requestedAmount) return false; - } - - boolean extracted = false; - for (var gathered : gatheredItems.entrySet()) { - int slot = gathered.getKey(), amount = gathered.getValue(); - var stack = availableHandlers.getStackInSlot(slot); - - if (stack.isItemStackDamageable()) { - int damage = 1; - if (stack.getItem() instanceof IGTTool gtTool) { - damage = gtTool.getToolStats().getDamagePerCraftingAction(stack); - } - stack.damageItem(damage, getSyncManager().getPlayer()); - } else if (stack.getItem().hasContainerItem(stack)) { - var newStack = stack.getItem().getContainerItem(stack); - availableHandlers.setStackInSlot(slot, newStack); + private boolean simulateExtractItem(ItemStack itemStack, int count) { + if (itemStack.isEmpty()) return true; + if (!stackLookupMap.containsKey(itemStack)) + return handleCacheMiss(itemStack); + int toExtract = count; + + Set slots = stackLookupMap.get(itemStack); + List toRemove = new IntArrayList(); + if (slots.isEmpty()) stackLookupMap.remove(itemStack); + + for (int slot : slots) { + var slotStack = availableHandlers.extractItem(slot, count, true); + // cache is not correct + if (slotStack.isEmpty() || !this.strategy.equals(slotStack, itemStack)) { + toRemove.add(slot); } else { - availableHandlers.extractItem(slot, amount, false); + toExtract -= slotStack.getCount(); + if (toExtract <= 0) return true; } - extracted = true; } - return extracted; - } - public boolean isRecipeValid() { - return cachedRecipeData.getRecipe() != null && cachedRecipeData.matches(craftingMatrix, this.world); + if (!toRemove.isEmpty()) + toRemove.forEach(slots::remove); + + return handleCacheMiss(itemStack); } public void updateCurrentRecipe() { @@ -325,14 +329,35 @@ public void detectAndSendChanges(boolean init) { var recipe = getCachedRecipe(); if (recipe == null) return; + requiredItems.clear(); final Map map = new Int2BooleanArrayMap(); for (CraftingInputSlot slot : this.inputSlots) { final boolean old = slot.hasIngredients; - slot.hasIngredients = getIngredientEquivalent(slot); + + // check if existing stack works + var slotStack = slot.getStack(); + if (slotStack.isEmpty()) { + slot.hasIngredients = true; + continue; + } + + int count = requiredItems.getOrDefault(slotStack, 0); + requiredItems.put(slotStack, ++count); + slot.hasIngredients = simulateExtractItem(slotStack, count); + + // check if substitute exists + if (!slot.hasIngredients) { + ItemStack substitute = findSubstitute(slot.getIndex(), slotStack); + count = requiredItems.getOrDefault(substitute, 0); + requiredItems.put(substitute, ++count); + slot.hasIngredients = !substitute.isEmpty() && simulateExtractItem(substitute, count); + } + if (old != slot.hasIngredients) map.put(slot.getIndex(), slot.hasIngredients); } + // only sync when something has changed if (!map.isEmpty()) { syncToClient(1, buffer -> { buffer.writeByte(map.size()); @@ -347,37 +372,21 @@ public void detectAndSendChanges(boolean init) { /** * searches available handlers for the stack directly and * adds the stack and slots the stack lookup map - * + * * @param stack stack to check for in available handlers * @return true if a suitable item was found */ public boolean handleCacheMiss(ItemStack stack) { - if (this.stackLookupMap.containsKey(stack)) { - ItemStack check; - List toRemove = new IntArrayList(); - List slots = this.stackLookupMap.get(stack); - for (int slot : slots) { - check = this.availableHandlers.getStackInSlot(slot); - if (!this.strategy.equals(stack, check)) { - toRemove.add(slot); - } - } - if (toRemove.size() == slots.size()) { - this.stackLookupMap.remove(stack); - } else { - toRemove.forEach(slots::remove); - } - } + if (stack.isEmpty()) return false; for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var curStack = this.availableHandlers.getStackInSlot(i); if (curStack.isEmpty()) continue; - // container items like buckets or tools might need special behavior + + var slots = this.stackLookupMap.computeIfAbsent(stack, k -> new IntArraySet()); + // container items like buckets or tools might need special behavior maybe? if (this.strategy.equals(stack, curStack)) { - this.stackLookupMap - .computeIfAbsent(stack, k -> new IntArrayList()) - .add(i); - return true; + if (slots.add(i)) return true; } } return false; @@ -435,6 +444,7 @@ private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { public static InventoryCrafting wrapHandler(IItemHandlerModifiable handler) { return new InventoryCrafting(new DummyContainer(), 3, 3) { + @Override public ItemStack getStackInRowAndColumn(int row, int column) { int index = row + (3 * column); From a9702b5c2c321bfe7a8366c249ff2c1babd56232 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 8 Jun 2024 20:41:55 -0700 Subject: [PATCH 096/147] update todo --- .../common/mui/widget/workbench/CraftingOutputSlot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 6b955dd305a..a5d8b4eff34 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -121,7 +121,7 @@ public void readOnServer(int id, PacketBuffer buf) { if (recipeLogic.performRecipe()) { handleItemCraft(this.slot.getStack(), getSyncManager().getPlayer()); if (data.shift) { - // todo handle shift transfer + // todo make shift transfer do more than one stack GTTransferUtils.insertItem(this.shiftclickslots, this.slot.getStack(), false); } else { syncToClient(5, this::syncCraftedStack); From f14f4c612243fab62f3379f9830ce4751509fdb8 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 8 Jun 2024 21:34:44 -0700 Subject: [PATCH 097/147] make sure to use copy --- .../metatileentities/storage/CraftingRecipeLogic.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index b6ad84ea4c5..c39b88a6311 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -342,14 +342,14 @@ public void detectAndSendChanges(boolean init) { } int count = requiredItems.getOrDefault(slotStack, 0); - requiredItems.put(slotStack, ++count); + requiredItems.put(slotStack.copy(), ++count); slot.hasIngredients = simulateExtractItem(slotStack, count); // check if substitute exists if (!slot.hasIngredients) { ItemStack substitute = findSubstitute(slot.getIndex(), slotStack); count = requiredItems.getOrDefault(substitute, 0); - requiredItems.put(substitute, ++count); + requiredItems.put(substitute.copy(), ++count); slot.hasIngredients = !substitute.isEmpty() && simulateExtractItem(substitute, count); } @@ -383,9 +383,9 @@ public boolean handleCacheMiss(ItemStack stack) { var curStack = this.availableHandlers.getStackInSlot(i); if (curStack.isEmpty()) continue; - var slots = this.stackLookupMap.computeIfAbsent(stack, k -> new IntArraySet()); - // container items like buckets or tools might need special behavior maybe? if (this.strategy.equals(stack, curStack)) { + // container items like buckets or tools might need special behavior maybe? + var slots = this.stackLookupMap.computeIfAbsent(stack, k -> new IntArraySet()); if (slots.add(i)) return true; } } From 2963bcd2e80b2bcc00a18a5938246a5574129d5a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 8 Jun 2024 21:36:17 -0700 Subject: [PATCH 098/147] try and fail at shift transfer --- .../widget/workbench/CraftingOutputSlot.java | 150 ++++++------------ 1 file changed, 48 insertions(+), 102 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index a5d8b4eff34..967a48af2a8 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -93,7 +93,7 @@ protected static class CraftingSlotSH extends SyncHandler { private final CraftingRecipeLogic recipeLogic; private final CraftingOutputMS slot; - private IItemHandlerModifiable shiftclickslots; + private final List shiftclickslots = new ArrayList<>(); public CraftingSlotSH(CraftingOutputMS slot) { this.slot = slot; @@ -101,15 +101,19 @@ public CraftingSlotSH(CraftingOutputMS slot) { } @Override - @SuppressWarnings("OverrideOnly") + @SuppressWarnings({ "OverrideOnly"}) public void init(String key, GuiSyncManager syncManager) { super.init(key, syncManager); - List list = new ArrayList<>(); getSyncManager().getSlotGroups().stream() + .filter(SlotGroup::allowShiftTransfer) .sorted(Comparator.comparingInt(SlotGroup::getShiftClickPriority)) .collect(Collectors.toList()) - .forEach(slotGroup -> list.addAll(slotGroup.getSlots())); - shiftclickslots = listToHandler(list); + .forEach(slotGroup -> slotGroup.getSlots() + .forEach(slot1 -> { + if (slot1 instanceof ModularSlot modularSlot) { + this.shiftclickslots.add(modularSlot); + } + })); } @Override @@ -119,108 +123,50 @@ public void readOnServer(int id, PacketBuffer buf) { if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { if (recipeLogic.performRecipe()) { - handleItemCraft(this.slot.getStack(), getSyncManager().getPlayer()); - if (data.shift) { - // todo make shift transfer do more than one stack - GTTransferUtils.insertItem(this.shiftclickslots, this.slot.getStack(), false); - } else { - syncToClient(5, this::syncCraftedStack); - } + ItemStack craftedStack = this.slot.getStack(); + handleItemCraft(craftedStack, getSyncManager().getPlayer()); + syncToClient(5, this::syncCraftedStack); + // todo make shift transfer do more than one stack and actually work +// if (data.shift) { +// List emptySlots = new ArrayList<>(); +// for (var slot : this.shiftclickslots) { +// +// ItemStack slotStack = slot.getStack().copy(); +// if (slotStack.isEmpty()) { +// emptySlots.add(slot); +// } else if (ItemHandlerHelper.canItemStacksStack(craftedStack, slotStack)) { +// if (!slot.isItemValid(craftedStack)) continue; +// +// int space = slot.getItemStackLimit(slotStack) - slotStack.getCount(); +// if (space == 0) continue; +// +// var split = craftedStack.splitStack(space); +// +// slotStack.setCount(split.getCount() + slotStack.getCount()); +// slot.putStack(slotStack); +// if (craftedStack.isEmpty()) +// return; +// } +// } +// +// for (var slot : emptySlots) { +// if (!slot.isItemValid(craftedStack)) continue; +// +// if (craftedStack.getCount() > slot.getSlotStackLimit()) { +// slot.putStack(craftedStack.splitStack(slot.getSlotStackLimit())); +// } else { +// slot.putStack(craftedStack.splitStack(craftedStack.getCount())); +// } +// if (craftedStack.isEmpty()) +// return; +// } +// } else { +// } } } } } - private static IItemHandlerModifiable listToHandler(List list) { - return new IItemHandlerModifiable() { - - @Override - public void setStackInSlot(int slot, ItemStack stack) { - list.get(slot).putStack(stack); - } - - @Override - public int getSlots() { - return list.size(); - } - - @Override - public ItemStack getStackInSlot(int slot) { - return list.get(slot).getStack(); - } - - @Override - public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { - if (stack.isEmpty()) - return ItemStack.EMPTY; - - var slot1 = list.get(slot); - ItemStack existing = slot1.getStack(); - - int limit = slot1.getItemStackLimit(stack); - - if (!existing.isEmpty()) { - if (!ItemHandlerHelper.canItemStacksStack(stack, existing)) - return stack; - - limit -= existing.getCount(); - } - - if (limit <= 0) - return stack; - - boolean reachedLimit = stack.getCount() > limit; - - if (!simulate) { - if (existing.isEmpty()) { - ItemStack s = reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, limit) : stack; - slot1.putStack(s); - } else { - existing.grow(reachedLimit ? limit : stack.getCount()); - slot1.putStack(existing); - } - } - - return reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - limit) : - ItemStack.EMPTY; - } - - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (amount == 0) - return ItemStack.EMPTY; - - var slot1 = list.get(slot); - ItemStack existing = slot1.getStack(); - - if (existing.isEmpty()) - return ItemStack.EMPTY; - - int toExtract = Math.min(amount, existing.getMaxStackSize()); - - if (existing.getCount() <= toExtract) { - if (!simulate) { - slot1.putStack(ItemStack.EMPTY); - } - return existing; - } else { - if (!simulate) { - ItemStack s = ItemHandlerHelper.copyStackWithSize(existing, - existing.getCount() - toExtract); - slot1.putStack(s); - } - - return ItemHandlerHelper.copyStackWithSize(existing, toExtract); - } - } - - @Override - public int getSlotLimit(int slot) { - return list.get(slot).getSlotStackLimit(); - } - }; - } - @Override public void readOnClient(int id, PacketBuffer buf) { if (id == 5) { From af7fc40cb47ab65101f4e44ba3bf721db9d769b1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:01:03 -0700 Subject: [PATCH 099/147] consume items correctly that why shift was broken --- .../storage/CraftingRecipeLogic.java | 11 ++- .../widget/workbench/CraftingOutputSlot.java | 93 +++++++++++-------- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index c39b88a6311..89299d61238 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -135,6 +135,11 @@ protected boolean consumeRecipeItems() { int extractedAmount = 0; for (int slot : slotList) { var extracted = availableHandlers.extractItem(slot, requestedAmount, true); + // i don't know if this is necessary + if (!this.strategy.equals(extracted, stack)) { + handleCacheMiss(stack); + continue; + } gatheredItems.put(slot, extracted.getCount()); extractedAmount += extracted.getCount(); requestedAmount -= extracted.getCount(); @@ -298,14 +303,14 @@ private boolean simulateExtractItem(ItemStack itemStack, int count) { toRemove.add(slot); } else { toExtract -= slotStack.getCount(); - if (toExtract <= 0) return true; + if (toExtract <= 0) break; } } if (!toRemove.isEmpty()) toRemove.forEach(slots::remove); - return handleCacheMiss(itemStack); + return toExtract <= 0 || handleCacheMiss(itemStack); } public void updateCurrentRecipe() { @@ -385,7 +390,7 @@ public boolean handleCacheMiss(ItemStack stack) { if (this.strategy.equals(stack, curStack)) { // container items like buckets or tools might need special behavior maybe? - var slots = this.stackLookupMap.computeIfAbsent(stack, k -> new IntArraySet()); + var slots = this.stackLookupMap.computeIfAbsent(stack.copy(), k -> new IntArraySet()); if (slots.add(i)) return true; } } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 967a48af2a8..af5090d4581 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,7 +1,6 @@ package gregtech.common.mui.widget.workbench; import gregtech.api.util.GTLog; -import gregtech.api.util.GTTransferUtils; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; @@ -9,7 +8,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.common.FMLCommonHandler; @@ -31,11 +29,13 @@ import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; public class CraftingOutputSlot extends Widget implements Interactable { @@ -93,7 +93,7 @@ protected static class CraftingSlotSH extends SyncHandler { private final CraftingRecipeLogic recipeLogic; private final CraftingOutputMS slot; - private final List shiftclickslots = new ArrayList<>(); + private final List shiftClickSlots = new ArrayList<>(); public CraftingSlotSH(CraftingOutputMS slot) { this.slot = slot; @@ -111,7 +111,7 @@ public void init(String key, GuiSyncManager syncManager) { .forEach(slotGroup -> slotGroup.getSlots() .forEach(slot1 -> { if (slot1 instanceof ModularSlot modularSlot) { - this.shiftclickslots.add(modularSlot); + this.shiftClickSlots.add(modularSlot); } })); } @@ -124,44 +124,55 @@ public void readOnServer(int id, PacketBuffer buf) { if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { if (recipeLogic.performRecipe()) { ItemStack craftedStack = this.slot.getStack(); + + if (data.shift) { + quickTransfer(craftedStack); + } else { + syncToClient(5, this::syncCraftedStack); + } handleItemCraft(craftedStack, getSyncManager().getPlayer()); - syncToClient(5, this::syncCraftedStack); - // todo make shift transfer do more than one stack and actually work -// if (data.shift) { -// List emptySlots = new ArrayList<>(); -// for (var slot : this.shiftclickslots) { -// -// ItemStack slotStack = slot.getStack().copy(); -// if (slotStack.isEmpty()) { -// emptySlots.add(slot); -// } else if (ItemHandlerHelper.canItemStacksStack(craftedStack, slotStack)) { -// if (!slot.isItemValid(craftedStack)) continue; -// -// int space = slot.getItemStackLimit(slotStack) - slotStack.getCount(); -// if (space == 0) continue; -// -// var split = craftedStack.splitStack(space); -// -// slotStack.setCount(split.getCount() + slotStack.getCount()); -// slot.putStack(slotStack); -// if (craftedStack.isEmpty()) -// return; -// } -// } -// -// for (var slot : emptySlots) { -// if (!slot.isItemValid(craftedStack)) continue; -// -// if (craftedStack.getCount() > slot.getSlotStackLimit()) { -// slot.putStack(craftedStack.splitStack(slot.getSlotStackLimit())); -// } else { -// slot.putStack(craftedStack.splitStack(craftedStack.getCount())); -// } -// if (craftedStack.isEmpty()) -// return; -// } -// } else { -// } + } + } + } + } + + public void quickTransfer(ItemStack fromStack) { + List emptySlots = new ArrayList<>(); + for (ModularSlot toSlot : this.shiftClickSlots) { + if (toSlot.isEnabled() && toSlot.isItemValid(fromStack)) { + ItemStack toStack = toSlot.getStack().copy(); + if (toStack.isEmpty()) emptySlots.add(toSlot); + + if (ItemHandlerHelper.canItemStacksStack(fromStack, toStack)) { + int j = toStack.getCount() + fromStack.getCount(); + int maxSize = Math.min(toSlot.getSlotStackLimit(), fromStack.getMaxStackSize()); + + if (j <= maxSize) { + fromStack.setCount(0); + toStack.setCount(j); + toSlot.putStack(toStack); + } else if (toStack.getCount() < maxSize) { + fromStack.shrink(maxSize - toStack.getCount()); + toStack.setCount(maxSize); + toSlot.putStack(toStack); + } + + if (fromStack.isEmpty()) { + return; + } + } + } + } + for (ModularSlot emptySlot : emptySlots) { + ItemStack itemstack = emptySlot.getStack(); + if (emptySlot.isEnabled() && itemstack.isEmpty() && emptySlot.isItemValid(fromStack)) { + if (fromStack.getCount() > emptySlot.getSlotStackLimit()) { + emptySlot.putStack(fromStack.splitStack(emptySlot.getSlotStackLimit())); + } else { + emptySlot.putStack(fromStack.splitStack(fromStack.getCount())); + } + if (fromStack.isEmpty()) { + return; } } } From d8a0adc77d8839ee2cac91055fc6d9b5701d7969 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:09:15 -0700 Subject: [PATCH 100/147] sbobless --- .../storage/CraftingRecipeLogic.java | 20 +++++++++++-------- .../widget/workbench/CraftingOutputSlot.java | 4 +--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 89299d61238..eb2a05c8ffe 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -9,8 +9,6 @@ import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; import gregtech.common.mui.widget.workbench.CraftingInputSlot; -import it.unimi.dsi.fastutil.ints.IntArrayList; - import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; @@ -27,6 +25,7 @@ import it.unimi.dsi.fastutil.ints.Int2BooleanArrayMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; @@ -113,8 +112,7 @@ public boolean isRecipeValid() { public boolean attemptMatchRecipe() { this.requiredItems.clear(); for (CraftingInputSlot slot : this.inputSlots) { - slot.hasIngredients = getIngredientEquivalent(slot); - if (!slot.hasIngredients) { + if (!getIngredientEquivalent(slot)) { return false; } } @@ -290,12 +288,16 @@ private boolean simulateExtractItem(ItemStack itemStack, int count) { if (itemStack.isEmpty()) return true; if (!stackLookupMap.containsKey(itemStack)) return handleCacheMiss(itemStack); - int toExtract = count; + if (stackLookupMap.get(itemStack).isEmpty()) { + stackLookupMap.remove(itemStack); + return handleCacheMiss(itemStack); + } + + int toExtract = count; Set slots = stackLookupMap.get(itemStack); - List toRemove = new IntArrayList(); - if (slots.isEmpty()) stackLookupMap.remove(itemStack); + List toRemove = new IntArrayList(); for (int slot : slots) { var slotStack = availableHandlers.extractItem(slot, count, true); // cache is not correct @@ -307,8 +309,10 @@ private boolean simulateExtractItem(ItemStack itemStack, int count) { } } - if (!toRemove.isEmpty()) + if (!toRemove.isEmpty()) { toRemove.forEach(slots::remove); + if (slots.isEmpty()) stackLookupMap.remove(itemStack); + } return toExtract <= 0 || handleCacheMiss(itemStack); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index af5090d4581..8280f386dfc 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -29,13 +29,11 @@ import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; public class CraftingOutputSlot extends Widget implements Interactable { @@ -101,7 +99,7 @@ public CraftingSlotSH(CraftingOutputMS slot) { } @Override - @SuppressWarnings({ "OverrideOnly"}) + @SuppressWarnings({ "OverrideOnly" }) public void init(String key, GuiSyncManager syncManager) { super.init(key, syncManager); getSyncManager().getSlotGroups().stream() From e27d6208dc3006033343789238d3c87a8404f7ee Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:28:25 -0700 Subject: [PATCH 101/147] small fixes --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index eb2a05c8ffe..74879978f26 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -226,7 +226,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { // iterate stored items to find equivalent for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var itemStack = availableHandlers.getStackInSlot(i); - if (itemStack.isEmpty()) continue; + if (itemStack.isEmpty() || this.strategy.equals(itemStack, stack)) continue; var recipe = getCachedRecipe(); @@ -268,6 +268,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { ItemStack.areItemStacksEqual(newResult, previousResult)) || recipe instanceof ShapedOreEnergyTransferRecipe) { // ingredient matched, return the substitute + craftingMatrix.setInventorySlotContents(craftingIndex, stack); map.put(itemStack.copy(), true); substitute = itemStack; break; From be88e55b840a82fd6e1a312c1bb431ff323831e1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:36:37 -0700 Subject: [PATCH 102/147] add jei support for output slot --- .../mui/widget/workbench/CraftingOutputSlot.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 8280f386dfc..f6ae213dde2 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,5 +1,7 @@ package gregtech.common.mui.widget.workbench; +import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; + import gregtech.api.util.GTLog; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; @@ -29,6 +31,7 @@ import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; @@ -36,7 +39,7 @@ import java.util.List; import java.util.stream.Collectors; -public class CraftingOutputSlot extends Widget implements Interactable { +public class CraftingOutputSlot extends Widget implements Interactable, JeiIngredientProvider { private final CraftingSlotSH syncHandler; @@ -86,6 +89,11 @@ public void drawForeground(GuiContext context) { } } + @Override + public @Nullable ItemStack getIngredient() { + return this.syncHandler.getOutputStack(); + } + protected static class CraftingSlotSH extends SyncHandler { private final CraftingRecipeLogic recipeLogic; @@ -139,7 +147,10 @@ public void quickTransfer(ItemStack fromStack) { for (ModularSlot toSlot : this.shiftClickSlots) { if (toSlot.isEnabled() && toSlot.isItemValid(fromStack)) { ItemStack toStack = toSlot.getStack().copy(); - if (toStack.isEmpty()) emptySlots.add(toSlot); + if (toStack.isEmpty()) { + emptySlots.add(toSlot); + continue; + } if (ItemHandlerHelper.canItemStacksStack(fromStack, toStack)) { int j = toStack.getCount() + fromStack.getCount(); From 0e6d154298c309ce45645644d5a021a4652299f9 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 12:43:08 -0700 Subject: [PATCH 103/147] remove comment --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 74879978f26..31ec2e3ea16 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -394,7 +394,6 @@ public boolean handleCacheMiss(ItemStack stack) { if (curStack.isEmpty()) continue; if (this.strategy.equals(stack, curStack)) { - // container items like buckets or tools might need special behavior maybe? var slots = this.stackLookupMap.computeIfAbsent(stack.copy(), k -> new IntArraySet()); if (slots.add(i)) return true; } From 94d092ceb8f58117bb3f85ca490797f45d304593 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 14:12:14 -0700 Subject: [PATCH 104/147] make strategy ignore tag --- .../metatileentities/storage/CraftingRecipeLogic.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 31ec2e3ea16..9fc990a98b1 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -42,7 +42,10 @@ public class CraftingRecipeLogic extends SyncHandler { private final World world; private IItemHandlerModifiable availableHandlers; - private final Hash.Strategy strategy = ItemStackHashStrategy.comparingAllButCount(); + private final Hash.Strategy strategy = ItemStackHashStrategy.builder() + .compareItem(true) + .compareDamage(true) + .build(); /** * Used to lookup a list of slots for a given stack @@ -55,7 +58,7 @@ public class CraftingRecipeLogic extends SyncHandler { * {@link CraftingRecipeLogic#getIngredientEquivalent(CraftingInputSlot)} )} **/ private final Map requiredItems = new Object2IntOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); + this.strategy); private final Map> replaceAttemptMap = new Int2ObjectArrayMap<>(); private final InventoryCrafting craftingMatrix; From c296eedcd2a2e2415b2f32d22b3623d280a2c28b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 14:21:27 -0700 Subject: [PATCH 105/147] remove the recipe on client --- .../common/mui/widget/workbench/RecipeMemorySlot.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index d262c0dd967..cd680359be6 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -81,6 +81,10 @@ public Result onMousePressed(int mouseButton) { recipe.setRecipeLocked(!recipe.isRecipeLocked()); } + if (!data.shift && data.mouseButton == 1) { + memory.removeRecipe(this.index); + } + return Result.ACCEPT; } } From e83f40a73d376449518106b0e341d07aa1c9c001 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:14:46 -0700 Subject: [PATCH 106/147] mostly fix recipe memory --- .../storage/CraftingRecipeMemory.java | 56 ++++++++++++------- .../widget/workbench/CraftingOutputSlot.java | 3 +- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 56c4631baf3..d2c5d402aeb 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -51,13 +51,9 @@ private MemorizedRecipe offsetRecipe(int startIndex) { for (int i = startIndex + 1; i < memorizedRecipes.length; i++) { MemorizedRecipe recipe = memorizedRecipes[i]; if (recipe != null && recipe.recipeLocked) continue; - memorizedRecipes[i] = previousRecipe; + memorizedRecipes[i] = previousRecipe.copy(); + memorizedRecipes[i].index = i; if (recipe == null) return null; - recipe.index = i; - syncToClient(3, buffer -> { - buffer.writeByte(recipe.index); - buffer.writeItemStack(recipe.recipeResult); - }); previousRecipe = recipe; } return previousRecipe; @@ -81,18 +77,14 @@ private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { continue; } else { memorizedRecipe = offsetRecipe(i); + final int startIndex = i; + syncToClient(5, buffer -> buffer.writeByte(startIndex)); if (memorizedRecipe == null) { memorizedRecipe = new MemorizedRecipe(i); } } memorizedRecipe.initialize(resultItemStack); - memorizedRecipes[i] = memorizedRecipe; - var sync = memorizedRecipes[i]; - syncToClient(3, buffer -> { - buffer.writeByte(sync.index); - buffer.writeItemStack(sync.recipeResult); - }); - return memorizedRecipe; + return memorizedRecipes[i] = memorizedRecipe; } return null; } @@ -103,7 +95,7 @@ public void notifyRecipePerformed(IItemHandler craftingGrid, ItemStack resultSta // notify slot and sync to client recipe.updateCraftingMatrix(craftingGrid); recipe.timesUsed++; - syncToClient(4, buffer -> buffer.writeByte(recipe.index)); + syncToClient(4, recipe::writeToBuffer); } } @@ -142,7 +134,6 @@ private static void copyInventoryItems(IItemHandler src, IItemHandlerModifiable public final void removeRecipe(int index) { if (hasRecipe(index)) { memorizedRecipes[index] = null; - syncToClient(4, buffer -> buffer.writeByte(index)); } } @@ -166,10 +157,16 @@ public void readOnClient(int id, PacketBuffer buf) { this.removeRecipe(buf.readByte()); } else if (id == 3) { int index = buf.readByte(); - if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(index); - memorizedRecipes[index].recipeResult = readStackSafe(buf); + var recipe = memorizedRecipes[index]; + if (recipe == null) recipe = new MemorizedRecipe(index); + recipe.recipeResult = readStackSafe(buf); + recipe.index = index; + memorizedRecipes[index] = recipe; } else if (id == 4) { - memorizedRecipes[buf.readByte()].timesUsed++; + var recipe = MemorizedRecipe.fromBuffer(buf); + memorizedRecipes[recipe.index] = recipe; + } else if (id == 5) { + this.offsetRecipe(buf.readByte()); } } @@ -222,7 +219,7 @@ public void readOnServer(int id, PacketBuffer buf) { } } - private ItemStack readStackSafe(PacketBuffer buffer) { + private static ItemStack readStackSafe(PacketBuffer buffer) { ItemStack ret = ItemStack.EMPTY; try { ret = buffer.readItemStack(); @@ -260,6 +257,19 @@ private static MemorizedRecipe deserializeNBT(NBTTagCompound tagCompound, int in return recipe; } + private void writeToBuffer(PacketBuffer buffer) { + buffer.writeByte(this.index); + buffer.writeInt(this.timesUsed); + buffer.writeItemStack(this.recipeResult); + } + + private static @NotNull MemorizedRecipe fromBuffer(PacketBuffer buffer) { + var recipe = new MemorizedRecipe(buffer.readByte()); + recipe.timesUsed = buffer.readInt(); + recipe.recipeResult = readStackSafe(buffer); + return recipe; + } + private void initialize(ItemStack recipeResult) { this.recipeResult = recipeResult.copy(); for (int i = 0; i < this.craftingMatrix.getSlots(); i++) { @@ -287,5 +297,13 @@ public boolean isRecipeLocked() { public void setRecipeLocked(boolean recipeLocked) { this.recipeLocked = recipeLocked; } + + public MemorizedRecipe copy() { + var recipe = new MemorizedRecipe(this.index); + recipe.initialize(this.recipeResult); + recipe.updateCraftingMatrix(this.craftingMatrix); + recipe.timesUsed = this.timesUsed; + return recipe; + } } } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index f6ae213dde2..7004e2df27d 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,7 +1,5 @@ package gregtech.common.mui.widget.workbench; -import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; - import gregtech.api.util.GTLog; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; @@ -18,6 +16,7 @@ import net.minecraftforge.items.ItemHandlerHelper; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; import com.cleanroommc.modularui.screen.GuiScreenWrapper; import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.screen.viewport.GuiContext; From 0dd724984097255ac5d69e00b69d3f737738fc88 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:28:58 -0700 Subject: [PATCH 107/147] add metadata to hash strategy --- .../api/util/ItemStackHashStrategy.java | 17 +++++++++++++++-- .../storage/CraftingRecipeLogic.java | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/util/ItemStackHashStrategy.java b/src/main/java/gregtech/api/util/ItemStackHashStrategy.java index fb68bc99112..405bcaf842e 100644 --- a/src/main/java/gregtech/api/util/ItemStackHashStrategy.java +++ b/src/main/java/gregtech/api/util/ItemStackHashStrategy.java @@ -58,7 +58,7 @@ static ItemStackHashStrategy comparingItemDamageCount() { */ class ItemStackHashStrategyBuilder { - private boolean item, count, damage, tag; + private boolean item, count, damage, tag, meta; /** * Defines whether the Item type should be considered for equality. @@ -93,6 +93,17 @@ public ItemStackHashStrategyBuilder compareDamage(boolean choice) { return this; } + /** + * Defines whether metadata values should be considered for equality. + * + * @param choice {@code true} to consider this property, {@code false} to ignore it. + * @return {@code this} + */ + public ItemStackHashStrategyBuilder compareMetadata(boolean choice) { + meta = choice; + return this; + } + /** * Defines whether NBT Tags should be considered for equality. * @@ -116,7 +127,8 @@ public int hashCode(@Nullable ItemStack o) { item ? o.getItem() : null, count ? o.getCount() : null, damage ? o.getItemDamage() : null, - tag ? o.getTagCompound() : null); + tag ? o.getTagCompound() : null, + meta ? o.getMetadata() : null); } @Override @@ -127,6 +139,7 @@ public boolean equals(@Nullable ItemStack a, @Nullable ItemStack b) { return (!item || a.getItem() == b.getItem()) && (!count || a.getCount() == b.getCount()) && (!damage || a.getItemDamage() == b.getItemDamage()) && + (!meta || a.getMetadata() == b.getMetadata()) && (!tag || Objects.equals(a.getTagCompound(), b.getTagCompound())); } }; diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 9fc990a98b1..6b8770bd61c 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -44,7 +44,7 @@ public class CraftingRecipeLogic extends SyncHandler { private IItemHandlerModifiable availableHandlers; private final Hash.Strategy strategy = ItemStackHashStrategy.builder() .compareItem(true) - .compareDamage(true) + .compareMetadata(true) .build(); /** From 2b5c151a9d74732a60718db38d51ca53b8bc9e04 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:12:37 -0700 Subject: [PATCH 108/147] minor fixes --- .../metatileentities/storage/CraftingRecipeLogic.java | 8 +++++--- .../metatileentities/storage/CraftingRecipeMemory.java | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 6b8770bd61c..436aa400381 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -361,9 +361,11 @@ public void detectAndSendChanges(boolean init) { // check if substitute exists if (!slot.hasIngredients) { ItemStack substitute = findSubstitute(slot.getIndex(), slotStack); - count = requiredItems.getOrDefault(substitute, 0); - requiredItems.put(substitute.copy(), ++count); - slot.hasIngredients = !substitute.isEmpty() && simulateExtractItem(substitute, count); + if (!substitute.isEmpty()) { + count = requiredItems.getOrDefault(substitute, 0); + requiredItems.put(substitute.copy(), ++count); + slot.hasIngredients = simulateExtractItem(substitute, count); + } } if (old != slot.hasIngredients) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index d2c5d402aeb..b0a051c644a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -51,9 +51,11 @@ private MemorizedRecipe offsetRecipe(int startIndex) { for (int i = startIndex + 1; i < memorizedRecipes.length; i++) { MemorizedRecipe recipe = memorizedRecipes[i]; if (recipe != null && recipe.recipeLocked) continue; - memorizedRecipes[i] = previousRecipe.copy(); + memorizedRecipes[i] = previousRecipe; memorizedRecipes[i].index = i; - if (recipe == null) return null; + if (recipe == null) + return memorizedRecipes[startIndex] = null; + previousRecipe = recipe; } return previousRecipe; From 26f2c74c0ec3de4b36ba34e0ab84bc45d818fb34 Mon Sep 17 00:00:00 2001 From: bruberu <80226372+bruberu@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:19:46 -0500 Subject: [PATCH 109/147] fix: all the bugs (#3) --- .../storage/CraftingRecipeLogic.java | 15 ++++++++------- .../storage/CraftingRecipeMemory.java | 2 ++ .../mui/widget/workbench/CraftingInputSlot.java | 12 +++++------- .../mui/widget/workbench/RecipeMemorySlot.java | 6 +++++- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 436aa400381..bb955cc854e 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -235,14 +235,13 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { boolean matchedPreviously = false; if (map.containsKey(itemStack)) { - if (!map.get(itemStack)) { - continue; + if (map.get(itemStack)) { + // cant return here before checking if: + // The item is available for extraction + // The recipe output is still the same, as depending on + // the ingredient, the output NBT may change + matchedPreviously = true; } - // cant return here before checking if: - // The item is available for extraction - // The recipe output is still the same, as depending on - // the ingredient, the output NBT may change - matchedPreviously = true; } if (!matchedPreviously) { @@ -351,6 +350,7 @@ public void detectAndSendChanges(boolean init) { var slotStack = slot.getStack(); if (slotStack.isEmpty()) { slot.hasIngredients = true; + map.put(slot.getIndex(), slot.hasIngredients); continue; } @@ -427,6 +427,7 @@ public void readOnServer(int id, PacketBuffer buf) { try { this.craftingMatrix.setInventorySlotContents(i, buf.readItemStack()); } catch (IOException ignore) {} + this.updateCurrentRecipe(); } } else if (id == 4) { int slot = buf.readVarInt(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index b0a051c644a..99850950e45 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -185,6 +185,7 @@ public void writeRecipes(PacketBuffer buf) { buf.writeByte(recipe.index); buf.writeItemStack(recipe.recipeResult); buf.writeInt(recipe.timesUsed); + buf.writeBoolean(recipe.isRecipeLocked()); } } @@ -197,6 +198,7 @@ public void readRecipes(PacketBuffer buf) { memorizedRecipes[index].recipeResult = readStackSafe(buf); memorizedRecipes[index].timesUsed = buf.readInt(); + memorizedRecipes[index].recipeLocked = buf.readBoolean(); } } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 6d850d86294..0d9249944ba 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -76,15 +76,13 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { ItemStack itemstack = this.syncHandler.getStack(); if (itemstack.isEmpty()) return; - if (!this.hasIngredients) { - RenderUtil.renderRect(0, 0, 18, 18, 100, 0x80FF0000); - } - - guiScreen.setZ(100f); - guiScreen.getItemRenderer().zLevel = 100f; - RenderUtil.renderItemInGUI(itemstack, 1, 1); guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); + RenderUtil.renderItemInGUI(itemstack, 1, 1); + + if (!this.hasIngredients) { + RenderUtil.renderRect(0, 0, 18, 18, 200, 0x80FF0000); + } } @Override diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index cd680359be6..41fc7ec1124 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -4,6 +4,7 @@ import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.item.ItemStack; import com.cleanroommc.modularui.api.drawable.IKey; @@ -49,8 +50,11 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { RenderUtil.renderItemInGUI(itemstack, 1, 1); itemstack.setCount(cachedCount); - if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) + if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) { + GlStateManager.disableDepth(); GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme); + GlStateManager.enableDepth(); + } guiScreen.getItemRenderer().zLevel = 0.0F; guiScreen.setZ(0f); From 67f0cb404c61d688bf2d3447ed6c23b0057dd0ec Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 20 Jul 2024 10:39:47 -0700 Subject: [PATCH 110/147] fix rebase --- .../api/mui/GregTechGuiTransferHandler.java | 9 +++++++-- .../storage/MetaTileEntityWorkbench.java | 14 +++++++------- .../mui/widget/workbench/CraftingInputSlot.java | 5 ++--- .../mui/widget/workbench/CraftingOutputSlot.java | 5 ++--- .../mui/widget/workbench/RecipeMemorySlot.java | 1 - 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 37d5fccba8d..1bf1792a491 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -1,14 +1,18 @@ package gregtech.api.mui; +import com.cleanroommc.modularui.screen.ModularScreen; + import gregtech.common.metatileentities.storage.CraftingRecipeLogic; +import mezz.jei.transfer.RecipeTransferErrorInternal; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import com.cleanroommc.modularui.screen.ModularContainer; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; @@ -33,8 +37,9 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { @Override public @Nullable IRecipeTransferError transferRecipe(ModularContainer container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer) { + String key = PanelSyncManager.makeSyncKey("recipe_logic", 0); CraftingRecipeLogic recipeLogic = (CraftingRecipeLogic) container.getSyncManager() - .getSyncHandler(GuiSyncManager.makeSyncKey("recipe_logic", 0)); + .getSyncHandler("workbench", key); if (!doTransfer) { // todo highlighting in JEI? diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index a8f506077b9..61d64dcda4d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -44,7 +44,7 @@ import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; @@ -201,7 +201,7 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); guiSyncManager.syncValue("recipe_logic", this.recipeLogic); @@ -256,7 +256,7 @@ public ModularPanel buildUI(PosGuiData guiData, GuiSyncManager guiSyncManager) { .bindPlayerInventory(); } - public IWidget createToolInventory(GuiSyncManager syncManager) { + public IWidget createToolInventory(PanelSyncManager syncManager) { var toolSlots = new SlotGroup("tool_slots", 9, -120, true); syncManager.registerSlotGroup(toolSlots); @@ -269,7 +269,7 @@ public IWidget createToolInventory(GuiSyncManager syncManager) { .build().marginTop(2); } - public IWidget createInternalInventory(GuiSyncManager syncManager) { + public IWidget createInternalInventory(PanelSyncManager syncManager) { var inventory = new SlotGroup("internal_slots", 9, -100, true); syncManager.registerSlotGroup(inventory); @@ -297,7 +297,7 @@ public IWidget createCraftingGrid() { .build(); } - public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManager) { + public IWidget createCraftingOutput(PosGuiData guiData, PanelSyncManager syncManager) { var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); syncManager.syncValue("amount_crafted", amountCrafted); amountCrafted.updateCacheFromSource(true); @@ -313,7 +313,7 @@ public IWidget createCraftingOutput(PosGuiData guiData, GuiSyncManager syncManag .asWidget().widthRel(1f)); } - public IWidget createRecipeMemoryGrid(GuiSyncManager syncManager) { + public IWidget createRecipeMemoryGrid(PanelSyncManager syncManager) { return SlotGroupWidget.builder() .matrix("XXX", "XXX", @@ -323,7 +323,7 @@ public IWidget createRecipeMemoryGrid(GuiSyncManager syncManager) { .build().right(0); } - public IWidget createInventoryPage(GuiSyncManager syncManager) { + public IWidget createInventoryPage(PanelSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 8, true); syncManager.registerSlotGroup(connected); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 0d9249944ba..391eba14d62 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -15,7 +15,7 @@ import com.cleanroommc.modularui.screen.Tooltip; import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.slot.IOnSlotChanged; @@ -36,7 +36,6 @@ public CraftingInputSlot(IItemHandlerModifiable handler, int index) { setSyncHandler(this.syncHandler); tooltip().setAutoUpdate(true).setHasTitleMargin(true); tooltipBuilder(tooltip -> { - tooltip.excludeArea(getArea()); if (!isSynced()) return; ItemStack stack = this.syncHandler.getStack(); if (stack.isEmpty()) return; @@ -135,7 +134,7 @@ public InputSyncHandler(IItemHandlerModifiable handler, int index) { } @Override - public void init(String key, GuiSyncManager syncHandler) { + public void init(String key, PanelSyncManager syncHandler) { super.init(key, syncHandler); this.lastStoredItem = this.handler.getStackInSlot(this.index).copy(); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 7004e2df27d..7e4baff730d 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -22,7 +22,7 @@ import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; @@ -50,7 +50,6 @@ public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbe setSyncHandler(this.syncHandler); tooltip().setAutoUpdate(true).setHasTitleMargin(true); tooltipBuilder(tooltip -> { - tooltip.excludeArea(getArea()); if (!isSynced()) return; ItemStack stack = this.syncHandler.getOutputStack(); if (stack.isEmpty()) return; @@ -107,7 +106,7 @@ public CraftingSlotSH(CraftingOutputMS slot) { @Override @SuppressWarnings({ "OverrideOnly" }) - public void init(String key, GuiSyncManager syncManager) { + public void init(String key, PanelSyncManager syncManager) { super.init(key, syncManager); getSyncManager().getSlotGroups().stream() .filter(SlotGroup::allowShiftTransfer) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 41fc7ec1124..df0b13ff585 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -27,7 +27,6 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.index = index; tooltip().setAutoUpdate(true).setHasTitleMargin(true); tooltipBuilder(tooltip -> { - tooltip.excludeArea(getArea()); var recipe = memory.getRecipeAtIndex(this.index); if (recipe == null) return; var list = getScreen().getScreenWrapper().getItemToolTip(recipe.getRecipeResult()); From 9123ddd2fce87ace9bc8a13390b9b409175932cd Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 20 Jul 2024 12:12:42 -0700 Subject: [PATCH 111/147] sootless --- .../java/gregtech/api/mui/GregTechGuiTransferHandler.java | 4 ---- .../metatileentities/storage/MetaTileEntityWorkbench.java | 2 +- .../common/mui/widget/workbench/CraftingOutputSlot.java | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 1bf1792a491..0d36ddeedf2 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -1,11 +1,7 @@ package gregtech.api.mui; -import com.cleanroommc.modularui.screen.ModularScreen; - import gregtech.common.metatileentities.storage.CraftingRecipeLogic; -import mezz.jei.transfer.RecipeTransferErrorInternal; - import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 61d64dcda4d..97df3910952 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -44,8 +44,8 @@ import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; -import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; import com.cleanroommc.modularui.widgets.ItemSlot; diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 7e4baff730d..5993c72b6ad 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -22,8 +22,8 @@ import com.cleanroommc.modularui.screen.viewport.GuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.slot.ModularSlot; From 3e10b99fb74cf605c827e47130db1f370e9b9082 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 24 Aug 2024 23:53:29 -0700 Subject: [PATCH 112/147] epic rebase + spotless --- .../common/metatileentities/storage/MetaTileEntityWorkbench.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 97df3910952..eaa254ad757 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -26,7 +26,6 @@ import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; From 0a7d0dc96ce8f898c882daf8d3196c1690c528e7 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 25 Aug 2024 00:12:58 -0700 Subject: [PATCH 113/147] improve recipe logic slightly --- .../storage/CraftingRecipeLogic.java | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index bb955cc854e..fa05a6cd174 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -33,10 +33,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class CraftingRecipeLogic extends SyncHandler { @@ -289,35 +286,29 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { */ private boolean simulateExtractItem(ItemStack itemStack, int count) { if (itemStack.isEmpty()) return true; - if (!stackLookupMap.containsKey(itemStack)) - return handleCacheMiss(itemStack); - - if (stackLookupMap.get(itemStack).isEmpty()) { - stackLookupMap.remove(itemStack); - return handleCacheMiss(itemStack); + if (!stackLookupMap.containsKey(itemStack)) { + if (handleCacheMiss(itemStack) == -1) + return false; } - int toExtract = count; - Set slots = stackLookupMap.get(itemStack); + int extracted = 0; - List toRemove = new IntArrayList(); - for (int slot : slots) { + Iterator slotItr = stackLookupMap.get(itemStack).iterator(); + while (slotItr.hasNext()) { + int slot = slotItr.next(); var slotStack = availableHandlers.extractItem(slot, count, true); // cache is not correct if (slotStack.isEmpty() || !this.strategy.equals(slotStack, itemStack)) { - toRemove.add(slot); - } else { - toExtract -= slotStack.getCount(); - if (toExtract <= 0) break; + slotItr.remove(); + slot = handleCacheMiss(itemStack); + if (slot == -1) return false; + slotStack = availableHandlers.getStackInSlot(slot); } + extracted += slotStack.getCount(); + if (extracted >= count) return true; } - if (!toRemove.isEmpty()) { - toRemove.forEach(slots::remove); - if (slots.isEmpty()) stackLookupMap.remove(itemStack); - } - - return toExtract <= 0 || handleCacheMiss(itemStack); + return false; } public void updateCurrentRecipe() { @@ -389,21 +380,26 @@ public void detectAndSendChanges(boolean init) { * adds the stack and slots the stack lookup map * * @param stack stack to check for in available handlers - * @return true if a suitable item was found + * @return the slot index containing the desired stack, -1 if the stack was not found */ - public boolean handleCacheMiss(ItemStack stack) { - if (stack.isEmpty()) return false; + public int handleCacheMiss(ItemStack stack) { + if (stack.isEmpty()) return -1; for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var curStack = this.availableHandlers.getStackInSlot(i); if (curStack.isEmpty()) continue; if (this.strategy.equals(stack, curStack)) { - var slots = this.stackLookupMap.computeIfAbsent(stack.copy(), k -> new IntArraySet()); - if (slots.add(i)) return true; + Set slots; + if (stackLookupMap.containsKey(stack)) + slots = stackLookupMap.get(stack); + else { + stackLookupMap.put(stack.copy(), slots = new IntArraySet()); + } + if (slots.add(i)) return i; } } - return false; + return -1; } @Override From bb6fdbc0fe21f5bc7c0052617f39fbf25926e270 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 27 Aug 2024 19:16:46 -0700 Subject: [PATCH 114/147] a few more optimizations --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index fa05a6cd174..91293e09fa6 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -286,7 +286,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { */ private boolean simulateExtractItem(ItemStack itemStack, int count) { if (itemStack.isEmpty()) return true; - if (!stackLookupMap.containsKey(itemStack)) { + if (!stackLookupMap.containsKey(itemStack) || stackLookupMap.get(itemStack).isEmpty()) { if (handleCacheMiss(itemStack) == -1) return false; } @@ -339,7 +339,7 @@ public void detectAndSendChanges(boolean init) { // check if existing stack works var slotStack = slot.getStack(); - if (slotStack.isEmpty()) { + if (slotStack.isEmpty() && !old) { slot.hasIngredients = true; map.put(slot.getIndex(), slot.hasIngredients); continue; From 73f8bb4b941c6c34fb4fb85985f03ee2fca7601f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 27 Aug 2024 19:19:18 -0700 Subject: [PATCH 115/147] spblss --- .../common/metatileentities/storage/CraftingRecipeLogic.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 91293e09fa6..c99a824bf54 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -25,7 +25,6 @@ import it.unimi.dsi.fastutil.ints.Int2BooleanArrayMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; -import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; From 55b29c86f5b99502e1a1a0f109f365364439430f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:23:47 -0700 Subject: [PATCH 116/147] allow cache miss to set any stack it comes across, instead of just the one we want --- .../storage/CraftingRecipeLogic.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index c99a824bf54..457b2e421f3 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -388,14 +388,16 @@ public int handleCacheMiss(ItemStack stack) { var curStack = this.availableHandlers.getStackInSlot(i); if (curStack.isEmpty()) continue; + Set slots; + if (stackLookupMap.containsKey(stack)) + slots = stackLookupMap.get(stack); + else { + stackLookupMap.put(stack.copy(), slots = new IntArraySet()); + } + slots.add(i); + if (this.strategy.equals(stack, curStack)) { - Set slots; - if (stackLookupMap.containsKey(stack)) - slots = stackLookupMap.get(stack); - else { - stackLookupMap.put(stack.copy(), slots = new IntArraySet()); - } - if (slots.add(i)) return i; + return i; } } return -1; From 0e20b058b80bb869dfa5d38c508ff2dd62e38877 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:31:08 -0700 Subject: [PATCH 117/147] remove stack key if int set is empty --- .../metatileentities/storage/CraftingRecipeLogic.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 457b2e421f3..a21721b472b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -299,6 +299,7 @@ private boolean simulateExtractItem(ItemStack itemStack, int count) { // cache is not correct if (slotStack.isEmpty() || !this.strategy.equals(slotStack, itemStack)) { slotItr.remove(); + if (!slotItr.hasNext()) stackLookupMap.remove(itemStack); slot = handleCacheMiss(itemStack); if (slot == -1) return false; slotStack = availableHandlers.getStackInSlot(slot); @@ -389,10 +390,10 @@ public int handleCacheMiss(ItemStack stack) { if (curStack.isEmpty()) continue; Set slots; - if (stackLookupMap.containsKey(stack)) - slots = stackLookupMap.get(stack); - else { - stackLookupMap.put(stack.copy(), slots = new IntArraySet()); + if (stackLookupMap.containsKey(curStack)) { + slots = stackLookupMap.get(curStack); + } else { + stackLookupMap.put(curStack.copy(), slots = new IntArraySet()); } slots.add(i); From 3548eaf319e16e7516ecacd9b0fc7b062cbf00a5 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:46:27 -0700 Subject: [PATCH 118/147] fix rebase --- .../storage/MetaTileEntityWorkbench.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index eaa254ad757..19a462608fe 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -52,8 +52,8 @@ import com.cleanroommc.modularui.widgets.PagedWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; -import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.slot.SlotGroup; import com.google.common.base.Preconditions; import org.apache.commons.lang3.ArrayUtils; @@ -209,7 +209,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) var controller = new PagedWidget.Controller(); return GTGuis.createPanel(this, 176, 224) - .child(new Row() + .child(Flow.row() .debugName("tab row") .widthRel(1f) .leftRel(0.5f) @@ -232,10 +232,10 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .controller(controller) .coverChildrenHeight() // workstation page - .addPage(new Column() + .addPage(Flow.column() .debugName("crafting page") .coverChildrenWidth() - .child(new Row() + .child(Flow.row() // todo add clear crafting grid button .debugName("crafting row") .coverChildrenHeight() @@ -301,7 +301,7 @@ public IWidget createCraftingOutput(PosGuiData guiData, PanelSyncManager syncMan syncManager.syncValue("amount_crafted", amountCrafted); amountCrafted.updateCacheFromSource(true); - return new Column() + return Flow.column() .size(54) .child(new CraftingOutputSlot(amountCrafted, this) .marginTop(18) @@ -347,10 +347,10 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { .setEnabledIf(checkSlotValid) .slot(SyncHandlers.itemSlot(this.connectedInventory, i) .slotGroup(connected)); - widget.setEnabled(checkSlotValid.test(widget)); + // widget.setEnabled(checkSlotValid.test(widget)); list.add(widget); } - return new Column() + return Flow.column() .debugName("inventory page") .padding(2) .leftRel(0.5f) From 64fec77055017eeb2efd65f03aae32b853b31549 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 9 Jan 2025 19:08:28 -0700 Subject: [PATCH 119/147] fix crafting widgets --- .../widget/workbench/CraftingInputSlot.java | 29 ++++++++++------- .../widget/workbench/CraftingOutputSlot.java | 32 +++++++++++-------- .../widget/workbench/RecipeMemorySlot.java | 27 ++++++++-------- 3 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 391eba14d62..86cdbb5569b 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -11,9 +11,8 @@ import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; -import com.cleanroommc.modularui.screen.GuiScreenWrapper; -import com.cleanroommc.modularui.screen.Tooltip; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandler; @@ -34,12 +33,14 @@ public class CraftingInputSlot extends Widget implements Int public CraftingInputSlot(IItemHandlerModifiable handler, int index) { this.syncHandler = new InputSyncHandler(handler, index); setSyncHandler(this.syncHandler); - tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltip().setAutoUpdate(true); + // .setHasTitleMargin(true); tooltipBuilder(tooltip -> { if (!isSynced()) return; ItemStack stack = this.syncHandler.getStack(); if (stack.isEmpty()) return; - tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); + tooltip.addFromItem(stack); + // tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); }); } @@ -49,6 +50,11 @@ public static CraftingInputSlot create(CraftingRecipeLogic logic, IItemHandlerMo return slot; } + @Override + public boolean isValidSyncHandler(SyncHandler syncHandler) { + return syncHandler instanceof InputSyncHandler; + } + @Override public void onInit() { getContext().getJeiSettings().addJeiGhostIngredientSlot(this); @@ -70,13 +76,12 @@ public Result onMousePressed(int mouseButton) { } @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { - GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { + // GuiScreen guiScreen = getScreen().getScreenWrapper().getGuiScreen(); ItemStack itemstack = this.syncHandler.getStack(); if (itemstack.isEmpty()) return; - - guiScreen.getItemRenderer().zLevel = 0.0F; - guiScreen.setZ(0f); + // guiScreen.getItemRenderer().zLevel = 0.0F; + // guiScreen.setZ(0f); RenderUtil.renderItemInGUI(itemstack, 1, 1); if (!this.hasIngredients) { @@ -85,8 +90,8 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { } @Override - public void drawForeground(GuiContext context) { - Tooltip tooltip = getTooltip(); + public void drawForeground(ModularGuiContext context) { + RichTooltip tooltip = getTooltip(); if (tooltip != null && isHoveringFor(tooltip.getShowUpTimer())) { tooltip.draw(getContext(), this.syncHandler.getStack()); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 5993c72b6ad..89684e662ba 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -17,9 +17,8 @@ import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; -import com.cleanroommc.modularui.screen.GuiScreenWrapper; -import com.cleanroommc.modularui.screen.Tooltip; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.IntSyncValue; @@ -48,15 +47,22 @@ public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbe workbench.getCraftingRecipeLogic().getCraftingResultInventory(), syncValue, workbench)); setSyncHandler(this.syncHandler); - tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltip().setAutoUpdate(true); + // .setHasTitleMargin(true); tooltipBuilder(tooltip -> { if (!isSynced()) return; ItemStack stack = this.syncHandler.getOutputStack(); if (stack.isEmpty()) return; - tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); + tooltip.addFromItem(stack); + // tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); }); } + @Override + public boolean isValidSyncHandler(SyncHandler syncHandler) { + return syncHandler instanceof CraftingSlotSH; + } + @Override public @NotNull Result onMousePressed(int mouseButton) { MouseData mouseData = MouseData.create(mouseButton); @@ -65,23 +71,23 @@ public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbe } @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { - GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { + // GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); ItemStack itemstack = this.syncHandler.getOutputStack(); if (itemstack.isEmpty()) return; - guiScreen.setZ(100f); - guiScreen.getItemRenderer().zLevel = 100.0F; + // guiScreen.setZ(100f); + // guiScreen.getItemRenderer().zLevel = 100.0F; RenderUtil.renderItemInGUI(itemstack, 1, 1); - guiScreen.getItemRenderer().zLevel = 0.0F; - guiScreen.setZ(0f); + // guiScreen.getItemRenderer().zLevel = 0.0F; + // guiScreen.setZ(0f); } @Override - public void drawForeground(GuiContext context) { - Tooltip tooltip = getTooltip(); + public void drawForeground(ModularGuiContext context) { + RichTooltip tooltip = getTooltip(); if (tooltip != null && isHoveringFor(tooltip.getShowUpTimer())) { tooltip.draw(getContext(), this.syncHandler.getOutputStack()); } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index df0b13ff585..2c7754a37ba 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -7,11 +7,11 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.item.ItemStack; +import com.cleanroommc.modularui.api.MCHelper; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; -import com.cleanroommc.modularui.screen.GuiScreenWrapper; -import com.cleanroommc.modularui.screen.Tooltip; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.widget.Widget; @@ -25,24 +25,25 @@ public class RecipeMemorySlot extends Widget implements Intera public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.memory = memory; this.index = index; - tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltip().setAutoUpdate(true); + // .setHasTitleMargin(true); tooltipBuilder(tooltip -> { var recipe = memory.getRecipeAtIndex(this.index); if (recipe == null) return; - var list = getScreen().getScreenWrapper().getItemToolTip(recipe.getRecipeResult()); + var list = MCHelper.getItemToolTip(recipe.getRecipeResult()); list.add(1, IKey.lang("Times Used: " + recipe.timesUsed).get()); tooltip.addStringLines(list); }); } @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { - GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { + // GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); ItemStack itemstack = this.memory.getRecipeOutputAtIndex(this.index); if (itemstack.isEmpty()) return; - guiScreen.setZ(100f); - guiScreen.getItemRenderer().zLevel = 100.0F; + // guiScreen.setZ(100f); + // guiScreen.getItemRenderer().zLevel = 100.0F; int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay @@ -55,13 +56,13 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { GlStateManager.enableDepth(); } - guiScreen.getItemRenderer().zLevel = 0.0F; - guiScreen.setZ(0f); + // guiScreen.getItemRenderer().zLevel = 0.0F; + // guiScreen.setZ(0f); } @Override - public void drawForeground(GuiContext context) { - Tooltip tooltip = getTooltip(); + public void drawForeground(ModularGuiContext context) { + RichTooltip tooltip = getTooltip(); if (tooltip != null && isHoveringFor(tooltip.getShowUpTimer())) { tooltip.draw(getContext(), this.memory.getRecipeOutputAtIndex(this.index)); } From 35aed6eedc347d2542dc7ae60baf9acd379be28c Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 10 Jan 2025 13:12:32 -0700 Subject: [PATCH 120/147] missed a column --- .../metatileentities/storage/MetaTileEntityWorkbench.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 19a462608fe..e529e875b6f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -51,7 +51,6 @@ import com.cleanroommc.modularui.widgets.PageButton; import com.cleanroommc.modularui.widgets.PagedWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; -import com.cleanroommc.modularui.widgets.layout.Column; import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; import com.cleanroommc.modularui.widgets.slot.SlotGroup; @@ -299,7 +298,7 @@ public IWidget createCraftingGrid() { public IWidget createCraftingOutput(PosGuiData guiData, PanelSyncManager syncManager) { var amountCrafted = new IntSyncValue(this::getItemsCrafted, this::setItemsCrafted); syncManager.syncValue("amount_crafted", amountCrafted); - amountCrafted.updateCacheFromSource(true); + amountCrafted.updateCacheFromSource(true); // todo remove return Flow.column() .size(54) @@ -333,7 +332,7 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { }; if (this.connectedInventory.getSlots() == 0) { - return new Column() + return Flow.column() .debugName("inventory page - empty") .leftRel(0.5f) .padding(2) From 88c249229cb27e1ad58752c204d9059703c49bde Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 19 Jan 2025 22:35:47 -0700 Subject: [PATCH 121/147] use mui2 methods to draw item cleanup --- .../java/gregtech/client/utils/RenderUtil.java | 15 --------------- .../mui/widget/workbench/CraftingInputSlot.java | 10 ++++++---- .../mui/widget/workbench/CraftingOutputSlot.java | 11 ++--------- .../mui/widget/workbench/RecipeMemorySlot.java | 13 +++---------- 4 files changed, 11 insertions(+), 38 deletions(-) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index 6c6328b3eac..f38d5cee0d4 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -384,21 +384,6 @@ public static void renderItemOverLay(float x, float y, float z, float scale, Ite net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); } - public static void renderItemInGUI(ItemStack stack, int x, int y, @Nullable String text) { - RenderHelper.enableGUIStandardItemLighting(); - GlStateManager.pushMatrix(); - RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); - renderItem.renderItemAndEffectIntoGUI(stack, x, y); - renderItem.renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRenderer, stack, x, y, text); - GlStateManager.popMatrix(); - RenderHelper.enableStandardItemLighting(); - GlStateManager.disableLighting(); - } - - public static void renderItemInGUI(ItemStack stack, int x, int y) { - renderItemInGUI(stack, x, y, null); - } - public static void renderFluidOverLay(float x, float y, float width, float height, float z, FluidStack fluidStack, float alpha) { if (fluidStack != null) { diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 86cdbb5569b..1a7cfaae12e 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -8,7 +8,9 @@ import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; +import com.cleanroommc.modularui.api.MCHelper; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; import com.cleanroommc.modularui.screen.RichTooltip; @@ -77,16 +79,16 @@ public Result onMousePressed(int mouseButton) { @Override public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { - // GuiScreen guiScreen = getScreen().getScreenWrapper().getGuiScreen(); ItemStack itemstack = this.syncHandler.getStack(); if (itemstack.isEmpty()) return; - // guiScreen.getItemRenderer().zLevel = 0.0F; - // guiScreen.setZ(0f); - RenderUtil.renderItemInGUI(itemstack, 1, 1); if (!this.hasIngredients) { RenderUtil.renderRect(0, 0, 18, 18, 200, 0x80FF0000); } + + GuiDraw.drawItem(itemstack, 1, 1, 16, 16); + var renderer = MCHelper.getMc().getRenderItem(); + renderer.renderItemOverlayIntoGUI(MCHelper.getFontRenderer(), itemstack, 1, 1, null); } @Override diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 89684e662ba..3c4bae63e5a 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,7 +1,6 @@ package gregtech.common.mui.widget.workbench; import gregtech.api.util.GTLog; -import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; @@ -16,6 +15,7 @@ import net.minecraftforge.items.ItemHandlerHelper; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; @@ -72,17 +72,10 @@ public boolean isValidSyncHandler(SyncHandler syncHandler) { @Override public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { - // GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); ItemStack itemstack = this.syncHandler.getOutputStack(); if (itemstack.isEmpty()) return; - // guiScreen.setZ(100f); - // guiScreen.getItemRenderer().zLevel = 100.0F; - - RenderUtil.renderItemInGUI(itemstack, 1, 1); - - // guiScreen.getItemRenderer().zLevel = 0.0F; - // guiScreen.setZ(0f); + GuiDraw.drawItem(itemstack, 1, 1, 16, 16); } @Override diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 2c7754a37ba..04d08daef06 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -1,7 +1,6 @@ package gregtech.common.mui.widget.workbench; import gregtech.api.mui.GTGuiTextures; -import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import net.minecraft.client.renderer.GlStateManager; @@ -10,6 +9,7 @@ import com.cleanroommc.modularui.api.MCHelper; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; @@ -26,11 +26,11 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.memory = memory; this.index = index; tooltip().setAutoUpdate(true); - // .setHasTitleMargin(true); tooltipBuilder(tooltip -> { var recipe = memory.getRecipeAtIndex(this.index); if (recipe == null) return; var list = MCHelper.getItemToolTip(recipe.getRecipeResult()); + // todo lang list.add(1, IKey.lang("Times Used: " + recipe.timesUsed).get()); tooltip.addStringLines(list); }); @@ -38,16 +38,12 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { @Override public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { - // GuiScreenWrapper guiScreen = getScreen().getScreenWrapper(); ItemStack itemstack = this.memory.getRecipeOutputAtIndex(this.index); if (itemstack.isEmpty()) return; - // guiScreen.setZ(100f); - // guiScreen.getItemRenderer().zLevel = 100.0F; - int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay - RenderUtil.renderItemInGUI(itemstack, 1, 1); + GuiDraw.drawItem(itemstack, 1, 1, 16, 16); itemstack.setCount(cachedCount); if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) { @@ -55,9 +51,6 @@ public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme); GlStateManager.enableDepth(); } - - // guiScreen.getItemRenderer().zLevel = 0.0F; - // guiScreen.setZ(0f); } @Override From e217b2935ed6522fba689ff41ab02cbfff4122dc Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Mon, 20 Jan 2025 12:06:49 -0700 Subject: [PATCH 122/147] remove unneeded method cleanup + clarify variables --- .../storage/CraftingRecipeMemory.java | 20 +++------- .../widget/workbench/CraftingInputSlot.java | 38 ++++++++----------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 99850950e45..aa28bcbea22 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -9,13 +9,13 @@ import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; +import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.SyncHandler; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; import java.util.Map; public class CraftingRecipeMemory extends SyncHandler { @@ -161,7 +161,7 @@ public void readOnClient(int id, PacketBuffer buf) { int index = buf.readByte(); var recipe = memorizedRecipes[index]; if (recipe == null) recipe = new MemorizedRecipe(index); - recipe.recipeResult = readStackSafe(buf); + recipe.recipeResult = NetworkUtils.readItemStack(buf); recipe.index = index; memorizedRecipes[index] = recipe; } else if (id == 4) { @@ -183,7 +183,7 @@ public void writeRecipes(PacketBuffer buf) { for (var entry : written.entrySet()) { var recipe = memorizedRecipes[entry.getKey()]; buf.writeByte(recipe.index); - buf.writeItemStack(recipe.recipeResult); + NetworkUtils.writeItemStack(buf, recipe.recipeResult); buf.writeInt(recipe.timesUsed); buf.writeBoolean(recipe.isRecipeLocked()); } @@ -196,7 +196,7 @@ public void readRecipes(PacketBuffer buf) { if (!hasRecipe(index)) memorizedRecipes[index] = new MemorizedRecipe(index); - memorizedRecipes[index].recipeResult = readStackSafe(buf); + memorizedRecipes[index].recipeResult = NetworkUtils.readItemStack(buf); memorizedRecipes[index].timesUsed = buf.readInt(); memorizedRecipes[index].recipeLocked = buf.readBoolean(); } @@ -223,14 +223,6 @@ public void readOnServer(int id, PacketBuffer buf) { } } - private static ItemStack readStackSafe(PacketBuffer buffer) { - ItemStack ret = ItemStack.EMPTY; - try { - ret = buffer.readItemStack(); - } catch (IOException ignored) {} - return ret; - } - public static class MemorizedRecipe { private final ItemStackHandler craftingMatrix = new ItemStackHandler(9); @@ -264,13 +256,13 @@ private static MemorizedRecipe deserializeNBT(NBTTagCompound tagCompound, int in private void writeToBuffer(PacketBuffer buffer) { buffer.writeByte(this.index); buffer.writeInt(this.timesUsed); - buffer.writeItemStack(this.recipeResult); + NetworkUtils.writeItemStack(buffer, this.recipeResult); } private static @NotNull MemorizedRecipe fromBuffer(PacketBuffer buffer) { var recipe = new MemorizedRecipe(buffer.readByte()); recipe.timesUsed = buffer.readInt(); - recipe.recipeResult = readStackSafe(buffer); + recipe.recipeResult = NetworkUtils.readItemStack(buffer); return recipe; } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 1a7cfaae12e..2bb498b6588 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -1,5 +1,6 @@ package gregtech.common.mui.widget.workbench; +import gregtech.api.util.GTUtility; import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; @@ -13,6 +14,7 @@ import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; +import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; @@ -23,8 +25,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; - public class CraftingInputSlot extends Widget implements Interactable, JeiGhostIngredientSlot, JeiIngredientProvider { @@ -149,21 +149,22 @@ public void init(String key, PanelSyncManager syncHandler) { @Override public void readOnClient(int id, PacketBuffer buf) { if (id == 1) { - boolean c = buf.readBoolean(); - var s = readStackSafe(buf); - boolean i = buf.readBoolean(); - this.handler.setStackInSlot(this.index, s); - this.listener.onChange(s, c, true, i); + boolean onlyAmt = buf.readBoolean(); + var stack = NetworkUtils.readItemStack(buf); + boolean init = buf.readBoolean(); + + this.handler.setStackInSlot(this.index, stack); + this.listener.onChange(stack, onlyAmt, true, init); } } @Override public void readOnServer(int id, PacketBuffer buf) { if (id == 1) { - var b = buf.readBoolean(); - var s = readStackSafe(buf); - this.handler.setStackInSlot(this.index, s); - this.listener.onChange(s, b, false, false); + var onlyAmt = buf.readBoolean(); + var stack = NetworkUtils.readItemStack(buf); + this.handler.setStackInSlot(this.index, stack); + this.listener.onChange(stack, onlyAmt, false, false); } } @@ -184,15 +185,14 @@ public void detectAndSendChanges(boolean init) { final boolean finalOnlyAmountChanged = onlyAmountChanged; syncToClient(1, buffer -> { buffer.writeBoolean(finalOnlyAmountChanged); - buffer.writeItemStack(itemStack); + NetworkUtils.writeItemStack(buffer, itemStack); buffer.writeBoolean(init); }); } } public void syncStack() { - final var cursorStack = getSyncManager().getCursorItem().copy(); - cursorStack.setCount(1); + final var cursorStack = GTUtility.copy(1, getSyncManager().getCursorItem()); final var curStack = getStack(); final boolean onlyAmt = ItemHandlerHelper.canItemStacksStackRelaxed(curStack, cursorStack); @@ -200,7 +200,7 @@ public void syncStack() { this.listener.onChange(cursorStack, onlyAmt, true, false); syncToServer(1, buffer -> { buffer.writeBoolean(onlyAmt); - buffer.writeItemStack(cursorStack); + NetworkUtils.writeItemStack(buffer, cursorStack); }); } @@ -217,13 +217,5 @@ public void setStack(ItemStack stack) { this.handler.setStackInSlot(this.index, stack); this.listener.onChange(stack, false, getSyncManager().isClient(), false); } - - private ItemStack readStackSafe(PacketBuffer buffer) { - ItemStack ret = ItemStack.EMPTY; - try { - ret = buffer.readItemStack(); - } catch (IOException ignored) {} - return ret; - } } } From c06c1d84dbdd057f26c11378014daa9d6ababfa1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 14:53:09 -0700 Subject: [PATCH 123/147] add todo lang add missing tooltips --- .../mui/widget/workbench/RecipeMemorySlot.java | 17 +++++++++++++---- .../resources/assets/gregtech/lang/en_us.lang | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 04d08daef06..a400124a635 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -1,5 +1,7 @@ package gregtech.common.mui.widget.workbench; +import com.cleanroommc.modularui.drawable.text.Spacer; + import gregtech.api.mui.GTGuiTextures; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; @@ -15,6 +17,9 @@ import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.widget.Widget; + +import net.minecraft.util.text.TextFormatting; + import org.jetbrains.annotations.NotNull; public class RecipeMemorySlot extends Widget implements Interactable { @@ -29,10 +34,14 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { tooltipBuilder(tooltip -> { var recipe = memory.getRecipeAtIndex(this.index); if (recipe == null) return; - var list = MCHelper.getItemToolTip(recipe.getRecipeResult()); - // todo lang - list.add(1, IKey.lang("Times Used: " + recipe.timesUsed).get()); - tooltip.addStringLines(list); + + tooltip.addFromItem(recipe.getRecipeResult()); + + tooltip.spaceLine(2); + tooltip.addLine(IKey.lang("gregtech.recipe_memory_widget.tooltip.1")); + tooltip.addLine(IKey.lang("gregtech.recipe_memory_widget.tooltip.2")); + tooltip.addLine(IKey.lang("gregtech.recipe_memory_widget.tooltip.0", recipe.timesUsed) + .format(TextFormatting.WHITE)); }); } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index eef80763ada..fcecbe83d21 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1210,6 +1210,7 @@ metaitem.blacklight.tooltip=Long-Wave ยงdUltravioletยง7 light source gui.widget.incrementButton.default_tooltip=Hold Shift, Ctrl or both to change the amount gui.widget.recipeProgressWidget.default_tooltip=Show Recipes +gregtech.recipe_memory_widget.tooltip.0=Times used: %d gregtech.recipe_memory_widget.tooltip.1=ยง7Left click to automatically input this recipe into the crafting grid gregtech.recipe_memory_widget.tooltip.2=ยง7Shift click to lock/unlock this recipe From c8960c89a4c8e63a7c9ecd2aa24233923fbba3c1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 14:58:38 -0700 Subject: [PATCH 124/147] cleanup CraftingOutputSlot --- .../widget/workbench/CraftingOutputSlot.java | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 3c4bae63e5a..a5aee5ad315 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,12 +1,12 @@ package gregtech.common.mui.widget.workbench; -import gregtech.api.util.GTLog; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.common.FMLCommonHandler; @@ -17,6 +17,7 @@ import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; +import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; @@ -31,7 +32,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -39,6 +39,8 @@ public class CraftingOutputSlot extends Widget implements Interactable, JeiIngredientProvider { + private static final int MOUSE_CLICK = 2; + private static final int SYNC_STACK = 5; private final CraftingSlotSH syncHandler; public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { @@ -47,14 +49,12 @@ public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbe workbench.getCraftingRecipeLogic().getCraftingResultInventory(), syncValue, workbench)); setSyncHandler(this.syncHandler); - tooltip().setAutoUpdate(true); - // .setHasTitleMargin(true); + tooltipAutoUpdate(true); tooltipBuilder(tooltip -> { if (!isSynced()) return; ItemStack stack = this.syncHandler.getOutputStack(); if (stack.isEmpty()) return; tooltip.addFromItem(stack); - // tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); }); } @@ -66,7 +66,7 @@ public boolean isValidSyncHandler(SyncHandler syncHandler) { @Override public @NotNull Result onMousePressed(int mouseButton) { MouseData mouseData = MouseData.create(mouseButton); - this.syncHandler.syncToServer(2, mouseData::writeToPacket); + this.syncHandler.syncToServer(MOUSE_CLICK, mouseData::writeToPacket); return Result.SUCCESS; } @@ -104,24 +104,24 @@ public CraftingSlotSH(CraftingOutputMS slot) { } @Override - @SuppressWarnings({ "OverrideOnly" }) public void init(String key, PanelSyncManager syncManager) { super.init(key, syncManager); getSyncManager().getSlotGroups().stream() .filter(SlotGroup::allowShiftTransfer) .sorted(Comparator.comparingInt(SlotGroup::getShiftClickPriority)) .collect(Collectors.toList()) - .forEach(slotGroup -> slotGroup.getSlots() - .forEach(slot1 -> { - if (slot1 instanceof ModularSlot modularSlot) { - this.shiftClickSlots.add(modularSlot); - } - })); + .forEach(slotGroup -> { + for (Slot slot : slotGroup.getSlots()) { + if (slot instanceof ModularSlot modularSlot) { + this.shiftClickSlots.add(modularSlot); + } + } + }); } @Override public void readOnServer(int id, PacketBuffer buf) { - if (id == 2) { + if (id == MOUSE_CLICK) { var data = MouseData.readPacket(buf); if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { @@ -131,7 +131,7 @@ public void readOnServer(int id, PacketBuffer buf) { if (data.shift) { quickTransfer(craftedStack); } else { - syncToClient(5, this::syncCraftedStack); + syncToClient(SYNC_STACK, this::syncCraftedStack); } handleItemCraft(craftedStack, getSyncManager().getPlayer()); } @@ -186,21 +186,11 @@ public void quickTransfer(ItemStack fromStack) { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == 5) { - getSyncManager().setCursorItem(readStackSafe(buf)); + if (id == SYNC_STACK) { + getSyncManager().setCursorItem(NetworkUtils.readItemStack(buf)); } } - private static ItemStack readStackSafe(PacketBuffer buffer) { - var stack = ItemStack.EMPTY; - try { - stack = buffer.readItemStack(); - } catch (IOException ignore) { - GTLog.logger.warn("A stack was read incorrectly, something is seriously wrong!"); - } - return stack; - } - private void syncCraftedStack(PacketBuffer buf) { ItemStack curStack = getSyncManager().getCursorItem(); ItemStack outStack = this.slot.getStack(); @@ -218,7 +208,7 @@ private void syncCraftedStack(PacketBuffer buf) { } else if (!curStack.isEmpty()) { toSync = curStack; } - buf.writeItemStack(toSync); + NetworkUtils.writeItemStack(buf, toSync); } public ItemStack getOutputStack() { From f42df8c8eb01b23df377fa48e161f5f71ce2c382 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:09:59 -0700 Subject: [PATCH 125/147] spotless --- .../common/mui/widget/workbench/RecipeMemorySlot.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index a400124a635..259cafd83e3 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -1,14 +1,12 @@ package gregtech.common.mui.widget.workbench; -import com.cleanroommc.modularui.drawable.text.Spacer; - import gregtech.api.mui.GTGuiTextures; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.item.ItemStack; +import net.minecraft.util.text.TextFormatting; -import com.cleanroommc.modularui.api.MCHelper; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiDraw; @@ -17,9 +15,6 @@ import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.widget.Widget; - -import net.minecraft.util.text.TextFormatting; - import org.jetbrains.annotations.NotNull; public class RecipeMemorySlot extends Widget implements Interactable { From a3ee25f968201ab8013b21a769b27af220ed4128 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:13:01 -0700 Subject: [PATCH 126/147] remove workbench from JEI module --- .../gregtech/integration/jei/JustEnoughItemsModule.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index d7c1be8b2de..6f78022e1f7 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -12,7 +12,6 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.modules.GregTechModule; -import gregtech.api.mui.GregTechGuiTransferHandler; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.category.GTRecipeCategory; @@ -154,7 +153,6 @@ public void register(IModRegistry registry) { // register transfer handler for all categories, but not for the crafting station ModularUIGuiHandler modularUIGuiHandler = new ModularUIGuiHandler(jeiHelpers.recipeTransferHandlerHelper()); - // modularUIGuiHandler.setValidHandlers(widget -> !(widget instanceof CraftingSlotWidget)); modularUIGuiHandler.blacklistCategory( IntCircuitCategory.UID, GTValues.MODID + ":material_tree", @@ -165,13 +163,6 @@ public void register(IModRegistry registry) { registry.addAdvancedGuiHandlers(modularUIGuiHandler); registry.addGhostIngredientHandler(modularUIGuiHandler.getGuiContainerClass(), modularUIGuiHandler); - // register transfer handler for crafting recipes - ModularUIGuiHandler craftingStationGuiHandler = new ModularUIGuiHandler( - jeiHelpers.recipeTransferHandlerHelper()); - registry.getRecipeTransferRegistry().addRecipeTransferHandler(craftingStationGuiHandler, - VanillaRecipeCategoryUid.CRAFTING); - registry.getRecipeTransferRegistry().addRecipeTransferHandler(new GregTechGuiTransferHandler( - jeiHelpers.recipeTransferHandlerHelper()), VanillaRecipeCategoryUid.CRAFTING); for (RecipeMap recipeMap : RecipeMap.getRecipeMaps()) { if (recipeMap.getRecipeMapUI().isJEIVisible()) { From 58328de392bbcf7784f217f45dea9facb4b66af6 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:14:42 -0700 Subject: [PATCH 127/147] remove unneeded override --- .../common/inventory/handlers/SingleItemStackHandler.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java b/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java index 88410d15faa..541b241d308 100644 --- a/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java +++ b/src/main/java/gregtech/common/inventory/handlers/SingleItemStackHandler.java @@ -18,9 +18,4 @@ public SingleItemStackHandler(ItemStack itemStack) { public int getSlotLimit(int slot) { return 1; } - - @Override - protected int getStackLimit(int slot, ItemStack stack) { - return getSlotLimit(slot); - } } From f1b262d98f92a62c90bf4dff74fe232e360ffc32 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:41:52 -0700 Subject: [PATCH 128/147] name internal ids use networkutils methods --- .../api/mui/GregTechGuiTransferHandler.java | 5 +- .../storage/CraftingRecipeLogic.java | 51 ++++++------------- .../storage/CraftingRecipeMemory.java | 32 ++++++++---- .../widget/workbench/CraftingInputSlot.java | 12 ++--- 4 files changed, 45 insertions(+), 55 deletions(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 0d36ddeedf2..7aefce9a7ae 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -7,6 +7,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; +import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.ModularContainer; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import mezz.jei.api.gui.IRecipeLayout; @@ -50,7 +51,7 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { this.craftingMatrix.setInventorySlotContents(i, ing == null ? ItemStack.EMPTY : ing); } - recipeLogic.syncToServer(0, this::writeCraftingMatrix); + recipeLogic.syncToServer(CraftingRecipeLogic.UPDATE_MATRIX, this::writeCraftingMatrix); recipeLogic.updateCurrentRecipe(); return null; } @@ -59,7 +60,7 @@ private void writeCraftingMatrix(PacketBuffer buffer) { buffer.writeVarInt(this.craftingMatrix.getSizeInventory()); for (int i = 0; i < this.craftingMatrix.getSizeInventory(); i++) { var stack = this.craftingMatrix.getStackInSlot(i); - buffer.writeItemStack(stack); + NetworkUtils.writeItemStack(buffer, stack); } } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index a21721b472b..16341febfa5 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -2,7 +2,6 @@ import gregtech.api.items.toolitem.IGTTool; import gregtech.api.util.DummyContainer; -import gregtech.api.util.GTLog; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.ItemStackHashStrategy; @@ -20,6 +19,7 @@ import net.minecraft.world.World; import net.minecraftforge.items.IItemHandlerModifiable; +import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.value.sync.SyncHandler; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.Int2BooleanArrayMap; @@ -31,11 +31,17 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; -import java.io.IOException; import java.util.*; public class CraftingRecipeLogic extends SyncHandler { + // client only + public static final int UPDATE_INGREDIENTS = 1; + public static final int SYNC_STACK = 4; + + // server only + public static final int UPDATE_MATRIX = 0; + private final World world; private IItemHandlerModifiable availableHandlers; private final Hash.Strategy strategy = ItemStackHashStrategy.builder() @@ -365,7 +371,7 @@ public void detectAndSendChanges(boolean init) { // only sync when something has changed if (!map.isEmpty()) { - syncToClient(1, buffer -> { + syncToClient(UPDATE_INGREDIENTS, buffer -> { buffer.writeByte(map.size()); for (var set : map.entrySet()) { buffer.writeByte(set.getKey()); @@ -406,53 +412,26 @@ public int handleCacheMiss(ItemStack stack) { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == 1) { + if (id == UPDATE_INGREDIENTS) { int size = buf.readByte(); for (int i = 0; i < size; i++) { this.inputSlots[buf.readByte()].hasIngredients = buf.readBoolean(); } } - if (id == 4) { - getSyncManager().setCursorItem(readStackSafe(buf)); + if (id == SYNC_STACK) { + getSyncManager().setCursorItem(NetworkUtils.readItemStack(buf)); } } @Override public void readOnServer(int id, PacketBuffer buf) { - if (id == 0) { + if (id == UPDATE_MATRIX) { int size = buf.readVarInt(); for (int i = 0; i < size; i++) { - try { - this.craftingMatrix.setInventorySlotContents(i, buf.readItemStack()); - } catch (IOException ignore) {} - this.updateCurrentRecipe(); + this.craftingMatrix.setInventorySlotContents(i, NetworkUtils.readItemStack(buf)); } - } else if (id == 4) { - int slot = buf.readVarInt(); - syncToClient(5, buffer -> { - buffer.writeVarInt(slot); - writeStackSafe(buffer, availableHandlers.getStackInSlot(slot)); - }); - } - } - - private static ItemStack readStackSafe(PacketBuffer buffer) { - var stack = ItemStack.EMPTY; - try { - var tag = buffer.readCompoundTag(); - if (tag == null) throw new IOException(); - // GTLog.logger.warn(String.format("Received: %s", tag)); - stack = new ItemStack(tag); - } catch (IOException ignore) { - GTLog.logger.warn("A stack was read incorrectly, something is seriously wrong!"); + this.updateCurrentRecipe(); } - return stack; - } - - private static void writeStackSafe(PacketBuffer buffer, ItemStack stack) { - var tag = stack.serializeNBT(); - // GTLog.logger.warn(String.format("Sent: %s", tag)); - buffer.writeCompoundTag(tag); } public static InventoryCrafting wrapHandler(IItemHandlerModifiable handler) { diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index aa28bcbea22..9d19840ee93 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -20,6 +20,18 @@ public class CraftingRecipeMemory extends SyncHandler { + // client and server + public static final int UPDATE_RECIPES = 1; + + // client only + public static final int SYNC_RECIPE = 4; + public static final int OFFSET_RECIPE = 5; + public static final int REMOVE_RECIPE = 2; + public static final int MAKE_RECIPE = 3; + + // server only + public static final int MOUSE_CLICK = 2; + private final MemorizedRecipe[] memorizedRecipes; private final IItemHandlerModifiable craftingMatrix; @@ -80,7 +92,7 @@ private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { } else { memorizedRecipe = offsetRecipe(i); final int startIndex = i; - syncToClient(5, buffer -> buffer.writeByte(startIndex)); + syncToClient(OFFSET_RECIPE, buffer -> buffer.writeByte(startIndex)); if (memorizedRecipe == null) { memorizedRecipe = new MemorizedRecipe(i); } @@ -97,7 +109,7 @@ public void notifyRecipePerformed(IItemHandler craftingGrid, ItemStack resultSta // notify slot and sync to client recipe.updateCraftingMatrix(craftingGrid); recipe.timesUsed++; - syncToClient(4, recipe::writeToBuffer); + syncToClient(SYNC_RECIPE, recipe::writeToBuffer); } } @@ -153,21 +165,21 @@ public void receiveInitialSyncData(@NotNull PacketBuffer buf) { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == 1) { + if (id == UPDATE_RECIPES) { this.readRecipes(buf); - } else if (id == 2) { + } else if (id == REMOVE_RECIPE) { this.removeRecipe(buf.readByte()); - } else if (id == 3) { + } else if (id == MAKE_RECIPE) { int index = buf.readByte(); var recipe = memorizedRecipes[index]; if (recipe == null) recipe = new MemorizedRecipe(index); recipe.recipeResult = NetworkUtils.readItemStack(buf); recipe.index = index; memorizedRecipes[index] = recipe; - } else if (id == 4) { + } else if (id == SYNC_RECIPE) { var recipe = MemorizedRecipe.fromBuffer(buf); memorizedRecipes[recipe.index] = recipe; - } else if (id == 5) { + } else if (id == OFFSET_RECIPE) { this.offsetRecipe(buf.readByte()); } } @@ -205,9 +217,9 @@ public void readRecipes(PacketBuffer buf) { @Override @SuppressWarnings("DataFlowIssue") public void readOnServer(int id, PacketBuffer buf) { - if (id == 1) { - syncToClient(1, this::writeRecipes); - } else if (id == 2) { + if (id == UPDATE_RECIPES) { + syncToClient(UPDATE_RECIPES, this::writeRecipes); + } else if (id == MOUSE_CLICK) { // read mouse data int index = buf.readByte(); var data = MouseData.readPacket(buf); diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 2bb498b6588..f732d208b73 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -35,14 +35,12 @@ public class CraftingInputSlot extends Widget implements Int public CraftingInputSlot(IItemHandlerModifiable handler, int index) { this.syncHandler = new InputSyncHandler(handler, index); setSyncHandler(this.syncHandler); - tooltip().setAutoUpdate(true); - // .setHasTitleMargin(true); + tooltipAutoUpdate(true); tooltipBuilder(tooltip -> { if (!isSynced()) return; ItemStack stack = this.syncHandler.getStack(); if (stack.isEmpty()) return; tooltip.addFromItem(stack); - // tooltip.addStringLines(getScreen().getScreenWrapper().getItemToolTip(stack)); }); } @@ -126,9 +124,9 @@ public void setStack(ItemStack stack) { this.syncHandler.setStack(stack); } - @SuppressWarnings("OverrideOnly") protected static class InputSyncHandler extends SyncHandler { + public static final int SYNC_STACK = 1; private final IItemHandlerModifiable handler; private final int index; private ItemStack lastStoredItem; @@ -148,7 +146,7 @@ public void init(String key, PanelSyncManager syncHandler) { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == 1) { + if (id == SYNC_STACK) { boolean onlyAmt = buf.readBoolean(); var stack = NetworkUtils.readItemStack(buf); boolean init = buf.readBoolean(); @@ -160,7 +158,7 @@ public void readOnClient(int id, PacketBuffer buf) { @Override public void readOnServer(int id, PacketBuffer buf) { - if (id == 1) { + if (id == SYNC_STACK) { var onlyAmt = buf.readBoolean(); var stack = NetworkUtils.readItemStack(buf); this.handler.setStackInSlot(this.index, stack); @@ -198,7 +196,7 @@ public void syncStack() { this.handler.setStackInSlot(this.index, cursorStack); this.listener.onChange(cursorStack, onlyAmt, true, false); - syncToServer(1, buffer -> { + syncToServer(SYNC_STACK, buffer -> { buffer.writeBoolean(onlyAmt); NetworkUtils.writeItemStack(buffer, cursorStack); }); From b545de73bf3d099922044c61d5ef6f6ed05bb2d4 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:49:00 -0700 Subject: [PATCH 129/147] make constructor private --- .../gregtech/common/mui/widget/workbench/CraftingInputSlot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index f732d208b73..279e2490906 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -32,7 +32,7 @@ public class CraftingInputSlot extends Widget implements Int private final InputSyncHandler syncHandler; public boolean hasIngredients = true; - public CraftingInputSlot(IItemHandlerModifiable handler, int index) { + private CraftingInputSlot(IItemHandlerModifiable handler, int index) { this.syncHandler = new InputSyncHandler(handler, index); setSyncHandler(this.syncHandler); tooltipAutoUpdate(true); From 647a14ff191481335d1ae16d274bb2a66b2bedf7 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:53:42 -0700 Subject: [PATCH 130/147] rename and cleanup --- .../mui/widget/workbench/CraftingInputSlot.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 279e2490906..f54103e9fb6 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -126,7 +126,8 @@ public void setStack(ItemStack stack) { protected static class InputSyncHandler extends SyncHandler { - public static final int SYNC_STACK = 1; + public static final int SLOT_CHANGED = 1; + private final IItemHandlerModifiable handler; private final int index; private ItemStack lastStoredItem; @@ -146,7 +147,7 @@ public void init(String key, PanelSyncManager syncHandler) { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == SYNC_STACK) { + if (id == SLOT_CHANGED) { boolean onlyAmt = buf.readBoolean(); var stack = NetworkUtils.readItemStack(buf); boolean init = buf.readBoolean(); @@ -158,7 +159,7 @@ public void readOnClient(int id, PacketBuffer buf) { @Override public void readOnServer(int id, PacketBuffer buf) { - if (id == SYNC_STACK) { + if (id == SLOT_CHANGED) { var onlyAmt = buf.readBoolean(); var stack = NetworkUtils.readItemStack(buf); this.handler.setStackInSlot(this.index, stack); @@ -181,7 +182,7 @@ public void detectAndSendChanges(boolean init) { this.lastStoredItem = itemStack.isEmpty() ? ItemStack.EMPTY : itemStack.copy(); } final boolean finalOnlyAmountChanged = onlyAmountChanged; - syncToClient(1, buffer -> { + syncToClient(SLOT_CHANGED, buffer -> { buffer.writeBoolean(finalOnlyAmountChanged); NetworkUtils.writeItemStack(buffer, itemStack); buffer.writeBoolean(init); @@ -194,9 +195,8 @@ public void syncStack() { final var curStack = getStack(); final boolean onlyAmt = ItemHandlerHelper.canItemStacksStackRelaxed(curStack, cursorStack); - this.handler.setStackInSlot(this.index, cursorStack); - this.listener.onChange(cursorStack, onlyAmt, true, false); - syncToServer(SYNC_STACK, buffer -> { + setStack(cursorStack); + syncToServer(SLOT_CHANGED, buffer -> { buffer.writeBoolean(onlyAmt); NetworkUtils.writeItemStack(buffer, cursorStack); }); From 87b8c48b6f5749a7ba4da3a12de3bc178aaa7e58 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:14:35 -0700 Subject: [PATCH 131/147] cleanup and sort inventory list --- .../storage/MetaTileEntityWorkbench.java | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index e529e875b6f..6257489f364 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -64,7 +64,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.function.Predicate; public class MetaTileEntityWorkbench extends MetaTileEntity { @@ -325,12 +324,6 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { var connected = new SlotGroup("connected_inventory", 8, true); syncManager.registerSlotGroup(connected); - List list = new ArrayList<>(this.connectedInventory.getSlots()); - Predicate checkSlotValid = itemSlot -> { - int slot = itemSlot.getSlot().getSlotIndex(); - return slot < this.connectedInventory.getSlots(); - }; - if (this.connectedInventory.getSlots() == 0) { return Flow.column() .debugName("inventory page - empty") @@ -341,14 +334,29 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { .background(GTGuiTextures.DISPLAY); } + List list = new ArrayList<>(this.connectedInventory.getSlots()); + for (int i = 0; i < this.connectedInventory.getSlots(); i++) { - var widget = new ItemSlot() - .setEnabledIf(checkSlotValid) + list.add(new ItemSlot() + .setEnabledIf(itemSlot -> { + int slot = itemSlot.getSlot().getSlotIndex(); + return slot < this.connectedInventory.getSlots(); + }) .slot(SyncHandlers.itemSlot(this.connectedInventory, i) - .slotGroup(connected)); - // widget.setEnabled(checkSlotValid.test(widget)); - list.add(widget); + .slotGroup(connected))); } + + // sort list + list.sort((o1, o2) -> { + var left = o1.getSlot().getStack(); + var right = o2.getSlot().getStack(); + + if (!left.isEmpty() && !right.isEmpty()) return 0; + if (left.isEmpty() && right.isEmpty()) return 0; + + return right.isEmpty() ? -1 : 1; + }); + return Flow.column() .debugName("inventory page") .padding(2) From 492286f76bd5dea7af4cbfa3bab3aab5026c522e Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:38:44 -0700 Subject: [PATCH 132/147] fix lock not syncing fix removing recipe on client --- .../storage/CraftingRecipeMemory.java | 15 +++++++++------ .../mui/widget/workbench/RecipeMemorySlot.java | 9 ++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 9d19840ee93..ac05cdc18e0 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -215,7 +215,6 @@ public void readRecipes(PacketBuffer buf) { } @Override - @SuppressWarnings("DataFlowIssue") public void readOnServer(int id, PacketBuffer buf) { if (id == UPDATE_RECIPES) { syncToClient(UPDATE_RECIPES, this::writeRecipes); @@ -223,14 +222,15 @@ public void readOnServer(int id, PacketBuffer buf) { // read mouse data int index = buf.readByte(); var data = MouseData.readPacket(buf); - if (data.shift && data.mouseButton == 0 && hasRecipe(index)) { - var recipe = getRecipeAtIndex(index); + var recipe = getRecipeAtIndex(index); + if (recipe == null) return; + + if (data.shift && data.mouseButton == 0) { recipe.setRecipeLocked(!recipe.isRecipeLocked()); } else if (data.mouseButton == 0) { loadRecipe(index); - } else if (data.mouseButton == 1) { - if (hasRecipe(index) && !getRecipeAtIndex(index).isRecipeLocked()) - removeRecipe(index); + } else if (data.mouseButton == 1 && !recipe.isRecipeLocked()) { + removeRecipe(index); } } } @@ -268,12 +268,14 @@ private static MemorizedRecipe deserializeNBT(NBTTagCompound tagCompound, int in private void writeToBuffer(PacketBuffer buffer) { buffer.writeByte(this.index); buffer.writeInt(this.timesUsed); + buffer.writeBoolean(this.recipeLocked); NetworkUtils.writeItemStack(buffer, this.recipeResult); } private static @NotNull MemorizedRecipe fromBuffer(PacketBuffer buffer) { var recipe = new MemorizedRecipe(buffer.readByte()); recipe.timesUsed = buffer.readInt(); + recipe.recipeLocked = buffer.readBoolean(); recipe.recipeResult = NetworkUtils.readItemStack(buffer); return recipe; } @@ -310,6 +312,7 @@ public MemorizedRecipe copy() { var recipe = new MemorizedRecipe(this.index); recipe.initialize(this.recipeResult); recipe.updateCraftingMatrix(this.craftingMatrix); + recipe.recipeLocked = this.recipeLocked; recipe.timesUsed = this.timesUsed; return recipe; } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 259cafd83e3..0dc838f1e84 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -25,7 +25,7 @@ public class RecipeMemorySlot extends Widget implements Intera public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { this.memory = memory; this.index = index; - tooltip().setAutoUpdate(true); + tooltipAutoUpdate(true); tooltipBuilder(tooltip -> { var recipe = memory.getRecipeAtIndex(this.index); if (recipe == null) return; @@ -50,6 +50,7 @@ public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { GuiDraw.drawItem(itemstack, 1, 1, 16, 16); itemstack.setCount(cachedCount); + //noinspection DataFlowIssue if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) { GlStateManager.disableDepth(); GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme); @@ -80,10 +81,8 @@ public Result onMousePressed(int mouseButton) { if (data.shift && data.mouseButton == 0) { recipe.setRecipeLocked(!recipe.isRecipeLocked()); - } - - if (!data.shift && data.mouseButton == 1) { - memory.removeRecipe(this.index); + } else if (data.mouseButton == 1 && !recipe.isRecipeLocked()) { + this.memory.removeRecipe(index); } return Result.ACCEPT; From 478a54db96029d43a66b63eb029a076fc9d9563f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:41:50 -0700 Subject: [PATCH 133/147] oops --- .../common/mui/widget/workbench/RecipeMemorySlot.java | 2 +- .../java/gregtech/integration/jei/JustEnoughItemsModule.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 0dc838f1e84..9949e58e4d9 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -50,7 +50,7 @@ public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { GuiDraw.drawItem(itemstack, 1, 1, 16, 16); itemstack.setCount(cachedCount); - //noinspection DataFlowIssue + // noinspection DataFlowIssue if (this.memory.getRecipeAtIndex(this.index).isRecipeLocked()) { GlStateManager.disableDepth(); GTGuiTextures.RECIPE_LOCK.draw(context, 10, 1, 8, 8, widgetTheme); diff --git a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java index 6f78022e1f7..1dd161878ed 100644 --- a/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java +++ b/src/main/java/gregtech/integration/jei/JustEnoughItemsModule.java @@ -12,6 +12,7 @@ import gregtech.api.metatileentity.SteamMetaTileEntity; import gregtech.api.metatileentity.registry.MTERegistry; import gregtech.api.modules.GregTechModule; +import gregtech.api.mui.GregTechGuiTransferHandler; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.category.GTRecipeCategory; @@ -161,6 +162,10 @@ public void register(IModRegistry registry) { registry.getRecipeTransferRegistry().addRecipeTransferHandler(modularUIGuiHandler, Constants.UNIVERSAL_RECIPE_TRANSFER_UID); + // register transfer handler for crafting recipes + registry.getRecipeTransferRegistry().addRecipeTransferHandler(new GregTechGuiTransferHandler( + jeiHelpers.recipeTransferHandlerHelper()), VanillaRecipeCategoryUid.CRAFTING); + registry.addAdvancedGuiHandlers(modularUIGuiHandler); registry.addGhostIngredientHandler(modularUIGuiHandler.getGuiContainerClass(), modularUIGuiHandler); From 876b7859c4ee69ca0253525e2b56fa7a6a733ffe Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 17:29:40 -0700 Subject: [PATCH 134/147] add button to clear grid --- .../java/gregtech/api/mui/GTGuiTextures.java | 1 + .../storage/CraftingRecipeLogic.java | 7 +++++++ .../storage/MetaTileEntityWorkbench.java | 17 ++++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index 04bcd7b0ea3..f34c08a936a 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -357,6 +357,7 @@ public static class IDs { public static final UITexture BUTTON_AUTO_COLLAPSE = fullImage( "textures/gui/widget/button_auto_collapse_overlay.png"); public static final UITexture BUTTON_X = fullImage("textures/gui/widget/button_x_overlay.png", true); + public static final UITexture BUTTON_CLEAR_GRID = fullImage("textures/gui/widget/button_clear_grid.png", false); public static final UITexture BUTTON_CROSS = fullImage("textures/gui/widget/button_cross.png"); public static final UITexture BUTTON_REDSTONE_ON = fullImage("textures/gui/widget/button_redstone_on.png"); diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 16341febfa5..c0dc49928a2 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -410,6 +410,13 @@ public int handleCacheMiss(ItemStack stack) { return -1; } + public void writeMatrix(PacketBuffer buffer) { + buffer.writeVarInt(craftingMatrix.getSizeInventory()); + for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { + NetworkUtils.writeItemStack(buffer, craftingMatrix.getStackInSlot(i)); + } + } + @Override public void readOnClient(int id, PacketBuffer buf) { if (id == UPDATE_INGREDIENTS) { diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 6257489f364..721d77f6950 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -47,6 +47,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; +import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.PageButton; import com.cleanroommc.modularui.widgets.PagedWidget; @@ -291,7 +292,21 @@ public IWidget createCraftingGrid() { } }) .background(GTGuiTextures.SLOT)) - .build(); + .build() + .child(new ButtonWidget<>() + .margin(2) + .size(8) + .topRel(0f) + .rightRel(0f, 0, 1f) + .background(GTGuiTextures.BUTTON_CLEAR_GRID) + .disableHoverBackground() + .onMousePressed(mouseButton -> { + this.recipeLogic.clearCraftingGrid(); + this.recipeLogic.syncToServer( + CraftingRecipeLogic.UPDATE_MATRIX, + this.recipeLogic::writeMatrix); + return true; + })); } public IWidget createCraftingOutput(PosGuiData guiData, PanelSyncManager syncManager) { From 8d92a30d0a633e4176c54a2ddbf5e1d4e7d9149b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:16:49 -0700 Subject: [PATCH 135/147] implement multi-crafting with shift --- .../widget/workbench/CraftingOutputSlot.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index a5aee5ad315..a7aaa0d9bd4 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -126,14 +126,20 @@ public void readOnServer(int id, PacketBuffer buf) { if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { if (recipeLogic.performRecipe()) { - ItemStack craftedStack = this.slot.getStack(); + ItemStack craftedStack = getOutputStack(); if (data.shift) { - quickTransfer(craftedStack); + ItemStack finalStack = craftedStack.copy(); + while (finalStack.getCount() < craftedStack.getMaxStackSize()) { + if (!recipeLogic.performRecipe()) break; + finalStack.setCount(finalStack.getCount() + craftedStack.getCount()); + handleItemCraft(craftedStack, getSyncManager().getPlayer()); + } + quickTransfer(finalStack); } else { syncToClient(SYNC_STACK, this::syncCraftedStack); + handleItemCraft(craftedStack, getSyncManager().getPlayer()); } - handleItemCraft(craftedStack, getSyncManager().getPlayer()); } } } @@ -215,13 +221,13 @@ public ItemStack getOutputStack() { return slot.getStack(); } - public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { - itemStack.onCrafting(player.world, player, 1); + public void handleItemCraft(ItemStack craftedStack, EntityPlayer player) { + craftedStack.onCrafting(player.world, player, 1); var inventoryCrafting = recipeLogic.getCraftingMatrix(); // if we're not simulated, fire the event, unlock recipe and add crafted items, and play sounds - FMLCommonHandler.instance().firePlayerCraftingEvent(player, itemStack, inventoryCrafting); + FMLCommonHandler.instance().firePlayerCraftingEvent(player, craftedStack, inventoryCrafting); var cachedRecipe = recipeLogic.getCachedRecipe(); if (cachedRecipe != null && !cachedRecipe.isDynamic()) { @@ -229,7 +235,6 @@ public void handleItemCraft(ItemStack itemStack, EntityPlayer player) { } if (cachedRecipe != null) { ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); - // itemsCrafted += resultStack.getCount(); this.slot.notifyRecipePerformed(resultStack); } } From 9dda6aef8e687ada3ff13650ae2da107afb42429 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:52:41 -0700 Subject: [PATCH 136/147] fix off by one crafting --- .../common/mui/widget/workbench/CraftingOutputSlot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index a7aaa0d9bd4..4f217b2153a 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -127,6 +127,7 @@ public void readOnServer(int id, PacketBuffer buf) { if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { if (recipeLogic.performRecipe()) { ItemStack craftedStack = getOutputStack(); + handleItemCraft(craftedStack, getSyncManager().getPlayer()); if (data.shift) { ItemStack finalStack = craftedStack.copy(); @@ -138,7 +139,6 @@ public void readOnServer(int id, PacketBuffer buf) { quickTransfer(finalStack); } else { syncToClient(SYNC_STACK, this::syncCraftedStack); - handleItemCraft(craftedStack, getSyncManager().getPlayer()); } } } From e3039a62debb69762aab0ae2ae7e118e3ee275f2 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 29 Jan 2025 20:06:19 -0700 Subject: [PATCH 137/147] use modified draw item method --- .../gregtech/client/utils/RenderUtil.java | 20 +++++++++++++++++++ .../widget/workbench/CraftingInputSlot.java | 6 +----- .../widget/workbench/CraftingOutputSlot.java | 4 ++-- .../widget/workbench/RecipeMemorySlot.java | 4 ++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index f38d5cee0d4..f81d6149975 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -26,6 +26,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.MCHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL11; @@ -384,6 +385,25 @@ public static void renderItemOverLay(float x, float y, float z, float scale, Ite net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); } + // adapted from com.cleanroommc.modularui.drawable.GuiDraw.java + public static void renderItem(ItemStack item, int x, int y, float width, float height) { + if (item.isEmpty()) return; + GlStateManager.pushMatrix(); + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.enableDepth(); + GlStateManager.translate(x, y, 0); + GlStateManager.scale(width / 16f, height / 16f, 1); + RenderItem renderItem = MCHelper.getMc().getRenderItem(); + renderItem.zLevel = 200; + renderItem.renderItemAndEffectIntoGUI(MCHelper.getPlayer(), item, 0, 0); + renderItem.renderItemOverlayIntoGUI(MCHelper.getFontRenderer(), item, x, y, null); + renderItem.zLevel = 0; + GlStateManager.disableDepth(); + RenderHelper.enableStandardItemLighting(); + GlStateManager.disableLighting(); + GlStateManager.popMatrix(); + } + public static void renderFluidOverLay(float x, float y, float width, float height, float z, FluidStack fluidStack, float alpha) { if (fluidStack != null) { diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index f54103e9fb6..1d7e6da8c77 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -9,9 +9,7 @@ import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; -import com.cleanroommc.modularui.api.MCHelper; import com.cleanroommc.modularui.api.widget.Interactable; -import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; import com.cleanroommc.modularui.network.NetworkUtils; @@ -84,9 +82,7 @@ public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { RenderUtil.renderRect(0, 0, 18, 18, 200, 0x80FF0000); } - GuiDraw.drawItem(itemstack, 1, 1, 16, 16); - var renderer = MCHelper.getMc().getRenderItem(); - renderer.renderItemOverlayIntoGUI(MCHelper.getFontRenderer(), itemstack, 1, 1, null); + RenderUtil.renderItem(itemstack, 1, 1, 16, 16); } @Override diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 4f217b2153a..b9e2348fcf0 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -1,5 +1,6 @@ package gregtech.common.mui.widget.workbench; +import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; @@ -15,7 +16,6 @@ import net.minecraftforge.items.ItemHandlerHelper; import com.cleanroommc.modularui.api.widget.Interactable; -import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.RichTooltip; @@ -75,7 +75,7 @@ public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { ItemStack itemstack = this.syncHandler.getOutputStack(); if (itemstack.isEmpty()) return; - GuiDraw.drawItem(itemstack, 1, 1, 16, 16); + RenderUtil.renderItem(itemstack, 1, 1, 16, 16); } @Override diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 9949e58e4d9..2d6ce049bf8 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -1,6 +1,7 @@ package gregtech.common.mui.widget.workbench; import gregtech.api.mui.GTGuiTextures; +import gregtech.client.utils.RenderUtil; import gregtech.common.metatileentities.storage.CraftingRecipeMemory; import net.minecraft.client.renderer.GlStateManager; @@ -9,7 +10,6 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; -import com.cleanroommc.modularui.drawable.GuiDraw; import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; @@ -47,7 +47,7 @@ public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { int cachedCount = itemstack.getCount(); itemstack.setCount(1); // required to not render the amount overlay - GuiDraw.drawItem(itemstack, 1, 1, 16, 16); + RenderUtil.renderItem(itemstack, 1, 1, 16, 16); itemstack.setCount(cachedCount); // noinspection DataFlowIssue From e59aebdafdc122e719e1ac596438505ff4b7a402 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 01:24:38 -0700 Subject: [PATCH 138/147] reset ingredients --- .../storage/CachedRecipeData.java | 6 ++++++ .../storage/CraftingRecipeLogic.java | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index aec49e23665..6ce6cedab9e 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -10,6 +10,7 @@ public class CachedRecipeData { private IRecipe recipe; + private IRecipe previousRecipe; public CachedRecipeData() { this(null); @@ -27,6 +28,7 @@ public boolean matches(InventoryCrafting inventoryCrafting, World world) { } public void setRecipe(IRecipe newRecipe) { + this.previousRecipe = this.recipe; this.recipe = newRecipe; } @@ -34,6 +36,10 @@ public IRecipe getRecipe() { return recipe; } + public IRecipe getPreviousRecipe() { + return previousRecipe; + } + public ItemStack getRecipeOutput() { return recipe == null ? ItemStack.EMPTY : recipe.getRecipeOutput(); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index c0dc49928a2..75cc78edec1 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -37,6 +37,7 @@ public class CraftingRecipeLogic extends SyncHandler { // client only public static final int UPDATE_INGREDIENTS = 1; + public static final int RESET_INGREDIENTS = 2; public static final int SYNC_STACK = 4; // server only @@ -336,7 +337,16 @@ public IRecipe getCachedRecipe() { @Override public void detectAndSendChanges(boolean init) { var recipe = getCachedRecipe(); - if (recipe == null) return; + if (recipe == null) { + var prevRecipe = cachedRecipeData.getPreviousRecipe(); + if (prevRecipe == null) return; + cachedRecipeData.setRecipe(null); + for (CraftingInputSlot inputSlot : this.inputSlots) { + inputSlot.hasIngredients = true; + } + syncToClient(RESET_INGREDIENTS); + return; + } requiredItems.clear(); final Map map = new Int2BooleanArrayMap(); @@ -424,9 +434,12 @@ public void readOnClient(int id, PacketBuffer buf) { for (int i = 0; i < size; i++) { this.inputSlots[buf.readByte()].hasIngredients = buf.readBoolean(); } - } - if (id == SYNC_STACK) { + } else if (id == SYNC_STACK) { getSyncManager().setCursorItem(NetworkUtils.readItemStack(buf)); + } else if (id == RESET_INGREDIENTS) { + for (CraftingInputSlot inputSlot : this.inputSlots) { + inputSlot.hasIngredients = true; + } } } From 585bdd43265a434a8d5f1c8e6ca15efaea27a488 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:58:25 -0700 Subject: [PATCH 139/147] improve recipe memory offsetting move used memorized recipe to the front --- .../storage/CraftingRecipeMemory.java | 58 ++++++++++++++----- .../widget/workbench/RecipeMemorySlot.java | 2 +- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index ac05cdc18e0..1cb9cadd94d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -57,31 +57,50 @@ public MemorizedRecipe getRecipeAtIndex(int index) { return hasRecipe(index) ? getRecipeAtIndex(index).getRecipeResult() : ItemStack.EMPTY; } - @Nullable - private MemorizedRecipe offsetRecipe(int startIndex) { - MemorizedRecipe previousRecipe = memorizedRecipes[startIndex]; + /** + * Offsets recipes from {@code startIndex} to the right, skipping locked recipes + * + * @param startIndex the index to start offsetting recipes + */ + private void offsetRecipe(int startIndex) { + MemorizedRecipe previousRecipe = removeRecipe(startIndex); for (int i = startIndex + 1; i < memorizedRecipes.length; i++) { MemorizedRecipe recipe = memorizedRecipes[i]; if (recipe != null && recipe.recipeLocked) continue; memorizedRecipes[i] = previousRecipe; memorizedRecipes[i].index = i; - if (recipe == null) - return memorizedRecipes[startIndex] = null; + + // we found a null recipe and there's no more recipes to check, + if (recipe == null) return; previousRecipe = recipe; } - return previousRecipe; } @Nullable private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { // search preexisting recipe with identical recipe result + MemorizedRecipe existing = null; for (MemorizedRecipe memorizedRecipe : memorizedRecipes) { if (memorizedRecipe != null && ItemStack.areItemStacksEqual(memorizedRecipe.recipeResult, resultItemStack)) { - return memorizedRecipe; + existing = memorizedRecipe; + break; } } + + // we already have a recipe that matches + // move it to the front + if (existing != null && !existing.recipeLocked) { + int removed = existing.index; + removeRecipe(existing.index); + syncToClient(REMOVE_RECIPE, buffer -> buffer.writeByte(removed)); + offsetRecipe(0); + syncToClient(OFFSET_RECIPE, buffer -> buffer.writeByte(0)); + existing.index = 0; + return memorizedRecipes[0] = existing; + } + // put new memorized recipe into array for (int i = 0; i < memorizedRecipes.length; i++) { MemorizedRecipe memorizedRecipe; @@ -90,12 +109,9 @@ private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { } else if (memorizedRecipes[i].recipeLocked) { continue; } else { - memorizedRecipe = offsetRecipe(i); - final int startIndex = i; - syncToClient(OFFSET_RECIPE, buffer -> buffer.writeByte(startIndex)); - if (memorizedRecipe == null) { - memorizedRecipe = new MemorizedRecipe(i); - } + offsetRecipe(i); + memorizedRecipe = new MemorizedRecipe(i); + syncToClient(OFFSET_RECIPE, buffer -> buffer.writeByte(memorizedRecipe.index)); } memorizedRecipe.initialize(resultItemStack); return memorizedRecipes[i] = memorizedRecipe; @@ -145,10 +161,13 @@ private static void copyInventoryItems(IItemHandler src, IItemHandlerModifiable } } - public final void removeRecipe(int index) { + public final MemorizedRecipe removeRecipe(int index) { if (hasRecipe(index)) { + MemorizedRecipe removed = memorizedRecipes[index]; memorizedRecipes[index] = null; + return removed; } + return null; } public final boolean hasRecipe(int index) { @@ -238,7 +257,7 @@ public void readOnServer(int id, PacketBuffer buf) { public static class MemorizedRecipe { private final ItemStackHandler craftingMatrix = new ItemStackHandler(9); - private ItemStack recipeResult; + private ItemStack recipeResult = ItemStack.EMPTY; private boolean recipeLocked = false; public int timesUsed = 0; public int index; @@ -316,5 +335,14 @@ public MemorizedRecipe copy() { recipe.timesUsed = this.timesUsed; return recipe; } + + @Override + public String toString() { + return String.format("MemorizedRecipe{%dx %s, locked: %s, times used: %d}", + getRecipeResult().getCount(), + getRecipeResult().getDisplayName(), + recipeLocked, + timesUsed); + } } } diff --git a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java index 2d6ce049bf8..8a37dd57a38 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -74,7 +74,7 @@ public Result onMousePressed(int mouseButton) { return Result.IGNORE; var data = MouseData.create(mouseButton); - this.memory.syncToServer(2, buffer -> { + this.memory.syncToServer(CraftingRecipeMemory.MOUSE_CLICK, buffer -> { buffer.writeByte(this.index); data.writeToPacket(buffer); }); From f84a3a965d2943429c8c6d990ccc72aa1e7d0d18 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:49:53 -0700 Subject: [PATCH 140/147] no need to move recipes at index 0 --- .../common/metatileentities/storage/CraftingRecipeMemory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 1cb9cadd94d..013e224f0f3 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -64,6 +64,7 @@ public MemorizedRecipe getRecipeAtIndex(int index) { */ private void offsetRecipe(int startIndex) { MemorizedRecipe previousRecipe = removeRecipe(startIndex); + if (previousRecipe == null) return; for (int i = startIndex + 1; i < memorizedRecipes.length; i++) { MemorizedRecipe recipe = memorizedRecipes[i]; if (recipe != null && recipe.recipeLocked) continue; @@ -92,6 +93,7 @@ private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { // we already have a recipe that matches // move it to the front if (existing != null && !existing.recipeLocked) { + if (existing.index == 0) return existing; // it's already at the front int removed = existing.index; removeRecipe(existing.index); syncToClient(REMOVE_RECIPE, buffer -> buffer.writeByte(removed)); From e7a875d085c2d6dce587a99970a31d8101fb0cc4 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:54:44 -0700 Subject: [PATCH 141/147] check and simulate if output can be inserted --- .../widget/workbench/CraftingOutputSlot.java | 69 +++++++++++-------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index b9e2348fcf0..256b380a731 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -125,18 +125,19 @@ public void readOnServer(int id, PacketBuffer buf) { var data = MouseData.readPacket(buf); if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { - if (recipeLogic.performRecipe()) { + if (quickTransfer(getOutputStack(), true) && recipeLogic.performRecipe()) { ItemStack craftedStack = getOutputStack(); handleItemCraft(craftedStack, getSyncManager().getPlayer()); if (data.shift) { ItemStack finalStack = craftedStack.copy(); - while (finalStack.getCount() < craftedStack.getMaxStackSize()) { + while (quickTransfer(finalStack, true) && + finalStack.getCount() < craftedStack.getMaxStackSize()) { if (!recipeLogic.performRecipe()) break; finalStack.setCount(finalStack.getCount() + craftedStack.getCount()); handleItemCraft(craftedStack, getSyncManager().getPlayer()); } - quickTransfer(finalStack); + quickTransfer(finalStack, false); } else { syncToClient(SYNC_STACK, this::syncCraftedStack); } @@ -145,49 +146,57 @@ public void readOnServer(int id, PacketBuffer buf) { } } - public void quickTransfer(ItemStack fromStack) { + private boolean insertStack(ItemStack fromStack, ModularSlot toSlot, boolean simulate) { + ItemStack toStack = toSlot.getStack().copy(); + if (ItemHandlerHelper.canItemStacksStack(fromStack, toStack)) { + int j = toStack.getCount() + fromStack.getCount(); + int maxSize = Math.min(toSlot.getSlotStackLimit(), fromStack.getMaxStackSize()); + + if (j <= maxSize) { + if (simulate) return true; + fromStack.setCount(0); + toStack.setCount(j); + toSlot.putStack(toStack); + } else if (toStack.getCount() < maxSize) { + if (simulate) return true; + fromStack.shrink(maxSize - toStack.getCount()); + toStack.setCount(maxSize); + toSlot.putStack(toStack); + } + + return fromStack.isEmpty(); + } else if (toStack.isEmpty()) { + if (simulate) return true; + int maxSize = Math.max(toSlot.getSlotStackLimit(), fromStack.getCount()); + toSlot.putStack(fromStack.splitStack(maxSize)); + return fromStack.isEmpty(); + } + return false; + } + + public boolean quickTransfer(ItemStack fromStack, boolean simulate) { List emptySlots = new ArrayList<>(); for (ModularSlot toSlot : this.shiftClickSlots) { if (toSlot.isEnabled() && toSlot.isItemValid(fromStack)) { - ItemStack toStack = toSlot.getStack().copy(); - if (toStack.isEmpty()) { + if (toSlot.getStack().isEmpty()) { emptySlots.add(toSlot); continue; } - if (ItemHandlerHelper.canItemStacksStack(fromStack, toStack)) { - int j = toStack.getCount() + fromStack.getCount(); - int maxSize = Math.min(toSlot.getSlotStackLimit(), fromStack.getMaxStackSize()); - - if (j <= maxSize) { - fromStack.setCount(0); - toStack.setCount(j); - toSlot.putStack(toStack); - } else if (toStack.getCount() < maxSize) { - fromStack.shrink(maxSize - toStack.getCount()); - toStack.setCount(maxSize); - toSlot.putStack(toStack); - } - - if (fromStack.isEmpty()) { - return; - } + if (insertStack(fromStack, toSlot, simulate)) { + if (simulate || fromStack.isEmpty()) return true; } } } for (ModularSlot emptySlot : emptySlots) { ItemStack itemstack = emptySlot.getStack(); if (emptySlot.isEnabled() && itemstack.isEmpty() && emptySlot.isItemValid(fromStack)) { - if (fromStack.getCount() > emptySlot.getSlotStackLimit()) { - emptySlot.putStack(fromStack.splitStack(emptySlot.getSlotStackLimit())); - } else { - emptySlot.putStack(fromStack.splitStack(fromStack.getCount())); - } - if (fromStack.isEmpty()) { - return; + if (insertStack(fromStack, emptySlot, simulate)) { + if (simulate || fromStack.isEmpty()) return true; } } } + return false; } @Override From 6dacf631551244eba943b7e370b224871b277b12 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:18:12 -0700 Subject: [PATCH 142/147] clear and refresh the lookup map every tick --- .../storage/CraftingRecipeLogic.java | 43 +++++-------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 75cc78edec1..4401ba239c2 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -52,7 +52,7 @@ public class CraftingRecipeLogic extends SyncHandler { /** * Used to lookup a list of slots for a given stack - * filled by {@link CraftingRecipeLogic#handleCacheMiss(ItemStack)} + * filled by {@link CraftingRecipeLogic#refreshStackMap()} **/ private final Map> stackLookupMap = new Object2ObjectOpenCustomHashMap<>(this.strategy); @@ -139,11 +139,6 @@ protected boolean consumeRecipeItems() { int extractedAmount = 0; for (int slot : slotList) { var extracted = availableHandlers.extractItem(slot, requestedAmount, true); - // i don't know if this is necessary - if (!this.strategy.equals(extracted, stack)) { - handleCacheMiss(stack); - continue; - } gatheredItems.put(slot, extracted.getCount()); extractedAmount += extracted.getCount(); requestedAmount -= extracted.getCount(); @@ -292,25 +287,13 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { */ private boolean simulateExtractItem(ItemStack itemStack, int count) { if (itemStack.isEmpty()) return true; - if (!stackLookupMap.containsKey(itemStack) || stackLookupMap.get(itemStack).isEmpty()) { - if (handleCacheMiss(itemStack) == -1) - return false; - } + if (!stackLookupMap.containsKey(itemStack)) return false; int extracted = 0; - Iterator slotItr = stackLookupMap.get(itemStack).iterator(); - while (slotItr.hasNext()) { - int slot = slotItr.next(); + for (int slot : stackLookupMap.get(itemStack)) { var slotStack = availableHandlers.extractItem(slot, count, true); - // cache is not correct - if (slotStack.isEmpty() || !this.strategy.equals(slotStack, itemStack)) { - slotItr.remove(); - if (!slotItr.hasNext()) stackLookupMap.remove(itemStack); - slot = handleCacheMiss(itemStack); - if (slot == -1) return false; - slotStack = availableHandlers.getStackInSlot(slot); - } + // we are certain the stack map is correct extracted += slotStack.getCount(); if (extracted >= count) return true; } @@ -349,6 +332,7 @@ public void detectAndSendChanges(boolean init) { } requiredItems.clear(); + refreshStackMap(); final Map map = new Int2BooleanArrayMap(); for (CraftingInputSlot slot : this.inputSlots) { final boolean old = slot.hasIngredients; @@ -392,15 +376,13 @@ public void detectAndSendChanges(boolean init) { } /** - * searches available handlers for the stack directly and + * Searches available handlers and * adds the stack and slots the stack lookup map - * - * @param stack stack to check for in available handlers - * @return the slot index containing the desired stack, -1 if the stack was not found */ - public int handleCacheMiss(ItemStack stack) { - if (stack.isEmpty()) return -1; - + public void refreshStackMap() { + // the stack lookup map is a pain to do "correctly" + // so just clear and reset every tick in detectAndSendChanges() + stackLookupMap.clear(); for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var curStack = this.availableHandlers.getStackInSlot(i); if (curStack.isEmpty()) continue; @@ -412,12 +394,7 @@ public int handleCacheMiss(ItemStack stack) { stackLookupMap.put(curStack.copy(), slots = new IntArraySet()); } slots.add(i); - - if (this.strategy.equals(stack, curStack)) { - return i; - } } - return -1; } public void writeMatrix(PacketBuffer buffer) { From 445c94c70806fe00092eace8142ed28c8c9baa25 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:18:47 -0700 Subject: [PATCH 143/147] fix issue with output slot not crafting when not holding shift --- .../common/mui/widget/workbench/CraftingOutputSlot.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java index 256b380a731..7624fd01886 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -125,7 +125,10 @@ public void readOnServer(int id, PacketBuffer buf) { var data = MouseData.readPacket(buf); if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { - if (quickTransfer(getOutputStack(), true) && recipeLogic.performRecipe()) { + boolean hasSpace = data.shift ? + quickTransfer(getOutputStack(), true) : + getSyncManager().getCursorItem().isEmpty(); + if (hasSpace && recipeLogic.performRecipe()) { ItemStack craftedStack = getOutputStack(); handleItemCraft(craftedStack, getSyncManager().getPlayer()); From fb29c8fdbc124d4b9b085f53d5777cd91b182094 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:42:03 -0700 Subject: [PATCH 144/147] more lang, remove todo --- .../metatileentities/storage/MetaTileEntityWorkbench.java | 7 ++++++- src/main/resources/assets/gregtech/lang/en_us.lang | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 721d77f6950..e7380bc3ff9 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -23,6 +23,7 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -217,9 +218,13 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .topRel(0f, 3, 1f) .child(new PageButton(0, controller) .tab(GuiTextures.TAB_TOP, 0) + .addTooltipLine(IKey.lang("gregtech.machine.workbench.tab.workbench")) .overlay(WORKSTATION)) .child(new PageButton(1, controller) .tab(GuiTextures.TAB_TOP, 0) + .addTooltipLine(IKey.lang("gregtech.machine.workbench.tab.item_list")) + .addTooltipLine(IKey.lang("gregtech.machine.workbench.storage_note") + .format(TextFormatting.DARK_GRAY)) .overlay(CHEST))) .child(IKey.lang(getMetaFullName()) .asWidget() @@ -235,7 +240,6 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .debugName("crafting page") .coverChildrenWidth() .child(Flow.row() - // todo add clear crafting grid button .debugName("crafting row") .coverChildrenHeight() .widthRel(1f) @@ -299,6 +303,7 @@ public IWidget createCraftingGrid() { .topRel(0f) .rightRel(0f, 0, 1f) .background(GTGuiTextures.BUTTON_CLEAR_GRID) + .addTooltipLine(IKey.lang("gregtech.machine.workbench.clear_grid")) .disableHoverBackground() .onMousePressed(mouseButton -> { this.recipeLogic.clearCraftingGrid(); diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index fcecbe83d21..3b5bbec8be3 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -2831,8 +2831,8 @@ gregtech.machine.workbench.tooltip1=Better than Forestry gregtech.machine.workbench.tooltip2=Has Item Storage, Tool Storage, pulls from adjacent Inventories, and saves Recipes. gregtech.machine.workbench.tab.workbench=Crafting gregtech.machine.workbench.tab.item_list=Storage -gregtech.machine.workbench.storage_note_1=(Available items from connected -gregtech.machine.workbench.storage_note_2=inventories usable for crafting) +gregtech.machine.workbench.storage_note=(Available items from connected\ninventories usable for crafting) +gregtech.machine.workbench.clear_grid=Clear Crafting Grid gregtech.item_list.item_stored=ยง7Stored: %,d gregtech.machine.workbench.tab.crafting=Crafting From eb43be95d6ee61b4b4a0f19b50e7652861d76913 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 20:27:17 -0700 Subject: [PATCH 145/147] implement dragging for input slots --- .../widget/workbench/CraftingInputSlot.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java index 1d7e6da8c77..8a21fcbc034 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -9,6 +9,7 @@ import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; +import com.cleanroommc.modularui.api.widget.IGuiAction; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; @@ -29,6 +30,7 @@ public class CraftingInputSlot extends Widget implements Int private final InputSyncHandler syncHandler; public boolean hasIngredients = true; + private static boolean dragging = false; private CraftingInputSlot(IItemHandlerModifiable handler, int index) { this.syncHandler = new InputSyncHandler(handler, index); @@ -40,6 +42,21 @@ private CraftingInputSlot(IItemHandlerModifiable handler, int index) { if (stack.isEmpty()) return; tooltip.addFromItem(stack); }); + + listenGuiAction((IGuiAction.MouseDrag) (m, t) -> { + if (isHovering() && dragging && syncHandler.isValid()) { + var player = syncHandler.getSyncManager().getCursorItem(); + if (!ItemHandlerHelper.canItemStacksStack(player, getStack())) + syncHandler.syncStack(); + return true; + } + return false; + }); + + listenGuiAction((IGuiAction.MouseReleased) mouseButton -> { + dragging = false; + return true; + }); } public static CraftingInputSlot create(CraftingRecipeLogic logic, IItemHandlerModifiable handler, int index) { @@ -66,13 +83,20 @@ public CraftingInputSlot changeListener(IOnSlotChanged listener) { @NotNull @Override public Result onMousePressed(int mouseButton) { - if (!this.syncHandler.isValid()) + if (!this.syncHandler.isValid() || dragging) return Result.IGNORE; this.syncHandler.syncStack(); return Result.SUCCESS; } + @Override + public void onMouseDrag(int mouseButton, long timeSinceClick) { + if (!dragging && timeSinceClick > 100) { + dragging = true; + } + } + @Override public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { ItemStack itemstack = this.syncHandler.getStack(); From 4d8b07fccb9d541cd5aacd3ea86b5bc977dec9a1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 30 Jan 2025 20:27:51 -0700 Subject: [PATCH 146/147] add todo --- src/main/java/gregtech/client/utils/RenderUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index f81d6149975..d49497e76b5 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -386,6 +386,7 @@ public static void renderItemOverLay(float x, float y, float z, float scale, Ite } // adapted from com.cleanroommc.modularui.drawable.GuiDraw.java + // todo merge this with the method from the qstorage mui2 port public static void renderItem(ItemStack item, int x, int y, float width, float height) { if (item.isEmpty()) return; GlStateManager.pushMatrix(); From 0852124362e49bfbb235d5e1d8af0cc2c1e884fc Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 31 Jan 2025 22:30:33 -0700 Subject: [PATCH 147/147] fix toolbelt slot group --- src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java index 2f4af5961da..b2ab0273a63 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -115,7 +115,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager int heightBonus = (handler.getSlots() / 9) * 18; - SlotGroup group = new SlotGroup("toolbelt_inventory", 9); + SlotGroup group = new SlotGroup("toolbelt_inventory", Math.min(handler.getSlots(), 9)); guiSyncManager.registerSlotGroup(group); List slots = new ArrayList<>();