From 9fe3ca02c0656645870cc2c9f90f76d591ff9cca 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/180] initial work on workbench port --- .../storage/MetaTileEntityWorkbench.java | 141 ++++++++++++++---- 1 file changed, 112 insertions(+), 29 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 44c92f8e11a..fb6eda7b38d 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -19,13 +19,12 @@ 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; @@ -49,6 +48,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; @@ -76,43 +88,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; @@ -198,29 +210,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 15e1a2e01aacaa70579a91aa375d24319755cf71 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/180] 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 fb6eda7b38d..a41e7a3b298 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -175,17 +175,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 7244de3b0189efa3d2c0547e0c9a2e85992535b9 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/180] 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 a41e7a3b298..e0fd6b2d82c 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -35,6 +35,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; @@ -42,6 +43,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; @@ -49,6 +51,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; @@ -233,6 +236,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(); @@ -241,9 +245,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() @@ -252,6 +256,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() @@ -259,7 +266,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() @@ -288,9 +295,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 f321ecee292356b38bb0e4fb08c5c150c61b223e 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/180] 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 eada02187ab..70a4b439800 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 553458200d7a597fa5c238a4869f5358993a247d 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/180] 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 571aec83630bdd9ed9cfacb2dbc712ac156ef1af 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/180] 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 e0fd6b2d82c..4680344a15a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -262,11 +262,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() @@ -295,13 +301,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 @@ -311,7 +323,7 @@ public int getSlots() { @Override public ItemStack getStackInSlot(int slot) { - return inventory.getStackInSlot(slot); + return inventory.getStackInSlot(slot).copy(); } @Override @@ -321,6 +333,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; } @@ -331,6 +346,7 @@ public int getSlotLimit(int slot) { @Override public void setStackInSlot(int slot, ItemStack stack) { + if (stack.isEmpty()) return; inventory.setInventorySlotContents(slot, stack); } } From 9cacb7fa1873bff80c6457450047454568fb79ce 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/180] 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 bf72c78ef8c0c90f6e3131bf5c94dd77bb72bf1c 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/180] 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 4680344a15a..792f4328441 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -333,10 +333,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 @@ -346,8 +345,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 0d43da0b4343871ed97cd3e415d0b180ca2123a1 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/180] test extending modularslot --- .../storage/MetaTileEntityWorkbench.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 792f4328441..3f04ca17991 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -1,21 +1,7 @@ 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.AbstractWidgetGroup; -import gregtech.api.gui.widgets.ClickButtonWidget; -import gregtech.api.gui.widgets.CraftingStationInputWidgetGroup; -import gregtech.api.gui.widgets.ImageWidget; -import gregtech.api.gui.widgets.LabelWidget; -import gregtech.api.gui.widgets.SimpleTextWidget; -import gregtech.api.gui.widgets.SlotWidget; -import gregtech.api.gui.widgets.TabGroup; -import gregtech.api.gui.widgets.TabGroup.TabLocation; -import gregtech.api.gui.widgets.WidgetGroup; -import gregtech.api.gui.widgets.tab.ItemTabInfo; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; + import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; @@ -43,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; @@ -269,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)) @@ -306,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; @@ -333,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(); } @@ -345,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 ff8a4690f9a83f016c83562d4a63f32e27b37fe3 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/180] 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 b3b32f22b03cbc27db6dc33cd37cc4b761b2d617 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/180] 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 bf035b6e4575bd5e399078e644ba29bafd3bbbd0 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/180] 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 3f04ca17991..96a8acf001b 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 2f23636a83f4d2e05ec7e808228d0635c41fd2bc 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/180] 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 96a8acf001b..ca1cb7619c0 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 c9ed5a9308d139af2fb95105bc47bd7625418709 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/180] 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 ca1cb7619c0..33cd480a2d8 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 849594abb44a34da4d8538084a80f42476424883 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/180] 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 7589daeecc8977f8d92681ce2cf695e21e3ac270 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/180] 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 6a8cd1ff30702d3cd1f9169892a5744e607e2700 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/180] 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 33cd480a2d8..9df0b6707b0 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 8842db793e2356787dfca28b0a74313f720fa319 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/180] 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 2c11ebee33578a9301ac4f53e2d964bda4924521 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/180] 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 c01808cce4f68a1028178e1cb06f373046ca6959 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/180] 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 9df0b6707b0..4ecb8af0335 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 6787f7c54ed19dcb14fb47657dc6080b20aa2ec7 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/180] 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 4ecb8af0335..fd8cb023b54 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 2da5cf13144a6414747ccc09cfd48ee944b0c843 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/180] 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 18d1f57ab0e5a3cb2471ede571c393a5795a3dc9 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/180] 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 fd8cb023b54..6c723f6598f 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 380447b4de1a0159e8283ac7ef1e1d23cb273609 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/180] 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 29acb3540404fdb0270a2917d9edf5fc6f869678 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/180] 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 6c723f6598f..405020ed3d9 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 98a7c719ebe307a6ae0855df80ea63c53ff6036b 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/180] 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 405020ed3d9..19fa3d6649f 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 3ea080088ffc184254b3e05165df16d449df715a 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/180] 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 19fa3d6649f..105f50fc8fb 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 40d2372e5c948405e54c5d6e06bb37be5b3169f3 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/180] 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 105f50fc8fb..c2ed2ff38e6 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 7abfa4b458633f20c59e3ee1f266f96ab8c8716c 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/180] 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 70a4b439800..eada02187ab 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 c2ed2ff38e6..e3c1b989b08 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 33561e17a90806254fdf1702be37eb2f805bf081 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/180] 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 2e0ac1a4b014429ccbe8263bcd7aaa9f62b2617a 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/180] 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 e3c1b989b08..04054cf8bd7 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 489af03ba794c7412464ab863d4eda40936cd190 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/180] 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 e98c1bdf0abdb2f6aaf807420a6084461845d13f 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/180] 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 04054cf8bd7..5355b546ba6 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 07ec049f192d989abfb95204c9bb4be9b27677fd 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/180] 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 5355b546ba6..96b894228a8 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 2a1b99018b22cad4c45f709e3bf90fa2f883542a 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/180] 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 20068094ad38ac428840b4af56a021522ee7cfe9 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/180] 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 96b894228a8..3b867f5603a 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 29e13bc2bb53d07dd080792cd75b18b6088291df 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/180] 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 3b867f5603a..27e46153c40 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 9593818cab8861a3108d195b22d12c2f706384e7 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/180] 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 27e46153c40..d8df2a23e7a 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 33dfea60e7c3fcb279232b8ebf82a973018d9da7 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/180] 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 d8df2a23e7a..6ec47eafae9 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 640aff535e3a2f2686372c13d9cf5be6d1177599 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/180] 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 7b6b2d0a3d2e45ef5bae79e3b21e2650e63cf932 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/180] 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 1d0ce6922c771752fff42b2e3f87c78395f08a73 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/180] 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 6ec47eafae9..64bec1716db 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 db6bdc2d7f6f7e3d80584e9a20a86f87b8b39a24 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/180] 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 64bec1716db..60cb63b9571 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 a1a86d8e29e580c2967a3a6bdb8d3d3578c036dd 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/180] 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 45f90d64c18d1fa05ab32374d903528bf5073c07 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/180] 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 c6f3d7d1b490f527785e89637a737b256b5b8832 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/180] 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 9d219e0eec756d264823336b4ca04b78a8edddce 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/180] 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 b3b98000fcda4779740a3d9578056a6f8f5ee101 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/180] 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 60cb63b9571..3720fd646d8 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 6143c413b5cd1ebcc8c67dd283288cc77c57b242 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/180] 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 b48304f7922fe8be7e1af96d81914e69383124c1 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/180] 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 3720fd646d8..8132504d7b0 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 2c4c4c1b371a3adafd012a7a02de297bef8d7d6d 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/180] 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 8132504d7b0..ce07d1a37dd 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 eca5c00e6374f259ab0e26a2e8194f48a8484801 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/180] 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 ce07d1a37dd..037d6d050be 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 e33263e472d44f8ddaa77d026a9d8a2f813db171 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/180] 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 037d6d050be..0c7522acd42 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 f9116ae1bfcc32c86a267dadc5edd7628132492c 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/180] add bogosorter as api --- dependencies.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/dependencies.gradle b/dependencies.gradle index ec6767e637c..7a1dea7d03f 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-rc3") { 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 41cf9aa35964ed74a0b1b7b6728b8f5387428f7b 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/180] 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 0c7522acd42..c264ef45055 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 84f731c01fac02e7dd5105f20949e85d524eb975 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/180] 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 c264ef45055..d58f9a60fad 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 bc86fbf4626d85284236b0411c0044e53e552169 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/180] 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 d58f9a60fad..81bf8063daf 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 feafa79932cb3a2cacb64c3b55fb4bae937a2b52 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/180] 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 81bf8063daf..7d13323132e 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 55993b7c23e3f2d1547d8eb30d43521c3258f29c 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/180] 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 7d13323132e..79e72f95b09 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 1e512bbf5e4fa4aa7e047abac3c854fa57d72910 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/180] 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 79e72f95b09..5453f2368ac 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 375ab38adca203a6841958c5cf3e042755e5861e 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/180] 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 5453f2368ac..cc0e5c73903 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 dad6f8da87b24d1e280213cfea8f664310bceb7f 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/180] 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 cc0e5c73903..52f8ded9229 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 e2a2049a82296834b1a4cd3bf09545fc970114c4 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/180] 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 52f8ded9229..44af539f909 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 8606c55abe8389d30e50156f85d6d64b1bff7273 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/180] 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 44af539f909..37429c540c5 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 99a4f8e16f6ff4dce8e4ea73fb62d8583237e656 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/180] 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 f1d46556357a342622b64540714358cea6b6776f 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/180] 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 37429c540c5..5db30c17cb7 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 029ef96291128029c6ccf2eb67b91837cae90ac1 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/180] 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 5db30c17cb7..e8725e9beb3 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 4e096eab2f32f010d36eb035ce79dc6fe613a149 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/180] 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 e8725e9beb3..649125b6f14 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 e0a9b41c5a322002e2cadea587aa6a2ddb692137 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/180] 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 649125b6f14..c8b95122836 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 37703d24aebce136f10e46b218b833d1d78768a6 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/180] 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 c8b95122836..c50b45cde28 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 b4edef9ac98efa19834711d0c144242868657d01 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/180] 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 c50b45cde28..be33f23a5cb 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 c4698b3582ce63519137fb1d9a2cf96ccb1cd8e8 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/180] 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 be33f23a5cb..efea85a0f00 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 f99456857f30bbb7951f7bd02596c0fceb07fdc5 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/180] 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 6b6f6ae6eb498bb091f429e6e98eef019cc4c1e9 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/180] 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 efea85a0f00..c0d39ce3d4e 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 8548a20bf1aa47b23e40307b68f6cfde3cea573d 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/180] 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 bdc5bbff854b77ec369f6b9e25c8869087108f2b 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/180] 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 a798ed39bed95a5b2b55498c18a67f7cce878d20 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/180] 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 c0d39ce3d4e..1ff75f06de6 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 525781c7e04a3654e69473707da96aee21e9a56a 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/180] 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 eaba7ae1f3bb688121999c0706723db76bd78397 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/180] 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 92157a661a6d6fadf13465bc7d22b33ead67e9d5 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/180] 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 1ff75f06de6..baff7d5f6ef 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 620036ce22c5b6a5b81b5c222806a36c2f0d0d35 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/180] 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 baff7d5f6ef..2efb80b5edb 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 1136702a09e2d40a234d55dc2a6f1e24f8471345 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/180] 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 8f9de58b93eb2253dd85fb367d2a6dc5059b76e5 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/180] 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 2efb80b5edb..3aeb6254e5b 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 9479c897ca3f5da4f7c9f903b380a32786c2181c 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/180] 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 eb34ae368772630de8fcbe4b64d7fba24a98a717 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/180] 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 3aeb6254e5b..553f7b6385f 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 16b45dd91f05fd5d554aebf8e7903140c7c434c0 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/180] 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 553f7b6385f..4cc193239c4 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 a6aed65a430876dd6904dd56d85a5040fd1b1510 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/180] 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 4cc193239c4..e2e7a8c21f6 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 30aa8a9f173043e335ec1f49b02d4274332f9b01 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/180] 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 6877c8b4073d111eb0e2f2a732f84d70c434d357 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/180] 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 e2e7a8c21f6..8f2ae355336 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 1ed3333b18ffc10262221939a4d5dc3f05012867 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/180] 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 1f4ea14fd11932c104e7d3d312600292c0dddadc 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/180] 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 3c8118f7b68f4dc44d62bd93a12d6ff750bf9439 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/180] 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 8f2ae355336..cac30d9b321 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 f096b0331362bf8092acfe2896e6ec01e69f25e8 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/180] 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 fbec6ad65d70ba76c8e19a24650084a93c310908 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/180] 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 cac30d9b321..1d8718b82c4 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 b16c5be230332afefb5b3fb87da0b161a54cbd57 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/180] 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 86b11905fe1d982f2b1d42b861edc5d07768b1af 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/180] 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 7004a9abffb1fc81a1039665672453ee0eba1c3a 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/180] 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 b2102798740f4f23fe9ed5ba044da4f06d430b66 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/180] 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 cc042d98d1a96ffe7b1ae02a2952c22f3f52b538 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/180] 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 8b8eae6905276a65f3033c29e93bab52e22c6eab 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/180] 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 055b86ab00b2eb57a6d729855707b53e16ddc313 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/180] 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 e29c37085e3a748705a29bb0485eb325c8e03ed2 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/180] 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 7b5c11ef9557e69630acaccf700a3571bc4f030c 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/180] 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 3a0b94cde25da111a10fbfd81c40c7f4b1074ce1 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/180] 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 adc147fd89b0647d5a47fc892915cab9c322cb74 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/180] 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 88ff0832bd95ddc84eba8452ee392332efbd18c0 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/180] 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 39d9627410de145268d7d3d00dd0f56a0ace7f08 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/180] 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 2b9977fe376cf80e8ce26cede64ef18a3cf4406a 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/180] 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 0476ce235ba8b2087f45a5ef6b06aef51a587eeb 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/180] 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 f9530b6cc7eab91e93bffcd4e9b24f45126621c7 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/180] 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 1d8718b82c4..8f8a33d46ce 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 782d19534ede4ca1f9c958725739448fb423c172 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/180] 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 8f8a33d46ce..1610bddbbcf 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 53f1eddabf0716e45536cc29f7cc82eb123c7917 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/180] 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 1610bddbbcf..be2111f8c2d 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 85ed6d5e3d37d5fca9d61a0bad4089dbfbc56464 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/180] 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 7f273dae89900bb2c97fb173991057207142ab98 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/180] 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 72babe5c738fffe7385c2e2941bdcd1e3067a6b5 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/180] 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 dae57260e66b146fd5b3ec67d6bd90919e4b14a0 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/180] 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 3cc5336e528d785a5b13dfdb8b394a580ed33386 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/180] 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 572721b556555c60e8a1f13ce751cf767cdb433b 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/180] 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 be2111f8c2d..1a327e46db2 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 ddcf9a019d9376281e44e1cf59c97236e28fba73 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/180] 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 9f8aefbd4d7cdf23d8f5e46542bdda1f185ca497 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/180] 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 1a327e46db2..fe5a2a0d585 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 dd973b3791b1879ac579d5c049a6e76c8430f056 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/180] 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 fa9557f81f533fd10bd2a55af53aae7a9e634752 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/180] 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 4bf95a35315ee4d3b520dcb0eeb42f04914cbf41 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/180] 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 56a674d293b..62388ffab98 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1211,6 +1211,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 627d2c13c80f4d96b6081e510d15287e19d32603 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/180] 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 1eda013619a4f7db1747f67f9fc0c5f56403bbac 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/180] 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 595e3c6c8ba46a4a60c272ebbbdfc9f270d4f778 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/180] 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 a2da02b70be9f15f1caaaa5eac3563025c7baf07 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/180] 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 cf4bf3099cc673c0569313716701a6804285424a 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/180] 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 a411120949b5d07df11679758336d2b83ee2cc8e 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/180] 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 71f52819de518a83825fb58d888ac9ba08fd5171 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/180] 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 e0933bcaabadece04d80ee29941a09b1dd19cf34 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/180] 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 fe5a2a0d585..5eec2e25dd9 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 00cb34116e66d385b895be05c787bbdcb6634706 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/180] 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 2c7e4c84bbd7a0e0effaeedf0500fba88041b1bd 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/180] 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 1e6fc59f297bd2d7d38c452005ee3e4cb6f496f1 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/180] 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 5eec2e25dd9..ddde0277c28 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 5261d3a46e3b5512580869aa9e515c17b1a2f4c7 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/180] 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 2f6b6635db6c1e45b00971228838d84593143ec8 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/180] 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 ac2b1e94e403c37c276d8531e2cc4d879560ba7f 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/180] 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 a518150990b00487b8cb40edbe67b72e126d4fde 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/180] 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 f90dbf161c2f9206fde2c88bf3aabc02c086504a 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/180] 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 1154606d3c0f5bc1c17bd196b3bcb433fffd4106 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/180] 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 631ec1d412f9efa653a15ef46d41033384eab814 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/180] 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 baccef0083400a29f38de005cb7a60602c53bb99 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/180] 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 5905980bb907269f4f65a68a1d4336eb21af6f70 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/180] 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 0b5caea37edd916dec7c5d7422413def29a2425f 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/180] 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 ddde0277c28..e75ef4ec02b 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 62388ffab98..85657dc9953 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -2832,8 +2832,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 f784b295f1edec916e4b2ae86d79cb7187af05a1 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/180] 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 dc2bf71c58e7c468bd24b26a614827b3f94746e5 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/180] 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 ea54e871a2d4967bf0cd2b79d61894fbed8c2544 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/180] 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<>(); From 53050774d878cbdccd587396f2d88a9f5091f921 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 31 Jan 2025 23:48:34 -0700 Subject: [PATCH 148/180] fix tools not making crafting sounds fix crafting with same item in hand --- .../storage/CraftingRecipeLogic.java | 13 +++----- .../widget/workbench/CraftingOutputSlot.java | 31 +++++++++++-------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 4401ba239c2..3d4fc57770b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -1,6 +1,5 @@ package gregtech.common.metatileentities.storage; -import gregtech.api.items.toolitem.IGTTool; import gregtech.api.util.DummyContainer; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; @@ -17,6 +16,7 @@ import net.minecraft.item.crafting.Ingredient; import net.minecraft.network.PacketBuffer; import net.minecraft.world.World; +import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.network.NetworkUtils; @@ -153,14 +153,11 @@ protected boolean consumeRecipeItems() { 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()); + var usedStack = ForgeHooks.getContainerItem(stack); + availableHandlers.setStackInSlot(slot, usedStack); } else if (stack.getItem().hasContainerItem(stack)) { - var useStack = stack.splitStack(1); - var newStack = useStack.getItem().getContainerItem(useStack); + var useStack = stack.getCount() > 1 ? stack.splitStack(1) : stack; + var newStack = ForgeHooks.getContainerItem(useStack); if (newStack.isEmpty()) return false; GTTransferUtils.insertItem(this.availableHandlers, newStack, 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 index 7624fd01886..da3c8d21dbc 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -10,6 +10,7 @@ import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -122,23 +123,29 @@ public void init(String key, PanelSyncManager syncManager) { @Override public void readOnServer(int id, PacketBuffer buf) { if (id == MOUSE_CLICK) { + ForgeHooks.setCraftingPlayer(getSyncManager().getPlayer()); var data = MouseData.readPacket(buf); if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { - boolean hasSpace = data.shift ? - quickTransfer(getOutputStack(), true) : - getSyncManager().getCursorItem().isEmpty(); + ItemStack cursorStack = getSyncManager().getCursorItem(); + ItemStack outputStack = getOutputStack(); + boolean hasSpace; + if (data.shift) { + hasSpace = quickTransfer(getOutputStack(), true); + } else { + hasSpace = cursorStack.isEmpty() || + ItemHandlerHelper.canItemStacksStack(cursorStack, outputStack); + } if (hasSpace && recipeLogic.performRecipe()) { - ItemStack craftedStack = getOutputStack(); - handleItemCraft(craftedStack, getSyncManager().getPlayer()); + handleItemCraft(outputStack, getSyncManager().getPlayer()); if (data.shift) { - ItemStack finalStack = craftedStack.copy(); + ItemStack finalStack = outputStack.copy(); while (quickTransfer(finalStack, true) && - finalStack.getCount() < craftedStack.getMaxStackSize()) { + finalStack.getCount() < outputStack.getMaxStackSize()) { if (!recipeLogic.performRecipe()) break; - finalStack.setCount(finalStack.getCount() + craftedStack.getCount()); - handleItemCraft(craftedStack, getSyncManager().getPlayer()); + finalStack.setCount(finalStack.getCount() + outputStack.getCount()); + handleItemCraft(outputStack, getSyncManager().getPlayer()); } quickTransfer(finalStack, false); } else { @@ -146,6 +153,7 @@ public void readOnServer(int id, PacketBuffer buf) { } } } + ForgeHooks.setCraftingPlayer(null); } } @@ -213,10 +221,7 @@ private void syncCraftedStack(PacketBuffer buf) { ItemStack curStack = getSyncManager().getCursorItem(); ItemStack outStack = this.slot.getStack(); ItemStack toSync = outStack.copy(); - if (curStack.getItem() == outStack.getItem() && - curStack.getMetadata() == outStack.getMetadata() && - ItemStack.areItemStackTagsEqual(curStack, outStack)) { - + if (ItemHandlerHelper.canItemStacksStack(curStack, outStack)) { int combined = curStack.getCount() + outStack.getCount(); if (combined <= outStack.getMaxStackSize()) { toSync.setCount(curStack.getCount() + outStack.getCount()); From 213b7356a2ef58b119f3ec23f72e6d8ce2a9df1c Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 31 Jan 2025 23:48:48 -0700 Subject: [PATCH 149/180] fix item overlay rendering --- src/main/java/gregtech/client/utils/RenderUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index d49497e76b5..c69917bbc30 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -397,7 +397,7 @@ public static void renderItem(ItemStack item, int x, int y, float width, float h RenderItem renderItem = MCHelper.getMc().getRenderItem(); renderItem.zLevel = 200; renderItem.renderItemAndEffectIntoGUI(MCHelper.getPlayer(), item, 0, 0); - renderItem.renderItemOverlayIntoGUI(MCHelper.getFontRenderer(), item, x, y, null); + renderItem.renderItemOverlayIntoGUI(MCHelper.getFontRenderer(), item, 0, 0, null); renderItem.zLevel = 0; GlStateManager.disableDepth(); RenderHelper.enableStandardItemLighting(); From 24f3e46f419526f647367dd27cfdb894b356119a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 1 Feb 2025 00:02:07 -0700 Subject: [PATCH 150/180] don't transfer if not in workbench --- .../java/gregtech/api/mui/GregTechGuiTransferHandler.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 7aefce9a7ae..12e6d809b9a 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -9,6 +9,7 @@ import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.ModularContainer; +import com.cleanroommc.modularui.value.sync.ModularSyncManager; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; @@ -34,8 +35,12 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { @Override public @Nullable IRecipeTransferError transferRecipe(ModularContainer container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer) { + ModularSyncManager syncManager = container.getSyncManager(); + if (!syncManager.isOpen("workbench")) { + return null; + } String key = PanelSyncManager.makeSyncKey("recipe_logic", 0); - CraftingRecipeLogic recipeLogic = (CraftingRecipeLogic) container.getSyncManager() + var recipeLogic = (CraftingRecipeLogic) syncManager .getSyncHandler("workbench", key); if (!doTransfer) { From 98c17ed8f01d5af41692acd884a8847ee848e887 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 1 Feb 2025 00:02:54 -0700 Subject: [PATCH 151/180] make RecipeMemorySlot a jei ingredient provider --- .../common/mui/widget/workbench/RecipeMemorySlot.java | 10 +++++++++- 1 file changed, 9 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 8a37dd57a38..88c16bb6667 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -10,14 +10,16 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; 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; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class RecipeMemorySlot extends Widget implements Interactable { +public class RecipeMemorySlot extends Widget implements Interactable, JeiIngredientProvider { private final CraftingRecipeMemory memory; private final int index; @@ -87,4 +89,10 @@ public Result onMousePressed(int mouseButton) { return Result.ACCEPT; } + + @Override + public @Nullable Object getIngredient() { + if (!this.memory.hasRecipe(this.index)) return null; + return this.memory.getRecipeOutputAtIndex(this.index); + } } From 2ac7f5d4876aa03edee080717188f680c23740e9 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 1 Feb 2025 00:38:38 -0700 Subject: [PATCH 152/180] fix duplicate recipe memory clarify todo --- .../storage/CraftingRecipeMemory.java | 16 +++++++++++++--- .../storage/MetaTileEntityWorkbench.java | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 013e224f0f3..1d45d9a27e0 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -1,5 +1,7 @@ package gregtech.common.metatileentities.storage; +import gregtech.api.util.ItemStackHashStrategy; + import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; @@ -12,6 +14,7 @@ import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.SyncHandler; +import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,6 +35,11 @@ public class CraftingRecipeMemory extends SyncHandler { // server only public static final int MOUSE_CLICK = 2; + private final Hash.Strategy strategy = ItemStackHashStrategy.builder() + .compareItem(true) + .compareMetadata(true) + .build(); + private final MemorizedRecipe[] memorizedRecipes; private final IItemHandlerModifiable craftingMatrix; @@ -84,7 +92,7 @@ private MemorizedRecipe findOrCreateRecipe(ItemStack resultItemStack) { MemorizedRecipe existing = null; for (MemorizedRecipe memorizedRecipe : memorizedRecipes) { if (memorizedRecipe != null && - ItemStack.areItemStacksEqual(memorizedRecipe.recipeResult, resultItemStack)) { + strategy.equals(memorizedRecipe.recipeResult, resultItemStack)) { existing = memorizedRecipe; break; } @@ -92,8 +100,10 @@ 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 + if (existing != null) { + // it's already at the front or it's locked + if (existing.index == 0 || existing.recipeLocked) return existing; + int removed = existing.index; removeRecipe(existing.index); syncToClient(REMOVE_RECIPE, buffer -> buffer.writeByte(removed)); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index e75ef4ec02b..72c4f2513e2 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -317,7 +317,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); // todo remove + amountCrafted.updateCacheFromSource(true); // todo remove on mui2 rc3 return Flow.column() .size(54) From 9148c5d1c9e10ac70fadcc1438bf1ca7b3e807ad Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sat, 1 Feb 2025 13:12:54 -0700 Subject: [PATCH 153/180] implement the fixes for phantom slots from mui2 master this was a pain --- .../java/gregtech/api/mui/InputAccessor.java | 23 +++ .../mixins/jei/DragManagerAccessor.java | 14 ++ .../mixins/jei/GhostDragAccessor.java | 14 ++ .../java/gregtech/mixins/mui2/InputMixin.java | 64 +++++++ .../mixins/mui2/ModularPanelMixin.java | 171 ++++++++++++++++++ src/main/resources/mixins.gregtech.jei.json | 2 + src/main/resources/mixins.gregtech.mui2.json | 5 +- 7 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 src/main/java/gregtech/api/mui/InputAccessor.java create mode 100644 src/main/java/gregtech/mixins/jei/DragManagerAccessor.java create mode 100644 src/main/java/gregtech/mixins/jei/GhostDragAccessor.java create mode 100644 src/main/java/gregtech/mixins/mui2/InputMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java diff --git a/src/main/java/gregtech/api/mui/InputAccessor.java b/src/main/java/gregtech/api/mui/InputAccessor.java new file mode 100644 index 00000000000..9cac66d865a --- /dev/null +++ b/src/main/java/gregtech/api/mui/InputAccessor.java @@ -0,0 +1,23 @@ +package gregtech.api.mui; + +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.screen.viewport.LocatedWidget; + +// todo remove on next mui2 update +// this can't be a true accessor because of illegal classloading +public interface InputAccessor { + + boolean held(); + + void held(boolean held); + + void timeHeld(long a); + + LocatedWidget lastPressed(); + + void lastPressed(LocatedWidget last); + + void lastButton(int b); + + void addInteractable(Interactable i); +} diff --git a/src/main/java/gregtech/mixins/jei/DragManagerAccessor.java b/src/main/java/gregtech/mixins/jei/DragManagerAccessor.java new file mode 100644 index 00000000000..7af21bad31e --- /dev/null +++ b/src/main/java/gregtech/mixins/jei/DragManagerAccessor.java @@ -0,0 +1,14 @@ +package gregtech.mixins.jei; + +import mezz.jei.gui.ghost.GhostIngredientDragManager; +import mezz.jei.gui.overlay.IngredientListOverlay; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +// todo remove on next mui2 update +@Mixin(value = IngredientListOverlay.class, remap = false) +public interface DragManagerAccessor { + + @Accessor("ghostIngredientDragManager") + GhostIngredientDragManager getManager(); +} diff --git a/src/main/java/gregtech/mixins/jei/GhostDragAccessor.java b/src/main/java/gregtech/mixins/jei/GhostDragAccessor.java new file mode 100644 index 00000000000..4293992f63c --- /dev/null +++ b/src/main/java/gregtech/mixins/jei/GhostDragAccessor.java @@ -0,0 +1,14 @@ +package gregtech.mixins.jei; + +import mezz.jei.gui.ghost.GhostIngredientDrag; +import mezz.jei.gui.ghost.GhostIngredientDragManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +// todo remove on next mui2 update +@Mixin(value = GhostIngredientDragManager.class, remap = false) +public interface GhostDragAccessor { + + @Accessor("ghostIngredientDrag") + GhostIngredientDrag getDrag(); +} diff --git a/src/main/java/gregtech/mixins/mui2/InputMixin.java b/src/main/java/gregtech/mixins/mui2/InputMixin.java new file mode 100644 index 00000000000..0e1d3febacf --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/InputMixin.java @@ -0,0 +1,64 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.InputAccessor; + +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.screen.viewport.LocatedWidget; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +// todo remove on next mui2 update +@Mixin(targets = "com.cleanroommc.modularui.screen.ModularPanel$Input", remap = false) +public abstract class InputMixin implements InputAccessor { + + @Shadow + private boolean held; + + @Shadow + private long timeHeld; + + @Shadow + private @Nullable LocatedWidget lastPressed; + + @Shadow + private int lastButton; + + @Shadow + protected abstract void addAcceptedInteractable(Interactable interactable); + + @Override + public boolean held() { + return this.held; + } + + @Override + public void held(boolean held) { + this.held = held; + } + + @Override + public void timeHeld(long a) { + timeHeld = a; + } + + @Override + public LocatedWidget lastPressed() { + return this.lastPressed; + } + + @Override + public void lastPressed(LocatedWidget last) { + this.lastPressed = last; + } + + @Override + public void lastButton(int b) { + this.lastButton = b; + } + + @Override + public void addInteractable(Interactable i) { + addAcceptedInteractable(i); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java b/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java new file mode 100644 index 00000000000..eeaf85048f2 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java @@ -0,0 +1,171 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.InputAccessor; +import gregtech.api.util.Mods; +import gregtech.integration.jei.JustEnoughItemsModule; +import gregtech.mixins.jei.DragManagerAccessor; +import gregtech.mixins.jei.GhostDragAccessor; + +import net.minecraft.client.Minecraft; + +import com.cleanroommc.modularui.api.layout.IViewport; +import com.cleanroommc.modularui.api.widget.IFocusedWidget; +import com.cleanroommc.modularui.api.widget.Interactable; +import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.viewport.LocatedWidget; +import com.cleanroommc.modularui.utils.ObjectList; +import com.cleanroommc.modularui.widget.ParentWidget; +import mezz.jei.gui.ghost.GhostIngredientDrag; +import mezz.jei.gui.ghost.GhostIngredientDragManager; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(value = ModularPanel.class, remap = false) +public abstract class ModularPanelMixin extends ParentWidget implements IViewport { + + @Shadow + @Final + private ObjectList hovering; + + @Shadow + public abstract boolean closeOnOutOfBoundsClick(); + + @Shadow + public abstract void animateClose(); + + @Shadow + @Final + private @NotNull String name; + @Unique + InputAccessor gregTech$mouse = null; + + /** + * @author Ghzdude - GTCEu + * @reason Implement fixes to phantom slot handling from Mui2 master + */ + // this looks really cursed in mixin.out, but it works + @Overwrite + private boolean lambda$onMousePressed$3(int mouseButton) { + LocatedWidget pressed = LocatedWidget.EMPTY; + boolean result = false; + + if (gregTech$mouse == null) { + // reflection because the type is a private inner class + try { + gregTech$mouse = (InputAccessor) ModularPanel.class.getDeclaredField("mouse").get(this); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException(e); + } + } + + if (this.hovering.isEmpty()) { + if (closeOnOutOfBoundsClick()) { + animateClose(); + result = true; + } + } else { + loop: + for (LocatedWidget widget : this.hovering) { + widget.applyMatrix(getContext()); + if (widget.getElement() instanceof JeiGhostIngredientSlotghostSlot && + Mods.JustEnoughItems.isModLoaded()) { + GhostIngredientDrag drag = gregTech$getGhostDrag(); + if (drag != null && gregTech$insertGhostIngredient(drag, ghostSlot)) { + gregTech$stopDrag(); + pressed = LocatedWidget.EMPTY; + result = true; + widget.unapplyMatrix(getContext()); + break; + } + } + if (widget.getElement() instanceof Interactable interactable) { + switch (interactable.onMousePressed(mouseButton)) { + case IGNORE: + break; + case ACCEPT: { + if (!gregTech$mouse.held()) { + gregTech$mouse.addInteractable(interactable); + } + pressed = widget; + // result = false; + break; + } + case STOP: { + pressed = LocatedWidget.EMPTY; + result = true; + widget.unapplyMatrix(getContext()); + break loop; + } + case SUCCESS: { + if (!gregTech$mouse.held()) { + gregTech$mouse.addInteractable(interactable); + } + pressed = widget; + result = true; + widget.unapplyMatrix(getContext()); + break loop; + } + } + } + if (getContext().onHoveredClick(mouseButton, widget)) { + pressed = LocatedWidget.EMPTY; + result = true; + widget.unapplyMatrix(getContext()); + break; + } + widget.unapplyMatrix(getContext()); + if (widget.getElement().canHover()) { + result = true; + break; + } + } + } + + if (result && pressed.getElement() instanceof IFocusedWidget) { + getContext().focus(pressed); + } else { + getContext().removeFocus(); + } + if (!gregTech$mouse.held()) { + gregTech$mouse.lastPressed(pressed); + if (gregTech$mouse.lastPressed().getElement() != null) { + gregTech$mouse.timeHeld(Minecraft.getSystemTime()); + } + gregTech$mouse.lastButton(mouseButton); + gregTech$mouse.held(true); + } + return result; + } + + @Unique + private static GhostIngredientDrag gregTech$getGhostDrag() { + GhostIngredientDragManager manager = ((DragManagerAccessor) JustEnoughItemsModule.jeiRuntime + .getIngredientListOverlay()).getManager(); + return ((GhostDragAccessor) manager).getDrag(); + } + + @Unique + @SuppressWarnings("rawtypes") + private static boolean gregTech$insertGhostIngredient(GhostIngredientDrag drag, + JeiGhostIngredientSlot slot) { + Object object = slot.castGhostIngredientIfValid(drag.getIngredient()); + if (object != null) { + // noinspection unchecked + slot.setGhostIngredient(object); + return true; + } + return false; + } + + @Unique + private static void gregTech$stopDrag() { + GhostIngredientDragManager manager = ((DragManagerAccessor) JustEnoughItemsModule.jeiRuntime + .getIngredientListOverlay()).getManager(); + manager.stopDrag(); + } +} diff --git a/src/main/resources/mixins.gregtech.jei.json b/src/main/resources/mixins.gregtech.jei.json index 107771e5f35..3df5ef9885e 100644 --- a/src/main/resources/mixins.gregtech.jei.json +++ b/src/main/resources/mixins.gregtech.jei.json @@ -6,6 +6,8 @@ "compatibilityLevel": "JAVA_8", "mixins": [ "BasicRecipeTransferHandlerServerMixin", + "DragManagerAccessor", + "GhostDragAccessor", "IngredientGridMixin", "JEITooltipMixin", "StackHelperMixin" diff --git a/src/main/resources/mixins.gregtech.mui2.json b/src/main/resources/mixins.gregtech.mui2.json index 427113e6ac8..41f64f92ed4 100644 --- a/src/main/resources/mixins.gregtech.mui2.json +++ b/src/main/resources/mixins.gregtech.mui2.json @@ -7,7 +7,10 @@ "injectors": { "maxShiftBy": 10 }, - "mixins": [], + "mixins": [ + "InputMixin", + "ModularPanelMixin" + ], "client": [ "LangKeyMixin" ], From 6ce953ec3d42a61dcadc7caf51ce3e94bb034e7d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 2 Feb 2025 18:39:12 -0700 Subject: [PATCH 154/180] fix compile and add note --- .../metatileentities/storage/MetaTileEntityWorkbench.java | 4 +++- .../common/mui/widget/workbench/RecipeMemorySlot.java | 2 +- 2 files changed, 4 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 72c4f2513e2..6a063b9c765 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -224,7 +224,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .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)) + .style(TextFormatting.DARK_GRAY)) .overlay(CHEST))) .child(IKey.lang(getMetaFullName()) .asWidget() @@ -354,6 +354,8 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { .background(GTGuiTextures.DISPLAY); } + // this is actually supposed to include the tool and storage inventory + // but that causes problems List list = new ArrayList<>(this.connectedInventory.getSlots()); for (int i = 0; i < this.connectedInventory.getSlots(); i++) { 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 88c16bb6667..03d9d6728ec 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -38,7 +38,7 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { 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)); + .style(TextFormatting.WHITE)); }); } From 8fa76a67dfbdfc66f62ff86cb01a8ddf89845f89 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 5 Feb 2025 00:09:39 -0700 Subject: [PATCH 155/180] fix stack syncing cleanup --- .../storage/CachedRecipeData.java | 5 --- .../widget/workbench/CraftingInputSlot.java | 37 ++++++------------- .../mixins/mui2/ModularPanelMixin.java | 4 -- 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index 6ce6cedab9e..f40d7b37d32 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -1,7 +1,6 @@ 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; @@ -39,8 +38,4 @@ public IRecipe getRecipe() { public IRecipe getPreviousRecipe() { return previousRecipe; } - - public ItemStack getRecipeOutput() { - return recipe == null ? ItemStack.EMPTY : recipe.getRecipeOutput(); - } } 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 8a21fcbc034..b26c55c5f7d 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -119,7 +119,7 @@ public void drawForeground(ModularGuiContext context) { @Override public void setGhostIngredient(@NotNull ItemStack ingredient) { - syncHandler.setStack(ingredient); + syncHandler.setStack(ingredient, true); } @Override @@ -141,7 +141,7 @@ public int getIndex() { } public void setStack(ItemStack stack) { - this.syncHandler.setStack(stack); + this.syncHandler.setStack(stack, true); } protected static class InputSyncHandler extends SyncHandler { @@ -168,22 +168,16 @@ public void init(String key, PanelSyncManager syncHandler) { @Override public void readOnClient(int id, PacketBuffer buf) { if (id == SLOT_CHANGED) { - 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); + setStack(stack, false); } } @Override public void readOnServer(int id, PacketBuffer buf) { if (id == SLOT_CHANGED) { - var onlyAmt = buf.readBoolean(); var stack = NetworkUtils.readItemStack(buf); - this.handler.setStackInSlot(this.index, stack); - this.listener.onChange(stack, onlyAmt, false, false); + this.setStack(stack, false); } } @@ -201,25 +195,13 @@ public void detectAndSendChanges(boolean init) { } else { this.lastStoredItem = itemStack.isEmpty() ? ItemStack.EMPTY : itemStack.copy(); } - final boolean finalOnlyAmountChanged = onlyAmountChanged; - syncToClient(SLOT_CHANGED, buffer -> { - buffer.writeBoolean(finalOnlyAmountChanged); - NetworkUtils.writeItemStack(buffer, itemStack); - buffer.writeBoolean(init); - }); + syncToClient(SLOT_CHANGED, buffer -> NetworkUtils.writeItemStack(buffer, itemStack)); } } public void syncStack() { final var cursorStack = GTUtility.copy(1, getSyncManager().getCursorItem()); - final var curStack = getStack(); - final boolean onlyAmt = ItemHandlerHelper.canItemStacksStackRelaxed(curStack, cursorStack); - - setStack(cursorStack); - syncToServer(SLOT_CHANGED, buffer -> { - buffer.writeBoolean(onlyAmt); - NetworkUtils.writeItemStack(buffer, cursorStack); - }); + setStack(cursorStack, true); } public ItemStack getStack() { @@ -231,9 +213,12 @@ public ItemStack getStack() { * * @param stack stack to put into this slot */ - public void setStack(ItemStack stack) { + public void setStack(ItemStack stack, boolean sync) { + var old = getStack(); + boolean onlyAmt = ItemHandlerHelper.canItemStacksStackRelaxed(stack, old); this.handler.setStackInSlot(this.index, stack); - this.listener.onChange(stack, false, getSyncManager().isClient(), false); + this.listener.onChange(stack, onlyAmt, getSyncManager().isClient(), false); + if (sync) syncToServer(SLOT_CHANGED, buffer -> NetworkUtils.writeItemStack(buffer, getStack())); } } } diff --git a/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java b/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java index eeaf85048f2..05d287c9610 100644 --- a/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java +++ b/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java @@ -18,7 +18,6 @@ import com.cleanroommc.modularui.widget.ParentWidget; import mezz.jei.gui.ghost.GhostIngredientDrag; import mezz.jei.gui.ghost.GhostIngredientDragManager; -import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -38,9 +37,6 @@ public abstract class ModularPanelMixin extends ParentWidget imple @Shadow public abstract void animateClose(); - @Shadow - @Final - private @NotNull String name; @Unique InputAccessor gregTech$mouse = null; From 4d062c2d75822e2c222fd289487567728b3fdfae Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 5 Feb 2025 23:57:43 -0700 Subject: [PATCH 156/180] fix scroll bar covering slots anticipate fix for slot groups + bogosorter --- .../storage/MetaTileEntityWorkbench.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 6a063b9c765..c4a367d461e 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -341,8 +341,6 @@ public IWidget createRecipeMemoryGrid(PanelSyncManager syncManager) { } public IWidget createInventoryPage(PanelSyncManager syncManager) { - var connected = new SlotGroup("connected_inventory", 8, true); - syncManager.registerSlotGroup(connected); if (this.connectedInventory.getSlots() == 0) { return Flow.column() @@ -358,6 +356,10 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { // but that causes problems List list = new ArrayList<>(this.connectedInventory.getSlots()); + int rowSize = Math.min(this.connectedInventory.getSlots(), 8); + var connected = new SlotGroup("connected_inventory", rowSize, true); + syncManager.registerSlotGroup(connected); + for (int i = 0; i < this.connectedInventory.getSlots(); i++) { list.add(new ItemSlot() .setEnabledIf(itemSlot -> { @@ -387,10 +389,9 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { .background(GTGuiTextures.DISPLAY) .child(new Grid() .scrollable(new VerticalScrollData(), null) - .coverChildrenWidth() + .width(18 * 8 + 4) .height(18 * 6) - .minElementMargin(0, 0) - .mapTo(8, list, (index, value) -> value)); + .mapTo(rowSize, list)); } public void sendHandlerToClient(PacketBuffer buffer) { From 0d5d3b83c2d3a05624832a327b9017363fbe4537 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 5 Feb 2025 23:58:08 -0700 Subject: [PATCH 157/180] 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 c4a367d461e..d29c49b1db4 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -341,7 +341,6 @@ public IWidget createRecipeMemoryGrid(PanelSyncManager syncManager) { } public IWidget createInventoryPage(PanelSyncManager syncManager) { - if (this.connectedInventory.getSlots() == 0) { return Flow.column() .debugName("inventory page - empty") From 0b013ec5163846d71d7303e5f4cc31718a447b80 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 11:00:11 -0700 Subject: [PATCH 158/180] fix substitute searching and finding required items make sure to copy stack with size 1 prevent sorting in connected inventory --- .../storage/CraftingRecipeLogic.java | 61 ++++++++++++------- .../storage/MetaTileEntityWorkbench.java | 5 +- 2 files changed, 43 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 3d4fc57770b..5d362c7050f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -17,12 +17,15 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.crafting.IShapedRecipe; 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; +import it.unimi.dsi.fastutil.ints.Int2IntArrayMap; +import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.IntArraySet; @@ -63,6 +66,8 @@ public class CraftingRecipeLogic extends SyncHandler { private final Map requiredItems = new Object2IntOpenCustomHashMap<>( this.strategy); + private final Int2IntMap compactedIndexes = new Int2IntArrayMap(9); + private final Map> replaceAttemptMap = new Int2ObjectArrayMap<>(); private final InventoryCrafting craftingMatrix; private final IInventory craftingResultInventory = new InventoryCraftResult(); @@ -221,13 +226,16 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { ItemStack substitute = ItemStack.EMPTY; + var recipe = getCachedRecipe(); + List ingredients = new ArrayList<>(recipe.getIngredients()); + ingredients.removeIf(ingredient -> ingredient == Ingredient.EMPTY); + int index = compactedIndexes.get(craftingIndex); + // iterate stored items to find equivalent for (int i = 0; i < this.availableHandlers.getSlots(); i++) { var itemStack = availableHandlers.getStackInSlot(i); if (itemStack.isEmpty() || this.strategy.equals(itemStack, stack)) continue; - var recipe = getCachedRecipe(); - boolean matchedPreviously = false; if (map.containsKey(itemStack)) { if (map.get(itemStack)) { @@ -240,18 +248,24 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { } 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; + boolean matched = false; + if (!(recipe instanceof IShapedRecipe)) { + for (Ingredient ing : ingredients) { + if (ing.apply(itemStack)) { + matched = true; + break; + } } + } else { + // for shaped recipes, check the exact ingredient instead + // ingredients should be in the correct order + matched = ingredients.get(index).apply(itemStack); } if (!matched) { - map.put(itemStack.copy(), false); + map.put(GTUtility.copy(1, itemStack), false); continue; } } @@ -266,7 +280,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { recipe instanceof ShapedOreEnergyTransferRecipe) { // ingredient matched, return the substitute craftingMatrix.setInventorySlotContents(craftingIndex, stack); - map.put(itemStack.copy(), true); + map.put(GTUtility.copy(1, itemStack), true); substitute = itemStack; break; } @@ -331,32 +345,37 @@ public void detectAndSendChanges(boolean init) { requiredItems.clear(); refreshStackMap(); final Map map = new Int2BooleanArrayMap(); + int next = 0; for (CraftingInputSlot slot : this.inputSlots) { - final boolean old = slot.hasIngredients; + final boolean hadIngredients = slot.hasIngredients; // check if existing stack works var slotStack = slot.getStack(); - if (slotStack.isEmpty() && !old) { - slot.hasIngredients = true; - map.put(slot.getIndex(), slot.hasIngredients); + if (slotStack.isEmpty()) { + if (!hadIngredients) { + slot.hasIngredients = true; + map.put(slot.getIndex(), slot.hasIngredients); + } continue; } - int count = requiredItems.getOrDefault(slotStack, 0); - requiredItems.put(slotStack.copy(), ++count); + compactedIndexes.put(slot.getIndex(), next++); + int count = requiredItems.getOrDefault(slotStack, 0) + 1; slot.hasIngredients = simulateExtractItem(slotStack, count); - // check if substitute exists - if (!slot.hasIngredients) { + if (slot.hasIngredients) { + requiredItems.put(GTUtility.copy(1, slotStack), count); + } else { + // check if substitute exists ItemStack substitute = findSubstitute(slot.getIndex(), slotStack); if (!substitute.isEmpty()) { - count = requiredItems.getOrDefault(substitute, 0); - requiredItems.put(substitute.copy(), ++count); + count = requiredItems.getOrDefault(substitute, 0) + 1; slot.hasIngredients = simulateExtractItem(substitute, count); + requiredItems.put(GTUtility.copy(1, substitute), count); } } - if (old != slot.hasIngredients) + if (hadIngredients != slot.hasIngredients) map.put(slot.getIndex(), slot.hasIngredients); } @@ -388,7 +407,7 @@ public void refreshStackMap() { if (stackLookupMap.containsKey(curStack)) { slots = stackLookupMap.get(curStack); } else { - stackLookupMap.put(curStack.copy(), slots = new IntArraySet()); + stackLookupMap.put(GTUtility.copy(1, curStack), slots = new IntArraySet()); } slots.add(i); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index d29c49b1db4..d33a7cdd09a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -356,7 +356,8 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { List list = new ArrayList<>(this.connectedInventory.getSlots()); int rowSize = Math.min(this.connectedInventory.getSlots(), 8); - var connected = new SlotGroup("connected_inventory", rowSize, true); + var connected = new SlotGroup("connected_inventory", rowSize, true) + .setAllowSorting(false); syncManager.registerSlotGroup(connected); for (int i = 0; i < this.connectedInventory.getSlots(); i++) { @@ -387,7 +388,7 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { .coverChildren() .background(GTGuiTextures.DISPLAY) .child(new Grid() - .scrollable(new VerticalScrollData(), null) + .scrollable(new VerticalScrollData()) .width(18 * 8 + 4) .height(18 * 6) .mapTo(rowSize, list)); From dc6bb1f5dac7f62108b56f8c3f285382f7fbfa2b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 11:13:26 -0700 Subject: [PATCH 159/180] only cast ingredient if enabled --- .../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 b26c55c5f7d..0d45bdd1355 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -124,7 +124,7 @@ public void setGhostIngredient(@NotNull ItemStack ingredient) { @Override public @Nullable ItemStack castGhostIngredientIfValid(@NotNull Object ingredient) { - return ingredient instanceof ItemStack ? (ItemStack) ingredient : null; + return areAncestorsEnabled() && ingredient instanceof ItemStack ? (ItemStack) ingredient : null; } @Override From e85f863a5946416846221aaac6118324ccb7123f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:15:46 -0700 Subject: [PATCH 160/180] don't set z level --- src/main/java/gregtech/client/utils/RenderUtil.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/gregtech/client/utils/RenderUtil.java b/src/main/java/gregtech/client/utils/RenderUtil.java index c69917bbc30..7228bd8212e 100644 --- a/src/main/java/gregtech/client/utils/RenderUtil.java +++ b/src/main/java/gregtech/client/utils/RenderUtil.java @@ -395,10 +395,8 @@ public static void renderItem(ItemStack item, int x, int y, float width, float h 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, 0, 0, null); - renderItem.zLevel = 0; GlStateManager.disableDepth(); RenderHelper.enableStandardItemLighting(); GlStateManager.disableLighting(); From 3b015b9e47eb7c9ffcedb60b9f888d10018f8049 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:20:54 -0700 Subject: [PATCH 161/180] set active page to crafting when setting recipe from JEI simplify matrix syncing guiSyncManager -> syncManager --- .../api/mui/GregTechGuiTransferHandler.java | 52 +++++++++---------- .../api/mui/sync/PagedWidgetSyncHandler.java | 45 ++++++++++++++++ .../storage/CraftingRecipeLogic.java | 7 +++ .../storage/MetaTileEntityWorkbench.java | 21 ++++---- 4 files changed, 87 insertions(+), 38 deletions(-) create mode 100644 src/main/java/gregtech/api/mui/sync/PagedWidgetSyncHandler.java diff --git a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java index 12e6d809b9a..9332b8a9a70 100644 --- a/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java +++ b/src/main/java/gregtech/api/mui/GregTechGuiTransferHandler.java @@ -1,16 +1,16 @@ package gregtech.api.mui; +import gregtech.api.mui.sync.PagedWidgetSyncHandler; import gregtech.common.metatileentities.storage.CraftingRecipeLogic; 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.network.NetworkUtils; import com.cleanroommc.modularui.screen.ModularContainer; -import com.cleanroommc.modularui.value.sync.ModularSyncManager; import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import mezz.jei.api.gui.IGuiItemStackGroup; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; @@ -21,7 +21,6 @@ public class GregTechGuiTransferHandler implements IRecipeTransferHandler { private final IRecipeTransferHandlerHelper handlerHelper; - private InventoryCrafting craftingMatrix; public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { this.handlerHelper = handlerHelper; @@ -33,39 +32,38 @@ public GregTechGuiTransferHandler(IRecipeTransferHandlerHelper handlerHelper) { } @Override - public @Nullable IRecipeTransferError transferRecipe(ModularContainer container, IRecipeLayout recipeLayout, - EntityPlayer player, boolean maxTransfer, boolean doTransfer) { - ModularSyncManager syncManager = container.getSyncManager(); - if (!syncManager.isOpen("workbench")) { + public @Nullable IRecipeTransferError transferRecipe(ModularContainer container, + @NotNull IRecipeLayout recipeLayout, + @NotNull EntityPlayer player, boolean maxTransfer, + boolean doTransfer) { + if (!container.getSyncManager().isOpen("workbench")) { return null; } - String key = PanelSyncManager.makeSyncKey("recipe_logic", 0); - var recipeLogic = (CraftingRecipeLogic) syncManager - .getSyncHandler("workbench", key); + PanelSyncManager syncManager = container.getSyncManager().getPanelSyncManager("workbench"); + var recipeLogic = (CraftingRecipeLogic) syncManager.getSyncHandler("recipe_logic:0"); + var pageController = (PagedWidgetSyncHandler) syncManager.getSyncHandler("page_controller: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(CraftingRecipeLogic.UPDATE_MATRIX, this::writeCraftingMatrix); - recipeLogic.updateCurrentRecipe(); + var matrix = extractMatrix(recipeLayout.getItemStacks()); + recipeLogic.fillCraftingGrid(matrix); + pageController.setPage(0); 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); - NetworkUtils.writeItemStack(buffer, stack); + private Int2ObjectMap extractMatrix(IGuiItemStackGroup stackGroup) { + var ingredients = stackGroup.getGuiIngredients(); + Int2ObjectMap matrix = new Int2ObjectArrayMap<>(9); + for (var slot : ingredients.keySet()) { + if (slot != 0) { + var ing = ingredients.get(slot).getDisplayedIngredient(); + if (ing == null) continue; + matrix.put(slot - 1, ingredients.get(slot).getDisplayedIngredient()); + } } + return matrix; } } diff --git a/src/main/java/gregtech/api/mui/sync/PagedWidgetSyncHandler.java b/src/main/java/gregtech/api/mui/sync/PagedWidgetSyncHandler.java new file mode 100644 index 00000000000..c91cee8c5a3 --- /dev/null +++ b/src/main/java/gregtech/api/mui/sync/PagedWidgetSyncHandler.java @@ -0,0 +1,45 @@ +package gregtech.api.mui.sync; + +import net.minecraft.network.PacketBuffer; + +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widgets.PagedWidget; + +public class PagedWidgetSyncHandler extends SyncHandler { + + private final PagedWidget.Controller controller; + public static final int SET_PAGE = 0; + + public PagedWidgetSyncHandler(PagedWidget.Controller controller) { + this.controller = controller; + } + + @Override + public void readOnClient(int id, PacketBuffer buf) { + if (id == SET_PAGE) { + setPage(buf.readVarInt(), false); + } + } + + @Override + public void readOnServer(int id, PacketBuffer buf) { + if (id == SET_PAGE) { + setPage(buf.readVarInt(), false); + } + } + + public void setPage(int page) { + setPage(page, true); + } + + public void setPage(int page, boolean sync) { + if (controller.isInitialised() && page != getPage()) { + controller.setPage(page); + if (sync) sync(SET_PAGE, buffer -> buffer.writeVarInt(page)); + } + } + + public int getPage() { + return controller.getActivePageIndex(); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 5d362c7050f..0158234fb0a 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -101,6 +101,8 @@ public void fillCraftingGrid(Map ingredients) { for (int i = 0; i < craftingMatrix.getSizeInventory(); i++) { craftingMatrix.setInventorySlotContents(i, ingredients.getOrDefault(i, ItemStack.EMPTY)); } + syncMatrix(); + updateCurrentRecipe(); } public void setInputSlot(CraftingInputSlot slot, int index) { @@ -447,6 +449,11 @@ public void readOnServer(int id, PacketBuffer buf) { } } + public void syncMatrix() { + if (getSyncManager().isClient()) + syncToServer(UPDATE_MATRIX, this::writeMatrix); + } + public static InventoryCrafting wrapHandler(IItemHandlerModifiable handler) { return new InventoryCrafting(new DummyContainer(), 3, 3) { diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index d33a7cdd09a..140d08b9f7f 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -7,6 +7,7 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; +import gregtech.api.mui.sync.PagedWidgetSyncHandler; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.common.inventory.handlers.SingleItemStackHandler; @@ -200,13 +201,14 @@ public boolean usesMui2() { } @Override - public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager syncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); - guiSyncManager.syncValue("recipe_logic", this.recipeLogic); - guiSyncManager.syncValue("recipe_memory", this.recipeMemory); + syncManager.syncValue("recipe_logic", this.recipeLogic); + syncManager.syncValue("recipe_memory", this.recipeMemory); var controller = new PagedWidget.Controller(); + syncManager.syncValue("page_controller", new PagedWidgetSyncHandler(controller)); return GTGuis.createPanel(this, 176, 224) .child(Flow.row() @@ -246,15 +248,15 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) // crafting grid .child(createCraftingGrid()) // crafting output slot - .child(createCraftingOutput(guiData, guiSyncManager)) + .child(createCraftingOutput(guiData, syncManager)) // recipe memory - .child(createRecipeMemoryGrid(guiSyncManager))) + .child(createRecipeMemoryGrid(syncManager))) // tool inventory - .child(createToolInventory(guiSyncManager)) + .child(createToolInventory(syncManager)) // internal inventory - .child(createInternalInventory(guiSyncManager))) + .child(createInternalInventory(syncManager))) // storage page - .addPage(createInventoryPage(guiSyncManager))) + .addPage(createInventoryPage(syncManager))) .bindPlayerInventory(); } @@ -307,9 +309,6 @@ public IWidget createCraftingGrid() { .disableHoverBackground() .onMousePressed(mouseButton -> { this.recipeLogic.clearCraftingGrid(); - this.recipeLogic.syncToServer( - CraftingRecipeLogic.UPDATE_MATRIX, - this.recipeLogic::writeMatrix); return true; })); } From b580b57fa4ecab5762a9aaa167ea9a61abf71d29 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:04:34 -0700 Subject: [PATCH 162/180] notify recipe logic when loading memorized recipes try to handle toolbelt write stacks safely --- .../storage/CraftingRecipeLogic.java | 27 ++++++++++++++----- .../storage/CraftingRecipeMemory.java | 9 +++++++ .../storage/MetaTileEntityWorkbench.java | 12 ++++----- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 0158234fb0a..fcda98b8e24 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -1,12 +1,15 @@ package gregtech.common.metatileentities.storage; +import gregtech.api.items.toolitem.ItemGTToolbelt; 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; import gregtech.common.crafting.ShapedOreEnergyTransferRecipe; import gregtech.common.mui.widget.workbench.CraftingInputSlot; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; @@ -158,16 +161,17 @@ protected boolean consumeRecipeItems() { for (var gathered : gatheredItems.entrySet()) { int slot = gathered.getKey(), amount = gathered.getValue(); var stack = availableHandlers.getStackInSlot(slot); + boolean hasContainer = stack.getItem().hasContainerItem(stack); - if (stack.isItemStackDamageable()) { - var usedStack = ForgeHooks.getContainerItem(stack); - availableHandlers.setStackInSlot(slot, usedStack); - } else if (stack.getItem().hasContainerItem(stack)) { - var useStack = stack.getCount() > 1 ? stack.splitStack(1) : stack; + if (hasContainer && stack.getCount() > 1) { + var useStack = stack.splitStack(1); var newStack = ForgeHooks.getContainerItem(useStack); if (newStack.isEmpty()) return false; GTTransferUtils.insertItem(this.availableHandlers, newStack, false); + } else if (hasContainer) { + var usedStack = ForgeHooks.getContainerItem(stack); + availableHandlers.setStackInSlot(slot, usedStack); } else { availableHandlers.extractItem(slot, amount, false); } @@ -264,7 +268,12 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { } else { // for shaped recipes, check the exact ingredient instead // ingredients should be in the correct order - matched = ingredients.get(index).apply(itemStack); + if (index >= 0 && index < ingredients.size()) + matched = ingredients.get(index).apply(itemStack); + else { + GTLog.logger.warn("Compacted index \"{}\" is out of bounds for list size \"{}\"", index, + ingredients.size()); + } } if (!matched) { map.put(GTUtility.copy(1, itemStack), false); @@ -307,6 +316,11 @@ private boolean simulateExtractItem(ItemStack itemStack, int count) { for (int slot : stackLookupMap.get(itemStack)) { var slotStack = availableHandlers.extractItem(slot, count, true); // we are certain the stack map is correct + if (slotStack.getItem() instanceof ItemGTToolbelt) { + // todo this doesn't work correctly + // the slots are different on the client for some reason + ItemGTToolbelt.setCraftingSlot(slot, (EntityPlayerMP) getSyncManager().getPlayer()); + } extracted += slotStack.getCount(); if (extracted >= count) return true; } @@ -344,6 +358,7 @@ public void detectAndSendChanges(boolean init) { return; } + compactedIndexes.clear(); requiredItems.clear(); refreshStackMap(); final Map map = new Int2BooleanArrayMap(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java index 1d45d9a27e0..af7f20b0b0b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeMemory.java @@ -31,6 +31,7 @@ public class CraftingRecipeMemory extends SyncHandler { public static final int OFFSET_RECIPE = 5; public static final int REMOVE_RECIPE = 2; public static final int MAKE_RECIPE = 3; + public static final int UPDATE_LOGIC = 6; // server only public static final int MOUSE_CLICK = 2; @@ -52,9 +53,15 @@ public void loadRecipe(int index) { MemorizedRecipe recipe = memorizedRecipes[index]; if (recipe != null) { copyInventoryItems(recipe.craftingMatrix, this.craftingMatrix); + getRecipeLogic().updateCurrentRecipe(); + syncToClient(UPDATE_LOGIC); } } + public CraftingRecipeLogic getRecipeLogic() { + return (CraftingRecipeLogic) getSyncManager().getSyncHandler("recipe_logic:0"); + } + @Nullable public MemorizedRecipe getRecipeAtIndex(int index) { return memorizedRecipes[index]; @@ -212,6 +219,8 @@ public void readOnClient(int id, PacketBuffer buf) { memorizedRecipes[recipe.index] = recipe; } else if (id == OFFSET_RECIPE) { this.offsetRecipe(buf.readByte()); + } else if (id == UPDATE_LOGIC) { + getRecipeLogic().updateCurrentRecipe(); } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 140d08b9f7f..78718bc6a33 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -43,6 +43,7 @@ import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.value.sync.IntSyncValue; @@ -63,7 +64,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -119,7 +119,7 @@ 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)); + NetworkUtils.writeItemStack(buf, craftingGrid.getStackInSlot(i)); } this.recipeMemory.writeInitialSyncData(buf); } @@ -128,11 +128,9 @@ public void writeInitialSyncData(@NotNull PacketBuffer buf) { 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()); - } - } catch (IOException ignored) {} + for (int i = 0; i < craftingGrid.getSlots(); i++) { + craftingGrid.setStackInSlot(i, NetworkUtils.readItemStack(buf)); + } this.recipeMemory.receiveInitialSyncData(buf); } From 1079bca9af9d332a339a10d27eafe7ae6eb0acff Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:05:43 -0700 Subject: [PATCH 163/180] sync handler on recipe logic construction move handler read into own method --- .../storage/MetaTileEntityWorkbench.java | 31 +++++++++++-------- 1 file changed, 18 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 78718bc6a33..50a6953fa0b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -182,6 +182,7 @@ public void onNeighborChanged() { Preconditions.checkState(getWorld() != null, "getRecipeResolver called too early"); if (this.recipeLogic == null) { this.recipeLogic = new CraftingRecipeLogic(getWorld(), getAvailableHandlers(), getCraftingGrid()); + writeCustomData(GregtechDataCodes.UPDATE_CLIENT_HANDLER, this::sendHandlerToClient); } return this.recipeLogic; } @@ -395,23 +396,27 @@ public void sendHandlerToClient(PacketBuffer buffer) { buffer.writeVarInt(this.connectedInventory.getSlots()); } - @Override - public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { - super.receiveCustomData(dataId, buf); - if (dataId == GregtechDataCodes.UPDATE_CLIENT_HANDLER) { - int connected = buf.readVarInt(); + public void readHandler(PacketBuffer buf) { + int connected = buf.readVarInt(); - // resize and keep any existing items + // set connected inventory + this.connectedInventory = new ItemStackHandler(connected); - // set connected inventory - this.connectedInventory = new ItemStackHandler(connected); + // set combined inventory + this.combinedInventory = new ItemHandlerList(Arrays.asList( + this.internalInventory, + this.toolInventory, + this.connectedInventory)); - // set combined inventory - this.combinedInventory = new ItemHandlerList( - Arrays.asList(this.internalInventory, this.connectedInventory)); + getCraftingRecipeLogic() + .updateInventory(this.combinedInventory); + } - getCraftingRecipeLogic() - .updateInventory(this.combinedInventory); + @Override + public void receiveCustomData(int dataId, @NotNull PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.UPDATE_CLIENT_HANDLER) { + readHandler(buf); } } From d60abe1ed03f013cfb8df1d6a82c88d3a5625709 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 19:04:47 -0700 Subject: [PATCH 164/180] simplify ToolItemStackHandler --- .../inventory/handlers/ToolItemStackHandler.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/common/inventory/handlers/ToolItemStackHandler.java b/src/main/java/gregtech/common/inventory/handlers/ToolItemStackHandler.java index 54a2d048ee1..f164b1b152e 100644 --- a/src/main/java/gregtech/common/inventory/handlers/ToolItemStackHandler.java +++ b/src/main/java/gregtech/common/inventory/handlers/ToolItemStackHandler.java @@ -1,7 +1,6 @@ package gregtech.common.inventory.handlers; -import gregtech.api.items.toolitem.IGTTool; -import gregtech.api.unification.OreDictUnifier; +import gregtech.api.items.toolitem.ToolHelper; import net.minecraft.item.ItemStack; @@ -13,19 +12,18 @@ public ToolItemStackHandler(int size) { super(size); } + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return ToolHelper.isTool(stack); + } + @Override @NotNull public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (stack.getItem().getToolClasses(stack).isEmpty()) return stack; - if (stack.getItem() instanceof IGTTool && - ((IGTTool) stack.getItem()).getToolStats().isSuitableForCrafting(stack)) { + if (isItemValid(slot, stack)) { return super.insertItem(slot, stack, simulate); } - if (stack.isItemStackDamageable() && OreDictUnifier.getOreDictionaryNames(stack).stream() - .anyMatch(s -> s.startsWith("craftingTool"))) { - return super.insertItem(slot, stack, simulate); - } return stack; } } From b34d7c9387f1ec299858cdbca3343335cfd2c1a1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 6 Feb 2025 19:11:28 -0700 Subject: [PATCH 165/180] sync slot and player for toolbelt simplify attemptMatchRecipe() add method to get base index offset from ItemHandlerList --- .../api/capability/impl/ItemHandlerList.java | 8 +++++- .../storage/CraftingRecipeLogic.java | 27 ++++++++++++++----- .../storage/MetaTileEntityWorkbench.java | 23 +++++++++++----- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java index 95a268c6314..08f8a70957b 100644 --- a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java +++ b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java @@ -6,6 +6,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -16,7 +18,7 @@ public class ItemHandlerList implements IItemHandlerModifiable { private final Int2ObjectMap handlerBySlotIndex = new Int2ObjectOpenHashMap<>(); - private final Map baseIndexOffset = new IdentityHashMap<>(); + private final Object2IntMap baseIndexOffset = new Object2IntArrayMap<>(); public ItemHandlerList(List itemHandlerList) { int currentSlotIndex = 0; @@ -33,6 +35,10 @@ public ItemHandlerList(List itemHandlerList) { } } + public int getIndexOffset(IItemHandler handler) { + return baseIndexOffset.getOrDefault(handler, -1); + } + @Override public int getSlots() { return handlerBySlotIndex.size(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index fcda98b8e24..e7cd589e5eb 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -70,6 +70,7 @@ public class CraftingRecipeLogic extends SyncHandler { this.strategy); private final Int2IntMap compactedIndexes = new Int2IntArrayMap(9); + private final Int2IntMap slotMap = new Int2IntArrayMap(); private final Map> replaceAttemptMap = new Int2ObjectArrayMap<>(); private final InventoryCrafting craftingMatrix; @@ -92,6 +93,14 @@ public InventoryCrafting getCraftingMatrix() { return this.craftingMatrix; } + public void updateSlotMap(int offset, int slot) { + slotMap.put(offset + slot, slotMap.size()); + } + + public void clearSlotMap() { + slotMap.clear(); + } + public void updateInventory(IItemHandlerModifiable handler) { this.availableHandlers = handler; } @@ -126,9 +135,8 @@ public boolean isRecipeValid() { * @return true if all items matched */ public boolean attemptMatchRecipe() { - this.requiredItems.clear(); for (CraftingInputSlot slot : this.inputSlots) { - if (!getIngredientEquivalent(slot)) { + if (!slot.hasIngredients) { return false; } } @@ -244,7 +252,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { boolean matchedPreviously = false; if (map.containsKey(itemStack)) { - if (map.get(itemStack)) { + if (map.getBoolean(itemStack)) { // cant return here before checking if: // The item is available for extraction // The recipe output is still the same, as depending on @@ -253,6 +261,12 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { } } + // this is also every tick + if (itemStack.getItem() instanceof ItemGTToolbelt) { + // we need to do this here because of ingredient apply + ItemGTToolbelt.setCraftingSlot(slotMap.get(i), (EntityPlayerMP) getSyncManager().getPlayer()); + } + if (!matchedPreviously) { // 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 @@ -286,6 +300,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { // update item in slot, and check that recipe matches and output item is equal to the expected one craftingMatrix.setInventorySlotContents(craftingIndex, itemStack); var newResult = recipe.getCraftingResult(craftingMatrix); + // this will send packets every tick for the toolbelt, not sure what can be done if ((cachedRecipeData.matches(craftingMatrix, world) && ItemStack.areItemStacksEqual(newResult, previousResult)) || recipe instanceof ShapedOreEnergyTransferRecipe) { @@ -295,7 +310,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { substitute = itemStack; break; } - map.put(itemStack.copy(), false); + map.put(GTUtility.copy(1, itemStack), false); craftingMatrix.setInventorySlotContents(craftingIndex, stack); } return substitute; @@ -317,9 +332,7 @@ private boolean simulateExtractItem(ItemStack itemStack, int count) { var slotStack = availableHandlers.extractItem(slot, count, true); // we are certain the stack map is correct if (slotStack.getItem() instanceof ItemGTToolbelt) { - // todo this doesn't work correctly - // the slots are different on the client for some reason - ItemGTToolbelt.setCraftingSlot(slot, (EntityPlayerMP) getSyncManager().getPlayer()); + ItemGTToolbelt.setCraftingSlot(slotMap.get(slot), (EntityPlayerMP) getSyncManager().getPlayer()); } extracted += slotStack.getCount(); if (extracted >= count) return true; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 50a6953fa0b..32f074426bb 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -48,7 +48,6 @@ import com.cleanroommc.modularui.utils.Alignment; 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.ButtonWidget; import com.cleanroommc.modularui.widgets.ItemSlot; @@ -57,6 +56,7 @@ import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; +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; @@ -66,6 +66,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; public class MetaTileEntityWorkbench extends MetaTileEntity { @@ -80,8 +81,8 @@ public class MetaTileEntityWorkbench extends MetaTileEntity { private final ItemStackHandler internalInventory = new GTItemStackHandler(this, 18); private final ItemStackHandler toolInventory = new ToolItemStackHandler(9); - private IItemHandlerModifiable combinedInventory; - private IItemHandlerModifiable connectedInventory; + private ItemHandlerList combinedInventory; + private ItemHandlerList connectedInventory; private final CraftingRecipeMemory recipeMemory = new CraftingRecipeMemory(9, this.craftingGrid); private CraftingRecipeLogic recipeLogic = null; @@ -202,6 +203,7 @@ public boolean usesMui2() { @Override public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager syncManager) { getCraftingRecipeLogic().updateCurrentRecipe(); + this.recipeLogic.clearSlotMap(); syncManager.syncValue("recipe_logic", this.recipeLogic); syncManager.syncValue("recipe_memory", this.recipeMemory); @@ -259,6 +261,13 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager syncManager) { .bindPlayerInventory(); } + private ModularSlot trackSlot(IItemHandler handler, int slot) { + int offset = combinedInventory.getIndexOffset(handler); + if (offset == -1) throw new NullPointerException("handler cannot be found"); + this.recipeLogic.updateSlotMap(offset, slot); + return new ModularSlot(handler, slot); + } + public IWidget createToolInventory(PanelSyncManager syncManager) { var toolSlots = new SlotGroup("tool_slots", 9, -120, true); syncManager.registerSlotGroup(toolSlots); @@ -267,7 +276,7 @@ public IWidget createToolInventory(PanelSyncManager syncManager) { .row("XXXXXXXXX") .key('X', i -> new ItemSlot() .background(GTGuiTextures.SLOT, GTGuiTextures.TOOL_SLOT_OVERLAY) - .slot(SyncHandlers.itemSlot(this.toolInventory, i) + .slot(trackSlot(this.toolInventory, i) .slotGroup(toolSlots))) .build().marginTop(2); } @@ -280,7 +289,7 @@ public IWidget createInternalInventory(PanelSyncManager syncManager) { .row("XXXXXXXXX") .row("XXXXXXXXX") .key('X', i -> new ItemSlot() - .slot(SyncHandlers.itemSlot(this.internalInventory, i) + .slot(trackSlot(this.internalInventory, i) .slotGroup(inventory))) .build().marginTop(2); } @@ -364,7 +373,7 @@ public IWidget createInventoryPage(PanelSyncManager syncManager) { int slot = itemSlot.getSlot().getSlotIndex(); return slot < this.connectedInventory.getSlots(); }) - .slot(SyncHandlers.itemSlot(this.connectedInventory, i) + .slot(trackSlot(this.connectedInventory, i) .slotGroup(connected))); } @@ -400,7 +409,7 @@ public void readHandler(PacketBuffer buf) { int connected = buf.readVarInt(); // set connected inventory - this.connectedInventory = new ItemStackHandler(connected); + this.connectedInventory = new ItemHandlerList(Collections.singletonList(new ItemStackHandler(connected))); // set combined inventory this.combinedInventory = new ItemHandlerList(Arrays.asList( From e6589f05517c5a871d0dde023d7c0fa3c211a09b Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Fri, 7 Feb 2025 14:44:29 -0700 Subject: [PATCH 166/180] don't reset selected slot in toolbelt --- src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java | 1 - 1 file changed, 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 b2ab0273a63..ab6bce96dd7 100644 --- a/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java +++ b/src/main/java/gregtech/api/items/toolitem/ItemGTToolbelt.java @@ -669,7 +669,6 @@ public boolean isItemValid(int slot, @NotNull ItemStack stack) { @Override protected void onContentsChanged(int slot) { - if (this.selectedSlot == slot) this.selectedSlot = -1; this.updateSlot(slot); this.update(); From 95aea37f9c036547fbe063087de843c87fbfb1b1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:45:08 -0700 Subject: [PATCH 167/180] fix and improve the recipe repair mixin --- .../minecraft/RecipeRepairItemMixin.java | 79 +++++++++++++------ 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/mixins/minecraft/RecipeRepairItemMixin.java b/src/main/java/gregtech/mixins/minecraft/RecipeRepairItemMixin.java index dd76f8d959c..72988b2164c 100644 --- a/src/main/java/gregtech/mixins/minecraft/RecipeRepairItemMixin.java +++ b/src/main/java/gregtech/mixins/minecraft/RecipeRepairItemMixin.java @@ -5,11 +5,11 @@ import gregtech.api.items.toolitem.ToolHelper; import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.RecipeRepairItem; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.NonNullList; -import net.minecraft.world.World; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.event.ForgeEventFactory; @@ -20,38 +20,74 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; +import java.util.Set; @Mixin(RecipeRepairItem.class) public class RecipeRepairItemMixin { - @Inject(method = "matches(Lnet/minecraft/inventory/InventoryCrafting;Lnet/minecraft/world/World;)Z", - at = @At(value = "INVOKE", - target = "Ljava/util/List;get(I)Ljava/lang/Object;", - shift = At.Shift.AFTER), - cancellable = true) - public void gregtechCEu$matches(InventoryCrafting inv, World worldIn, CallbackInfoReturnable cir, - @Local(ordinal = 0) ItemStack itemstack, @Local(ordinal = 0) List list) { - ItemStack itemstack1 = list.get(0); - if (itemstack.getItem() instanceof IGTTool first && - itemstack1.getItem() instanceof IGTTool second) { - if (first.isElectric() || second.isElectric() || - first instanceof ItemGTToolbelt || second instanceof ItemGTToolbelt) { - cir.setReturnValue(false); - } else { - cir.setReturnValue(first.getToolMaterial(itemstack) == second.getToolMaterial(itemstack1)); + @Redirect(method = "matches", + at = @At(value = "INVOKE", + ordinal = 0, + target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;")) + public Item gregtechCEu$checkFirst(ItemStack instance) { + if (instance.getItem() instanceof IGTTool) + return null; // return null to bypass item check + else return instance.getItem(); + } + + @Redirect(method = "matches", + at = @At(value = "INVOKE", + ordinal = 1, + target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;")) + public Item gregtechCEu$checkSecond(ItemStack instance) { + if (instance.getItem() instanceof IGTTool) + return null; // return null to bypass item check + else return instance.getItem(); + } + + @ModifyReturnValue(method = "matches", at = @At(value = "RETURN", ordinal = 1), remap = false) + public boolean gregtechCEu$matches(boolean b, @Local List list) { + if (!b) return false; // list size is not two + + ItemStack stack1 = list.get(0); + ItemStack stack2 = list.get(1); + + if (!(stack1.getItem() instanceof IGTTool) || stack1.getItem() instanceof ItemGTToolbelt) + return false; + + // items must be the same at this point + IGTTool first = (IGTTool) stack1.getItem(); + IGTTool second = (IGTTool) stack2.getItem(); + + // must be same material + if (first.getToolMaterial(stack1) != second.getToolMaterial(stack2)) + return false; + + // must not be electric + if (first.isElectric() || second.isElectric()) + return false; + + // must share at least one tool class + Set firstClasses = first.getToolClasses(stack1); + Set secondClasses = second.getToolClasses(stack2); + if (!firstClasses.isEmpty() && !secondClasses.isEmpty()) { + for (String toolClass : first.getToolClasses(stack1)) { + if (second.getToolClasses(stack2).contains(toolClass)) { + return true; + } } } + return false; } @Inject(method = "getCraftingResult(Lnet/minecraft/inventory/InventoryCrafting;)Lnet/minecraft/item/ItemStack;", at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/List;get(I)Ljava/lang/Object;", - ordinal = 0, - shift = At.Shift.BY, - by = 2), + ordinal = 0), cancellable = true) public void gregtechCEu$getCraftingResultFirst(InventoryCrafting inv, CallbackInfoReturnable cir, @Local(ordinal = 0) ItemStack itemstack, @@ -63,11 +99,6 @@ public class RecipeRepairItemMixin { } } - /* - * @Inject(method = "getCraftingResult(Lnet/minecraft/inventory/InventoryCrafting;)Lnet/minecraft/item/ItemStack;", - * at = @At(value = "RETURN", ordinal = 1), - * cancellable = true) - */ @ModifyReturnValue(method = "getCraftingResult", at = @At(value = "RETURN", ordinal = 1)) public ItemStack gregtechCEu$getCraftingResultSecond(ItemStack originalResult, InventoryCrafting inv, @Local(ordinal = 3) int itemDamage, From c6e68f309f77a233a9a1bb7f8566ed5f6ac5bc34 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 09:51:16 -0700 Subject: [PATCH 168/180] send handler updates on network rebuild rename method more appropriately --- .../java/gregtech/api/capability/IQuantumController.java | 2 +- .../storage/MetaTileEntityCreativeChest.java | 2 +- .../metatileentities/storage/MetaTileEntityCreativeTank.java | 2 +- .../storage/MetaTileEntityQuantumStorageController.java | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/gregtech/api/capability/IQuantumController.java b/src/main/java/gregtech/api/capability/IQuantumController.java index f2e5d333a5a..e4ebc31ba22 100644 --- a/src/main/java/gregtech/api/capability/IQuantumController.java +++ b/src/main/java/gregtech/api/capability/IQuantumController.java @@ -30,5 +30,5 @@ public interface IQuantumController extends ICapabilityProvider { long getTypeEnergy(IQuantumStorage storage); - void updateHandler(); + void onHandlerUpdate(); } diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java index 3829ae30586..cf551c5c929 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeChest.java @@ -105,7 +105,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { active = value; scheduleRenderUpdate(); var c = getQuantumController(); - if (c != null) c.updateHandler(); + if (c != null) c.onHandlerUpdate(); }, "gregtech.creative.activity.off", "gregtech.creative.activity.on")); builder.widget(createConnectedGui(6)); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java index a40d0b54bf2..b14c322745e 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeTank.java @@ -107,7 +107,7 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { active = value; scheduleRenderUpdate(); var c = getQuantumController(); - if (c != null) c.updateHandler(); + if (c != null) c.onHandlerUpdate(); }, "gregtech.creative.activity.off", "gregtech.creative.activity.on")); builder.widget(createConnectedGui(6)); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java index c4431e902a9..4bc6473d713 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityQuantumStorageController.java @@ -105,7 +105,7 @@ public void update() { buf.writeBlockPos(this.bounds[0]); buf.writeBlockPos(this.bounds[1]); }); - updateHandler(); + onHandlerUpdate(); } } } @@ -332,6 +332,7 @@ public void rebuildNetwork() { storage.setDisconnected(); } handler.rebuildCache(); + onHandlerUpdate(); calculateEnergyUsage(); markDirty(); } @@ -344,7 +345,7 @@ private static boolean checkStorageNeighbor(MetaTileEntity mte, EnumFacing facin } @Override - public void updateHandler() { + public void onHandlerUpdate() { if (getWorld().isRemote) return; notifyBlockUpdate(); for (var pos : typePosMap.get(PROXY)) { From 3cf0134c1b9ca46962155becfca1fe23bef94bc0 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:00:18 -0700 Subject: [PATCH 169/180] format amount crafted better --- .../storage/MetaTileEntityWorkbench.java | 11 +++++++++-- 1 file changed, 9 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 32f074426bb..561252be877 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.mui.sync.PagedWidgetSyncHandler; import gregtech.api.util.GTUtility; +import gregtech.api.util.TextFormattingUtil; import gregtech.client.renderer.texture.Textures; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; @@ -332,8 +333,14 @@ public IWidget createCraftingOutput(PosGuiData guiData, PanelSyncManager syncMan .marginTop(18) .background(GTGuiTextures.SLOT.asIcon().size(22)) .marginBottom(4)) - .child(IKey.dynamic(amountCrafted::getStringValue) - .alignment(Alignment.Center) + .child(IKey.dynamic(() -> { + int amount = amountCrafted.getIntValue(); + if (amount > 1000) { + return TextFormattingUtil.formatLongToCompactString(amount); + } else { + return TextFormattingUtil.formatNumbers(amount); + } + }).alignment(Alignment.Center) .asWidget().widthRel(1f)); } From ca9996ec6f08cf08bddf96e4cc6952a41509668f Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:10:01 -0700 Subject: [PATCH 170/180] add line for removing recipe --- .../gregtech/common/mui/widget/workbench/RecipeMemorySlot.java | 1 + src/main/resources/assets/gregtech/lang/en_us.lang | 1 + 2 files changed, 2 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 03d9d6728ec..2d24eea1d83 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/RecipeMemorySlot.java @@ -37,6 +37,7 @@ public RecipeMemorySlot(CraftingRecipeMemory memory, int index) { 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.3")); tooltip.addLine(IKey.lang("gregtech.recipe_memory_widget.tooltip.0", recipe.timesUsed) .style(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 85657dc9953..69f6287581e 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1214,6 +1214,7 @@ 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 +gregtech.recipe_memory_widget.tooltip.3=§7Right click to remove this recipe if it is unlocked cover.filter.blacklist.disabled=Whitelist cover.filter.blacklist.enabled=Blacklist From d793acfad779e820fed785568bfdc01fcc72c232 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:17:07 -0700 Subject: [PATCH 171/180] only sync mouse click if recipe is valid store player in variable simplify empty slot insertion --- .../widget/workbench/CraftingOutputSlot.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 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 da3c8d21dbc..d77193dd698 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -31,7 +31,6 @@ 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.util.ArrayList; import java.util.Comparator; @@ -67,7 +66,9 @@ public boolean isValidSyncHandler(SyncHandler syncHandler) { @Override public @NotNull Result onMousePressed(int mouseButton) { MouseData mouseData = MouseData.create(mouseButton); - this.syncHandler.syncToServer(MOUSE_CLICK, mouseData::writeToPacket); + // if there's a valid recipe, then the output slot should not be empty + if (!getIngredient().isEmpty()) + this.syncHandler.syncToServer(MOUSE_CLICK, mouseData::writeToPacket); return Result.SUCCESS; } @@ -88,7 +89,7 @@ public void drawForeground(ModularGuiContext context) { } @Override - public @Nullable ItemStack getIngredient() { + public @NotNull ItemStack getIngredient() { return this.syncHandler.getOutputStack(); } @@ -123,10 +124,11 @@ public void init(String key, PanelSyncManager syncManager) { @Override public void readOnServer(int id, PacketBuffer buf) { if (id == MOUSE_CLICK) { - ForgeHooks.setCraftingPlayer(getSyncManager().getPlayer()); + EntityPlayer player = getSyncManager().getPlayer(); + ForgeHooks.setCraftingPlayer(player); var data = MouseData.readPacket(buf); - if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(getSyncManager().getPlayer())) { + if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(player)) { ItemStack cursorStack = getSyncManager().getCursorItem(); ItemStack outputStack = getOutputStack(); boolean hasSpace; @@ -137,7 +139,7 @@ public void readOnServer(int id, PacketBuffer buf) { ItemHandlerHelper.canItemStacksStack(cursorStack, outputStack); } if (hasSpace && recipeLogic.performRecipe()) { - handleItemCraft(outputStack, getSyncManager().getPlayer()); + handleItemCraft(outputStack, player); if (data.shift) { ItemStack finalStack = outputStack.copy(); @@ -145,7 +147,7 @@ public void readOnServer(int id, PacketBuffer buf) { finalStack.getCount() < outputStack.getMaxStackSize()) { if (!recipeLogic.performRecipe()) break; finalStack.setCount(finalStack.getCount() + outputStack.getCount()); - handleItemCraft(outputStack, getSyncManager().getPlayer()); + handleItemCraft(outputStack, player); } quickTransfer(finalStack, false); } else { @@ -200,11 +202,8 @@ public boolean quickTransfer(ItemStack fromStack, boolean simulate) { } } for (ModularSlot emptySlot : emptySlots) { - ItemStack itemstack = emptySlot.getStack(); - if (emptySlot.isEnabled() && itemstack.isEmpty() && emptySlot.isItemValid(fromStack)) { - if (insertStack(fromStack, emptySlot, simulate)) { - if (simulate || fromStack.isEmpty()) return true; - } + if (insertStack(fromStack, emptySlot, simulate)) { + if (simulate || fromStack.isEmpty()) return true; } } return false; From 845c974cf568a7099bd1cdca9c7d4a4c59ca09c8 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:25:31 -0700 Subject: [PATCH 172/180] fix output slot shift clicking with full cursor item --- .../mui/widget/workbench/CraftingOutputSlot.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 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 d77193dd698..a07f52ee396 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -128,15 +128,13 @@ public void readOnServer(int id, PacketBuffer buf) { ForgeHooks.setCraftingPlayer(player); var data = MouseData.readPacket(buf); - if (recipeLogic.isRecipeValid() && this.slot.canTakeStack(player)) { - ItemStack cursorStack = getSyncManager().getCursorItem(); + if (recipeLogic.isRecipeValid()) { ItemStack outputStack = getOutputStack(); boolean hasSpace; if (data.shift) { hasSpace = quickTransfer(getOutputStack(), true); } else { - hasSpace = cursorStack.isEmpty() || - ItemHandlerHelper.canItemStacksStack(cursorStack, outputStack); + hasSpace = this.slot.canTakeStack(player); } if (hasSpace && recipeLogic.performRecipe()) { handleItemCraft(outputStack, player); @@ -278,10 +276,7 @@ public boolean canTakeStack(EntityPlayer playerIn) { if (curStack.isEmpty()) return true; ItemStack outStack = recipeLogic.getCachedRecipe().getRecipeOutput(); - if (curStack.getItem() == outStack.getItem() && - curStack.getMetadata() == outStack.getMetadata() && - ItemStack.areItemStackTagsEqual(curStack, outStack)) { - + if (ItemHandlerHelper.canItemStacksStack(curStack, outStack)) { int combined = curStack.getCount() + outStack.getCount(); return combined <= outStack.getMaxStackSize(); } else { From 5443fb9f8155cb1db647839d09eeb49392917886 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:27:11 -0700 Subject: [PATCH 173/180] merge if statements clarify slot insertion --- .../mui/widget/workbench/CraftingOutputSlot.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 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 a07f52ee396..a43973a47ae 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -160,16 +160,18 @@ public void readOnServer(int id, PacketBuffer buf) { 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 combined = toStack.getCount() + fromStack.getCount(); int maxSize = Math.min(toSlot.getSlotStackLimit(), fromStack.getMaxStackSize()); - if (j <= maxSize) { + // we can fit all of toStack + if (combined <= maxSize) { if (simulate) return true; fromStack.setCount(0); - toStack.setCount(j); + toStack.setCount(combined); toSlot.putStack(toStack); } else if (toStack.getCount() < maxSize) { if (simulate) return true; + // we can fit some of toStack, but not all fromStack.shrink(maxSize - toStack.getCount()); toStack.setCount(maxSize); toSlot.putStack(toStack); @@ -244,10 +246,10 @@ public void handleItemCraft(ItemStack craftedStack, EntityPlayer player) { FMLCommonHandler.instance().firePlayerCraftingEvent(player, craftedStack, inventoryCrafting); var cachedRecipe = recipeLogic.getCachedRecipe(); - if (cachedRecipe != null && !cachedRecipe.isDynamic()) { - player.unlockRecipes(Lists.newArrayList(cachedRecipe)); - } if (cachedRecipe != null) { + if (!cachedRecipe.isDynamic()) { + player.unlockRecipes(Lists.newArrayList(cachedRecipe)); + } ItemStack resultStack = cachedRecipe.getCraftingResult(inventoryCrafting); this.slot.notifyRecipePerformed(resultStack); } From b488da67ab894463f06f37b805f1b76d67d17a1d Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 10:52:12 -0700 Subject: [PATCH 174/180] improve and clarify sync cursor item --- .../widget/workbench/CraftingOutputSlot.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 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 a43973a47ae..ea484cdd903 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -149,7 +149,7 @@ public void readOnServer(int id, PacketBuffer buf) { } quickTransfer(finalStack, false); } else { - syncToClient(SYNC_STACK, this::syncCraftedStack); + syncToClient(SYNC_STACK, this::syncCursorStack); } } } @@ -211,26 +211,24 @@ public boolean quickTransfer(ItemStack fromStack, boolean simulate) { @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == SYNC_STACK) { + if (id == SYNC_STACK && buf.readBoolean()) { getSyncManager().setCursorItem(NetworkUtils.readItemStack(buf)); } } - private void syncCraftedStack(PacketBuffer buf) { + private void syncCursorStack(PacketBuffer buf) { ItemStack curStack = getSyncManager().getCursorItem(); ItemStack outStack = this.slot.getStack(); - ItemStack toSync = outStack.copy(); - if (ItemHandlerHelper.canItemStacksStack(curStack, outStack)) { + if (this.slot.canTakeStack(getSyncManager().getPlayer())) { + ItemStack toSync = outStack.copy(); 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; + // clamp to max stack size + toSync.setCount(Math.min(combined, outStack.getMaxStackSize())); + buf.writeBoolean(true); + NetworkUtils.writeItemStack(buf, toSync); + } else { + buf.writeBoolean(false); } - NetworkUtils.writeItemStack(buf, toSync); } public ItemStack getOutputStack() { @@ -277,7 +275,7 @@ public boolean canTakeStack(EntityPlayer playerIn) { ItemStack curStack = playerIn.inventory.getItemStack(); if (curStack.isEmpty()) return true; - ItemStack outStack = recipeLogic.getCachedRecipe().getRecipeOutput(); + ItemStack outStack = getStack(); if (ItemHandlerHelper.canItemStacksStack(curStack, outStack)) { int combined = curStack.getCount() + outStack.getCount(); return combined <= outStack.getMaxStackSize(); From 2f2df84ae6846f64b5936f13dbb22a0fa06647bf Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:07:09 -0700 Subject: [PATCH 175/180] annotations --- .../common/mui/widget/workbench/CraftingOutputSlot.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 ea484cdd903..b797c8bc220 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -316,17 +316,17 @@ public int getSlots() { } @Override - public ItemStack getStackInSlot(int slot) { + public @NotNull ItemStack getStackInSlot(int slot) { return inventory.getStackInSlot(slot).copy(); } @Override - public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { return stack; } @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { + public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { return inventory.getStackInSlot(slot); } @@ -336,7 +336,7 @@ public int getSlotLimit(int slot) { } @Override - public void setStackInSlot(int slot, ItemStack stack) { + public void setStackInSlot(int slot, @NotNull ItemStack stack) { if (!recipeLogic.isRecipeValid()) { inventory.setInventorySlotContents(slot, ItemStack.EMPTY); } From f750d95f204d5d251369624b7d1799c9b0b197a2 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:19:42 -0700 Subject: [PATCH 176/180] improve formatting a bit more use format number for easy case in compact string --- .../java/gregtech/api/util/TextFormattingUtil.java | 2 +- .../storage/MetaTileEntityWorkbench.java | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/api/util/TextFormattingUtil.java b/src/main/java/gregtech/api/util/TextFormattingUtil.java index 00a1f5f0aea..ba3e3606f43 100644 --- a/src/main/java/gregtech/api/util/TextFormattingUtil.java +++ b/src/main/java/gregtech/api/util/TextFormattingUtil.java @@ -20,7 +20,7 @@ public class TextFormattingUtil { public static String formatLongToCompactString(long value, int precision) { if (value == 0 || Math.abs(value) < Math.pow(10, precision)) { - return Long.toString(value); // deal with easy case + return formatNumbers(value); // deal with easy case } StringBuilder stb = new StringBuilder(); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 561252be877..e234161aa73 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -333,14 +333,8 @@ public IWidget createCraftingOutput(PosGuiData guiData, PanelSyncManager syncMan .marginTop(18) .background(GTGuiTextures.SLOT.asIcon().size(22)) .marginBottom(4)) - .child(IKey.dynamic(() -> { - int amount = amountCrafted.getIntValue(); - if (amount > 1000) { - return TextFormattingUtil.formatLongToCompactString(amount); - } else { - return TextFormattingUtil.formatNumbers(amount); - } - }).alignment(Alignment.Center) + .child(IKey.dynamic(() -> TextFormattingUtil.formatLongToCompactString(amountCrafted.getIntValue(), 5)) + .alignment(Alignment.Center) .asWidget().widthRel(1f)); } From 36d713ce0d612fba69b0047d6ce5ecc5c5a5dc51 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:28:41 -0700 Subject: [PATCH 177/180] simplify CraftingOutputSlot MS and SH constructor rename int sync value to be more appropriate --- .../widget/workbench/CraftingOutputSlot.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 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 b797c8bc220..db766fe50bf 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingOutputSlot.java @@ -43,11 +43,8 @@ public class CraftingOutputSlot extends Widget implements In private static final int SYNC_STACK = 5; private final CraftingSlotSH syncHandler; - public CraftingOutputSlot(IntSyncValue syncValue, MetaTileEntityWorkbench workbench) { - this.syncHandler = new CraftingSlotSH( - new CraftingOutputMS( - workbench.getCraftingRecipeLogic().getCraftingResultInventory(), - syncValue, workbench)); + public CraftingOutputSlot(IntSyncValue amountCrafted, MetaTileEntityWorkbench workbench) { + this.syncHandler = new CraftingSlotSH(amountCrafted, workbench); setSyncHandler(this.syncHandler); tooltipAutoUpdate(true); tooltipBuilder(tooltip -> { @@ -100,8 +97,8 @@ protected static class CraftingSlotSH extends SyncHandler { private final List shiftClickSlots = new ArrayList<>(); - public CraftingSlotSH(CraftingOutputMS slot) { - this.slot = slot; + public CraftingSlotSH(IntSyncValue amountCrafted, MetaTileEntityWorkbench workbench) { + this.slot = new CraftingOutputMS(amountCrafted, workbench); this.recipeLogic = slot.recipeLogic; } @@ -256,15 +253,16 @@ public void handleItemCraft(ItemStack craftedStack, EntityPlayer player) { protected static class CraftingOutputMS extends ModularSlot { - private final IntSyncValue syncValue; + private final IntSyncValue amountCrafted; private final CraftingRecipeLogic recipeLogic; private final CraftingRecipeMemory recipeMemory; private final IItemHandler craftingGrid; - public CraftingOutputMS(IInventory craftingInventory, IntSyncValue syncValue, - MetaTileEntityWorkbench workbench) { - super(new InventoryWrapper(craftingInventory, workbench.getCraftingRecipeLogic()), 0, true); - this.syncValue = syncValue; + public CraftingOutputMS(IntSyncValue amountCrafted, MetaTileEntityWorkbench workbench) { + super(new InventoryWrapper( + workbench.getCraftingRecipeLogic().getCraftingResultInventory(), + workbench.getCraftingRecipeLogic()), 0, true); + this.amountCrafted = amountCrafted; this.recipeLogic = workbench.getCraftingRecipeLogic(); this.recipeMemory = workbench.getRecipeMemory(); this.craftingGrid = workbench.getCraftingGrid(); @@ -285,7 +283,7 @@ public boolean canTakeStack(EntityPlayer playerIn) { } public void notifyRecipePerformed(ItemStack stack) { - this.syncValue.setValue(this.syncValue.getValue() + stack.getCount(), true, true); + this.amountCrafted.setValue(this.amountCrafted.getValue() + stack.getCount(), true, true); this.recipeMemory.notifyRecipePerformed(this.craftingGrid, stack); } From aabe7231b79c0d59f10de766ccb1c53495aae6fe Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Wed, 12 Feb 2025 12:13:18 -0700 Subject: [PATCH 178/180] remove unused method move ingredient list to CachedRecipeData apply the ingredient to the stack when extracting --- .../storage/CachedRecipeData.java | 23 +++++++ .../storage/CraftingRecipeLogic.java | 66 ++++--------------- 2 files changed, 35 insertions(+), 54 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java index f40d7b37d32..be5716f65fb 100755 --- a/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java @@ -1,15 +1,23 @@ package gregtech.common.metatileentities.storage; +import gregtech.api.util.GTLog; + 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 org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + public class CachedRecipeData { private IRecipe recipe; private IRecipe previousRecipe; + private final List recipeIngredients = new ArrayList<>(); public CachedRecipeData() { this(null); @@ -29,6 +37,11 @@ public boolean matches(InventoryCrafting inventoryCrafting, World world) { public void setRecipe(IRecipe newRecipe) { this.previousRecipe = this.recipe; this.recipe = newRecipe; + this.recipeIngredients.clear(); + if (newRecipe != null) { + this.recipeIngredients.addAll(newRecipe.getIngredients()); + this.recipeIngredients.removeIf(ing -> ing == Ingredient.EMPTY); + } } public IRecipe getRecipe() { @@ -38,4 +51,14 @@ public IRecipe getRecipe() { public IRecipe getPreviousRecipe() { return previousRecipe; } + + public boolean canIngredientApply(int index, ItemStack stack) { + if (this.recipeIngredients.isEmpty()) return false; + if (index < 0 || index >= this.recipeIngredients.size()) { + GTLog.logger.warn("Compacted index \"{}\" is out of bounds for list size \"{}\"", index, + this.recipeIngredients.size()); + return false; + } + return this.recipeIngredients.get(index).apply(stack); + } } diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index e7cd589e5eb..4557d28a9df 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.ItemGTToolbelt; 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; @@ -64,7 +63,7 @@ public class CraftingRecipeLogic extends SyncHandler { /** * List of items needed to complete the crafting recipe, filled by - * {@link CraftingRecipeLogic#getIngredientEquivalent(CraftingInputSlot)} )} + * {@link CraftingRecipeLogic#detectAndSendChanges(boolean)} )} **/ private final Map requiredItems = new Object2IntOpenCustomHashMap<>( this.strategy); @@ -188,43 +187,6 @@ protected boolean consumeRecipeItems() { return extracted; } - /** - *

- * 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 true if the stack in the slot can be extracted or has a valid substitute - */ - public boolean getIngredientEquivalent(CraftingInputSlot slot) { - ItemStack currentStack = slot.getStack(); - if (currentStack.isEmpty()) { - return true; // stack is empty, nothing to return - } - - int count = requiredItems.getOrDefault(currentStack, 0); - if (simulateExtractItem(currentStack, count + 1)) { - requiredItems.put(currentStack, ++count); - return true; - } - - 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 @@ -241,8 +203,6 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { ItemStack substitute = ItemStack.EMPTY; var recipe = getCachedRecipe(); - List ingredients = new ArrayList<>(recipe.getIngredients()); - ingredients.removeIf(ingredient -> ingredient == Ingredient.EMPTY); int index = compactedIndexes.get(craftingIndex); // iterate stored items to find equivalent @@ -273,7 +233,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { // take the stack boolean matched = false; if (!(recipe instanceof IShapedRecipe)) { - for (Ingredient ing : ingredients) { + for (Ingredient ing : recipe.getIngredients()) { if (ing.apply(itemStack)) { matched = true; break; @@ -282,12 +242,7 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { } else { // for shaped recipes, check the exact ingredient instead // ingredients should be in the correct order - if (index >= 0 && index < ingredients.size()) - matched = ingredients.get(index).apply(itemStack); - else { - GTLog.logger.warn("Compacted index \"{}\" is out of bounds for list size \"{}\"", index, - ingredients.size()); - } + matched = cachedRecipeData.canIngredientApply(index, itemStack); } if (!matched) { map.put(GTUtility.copy(1, itemStack), false); @@ -319,10 +274,11 @@ public ItemStack findSubstitute(int craftingIndex, ItemStack stack) { /** * Attempts to extract the given stack from connected inventories * - * @param itemStack stack from the crafting matrix + * @param craftingIndex current crafting index + * @param itemStack stack from the crafting matrix * @return true if the stack was successfully extracted or the stack is empty */ - private boolean simulateExtractItem(ItemStack itemStack, int count) { + private boolean simulateExtractItem(int craftingIndex, ItemStack itemStack, int count) { if (itemStack.isEmpty()) return true; if (!stackLookupMap.containsKey(itemStack)) return false; @@ -334,8 +290,10 @@ private boolean simulateExtractItem(ItemStack itemStack, int count) { if (slotStack.getItem() instanceof ItemGTToolbelt) { ItemGTToolbelt.setCraftingSlot(slotMap.get(slot), (EntityPlayerMP) getSyncManager().getPlayer()); } - extracted += slotStack.getCount(); - if (extracted >= count) return true; + if (cachedRecipeData.canIngredientApply(compactedIndexes.get(craftingIndex), slotStack)) { + extracted += slotStack.getCount(); + if (extracted >= count) return true; + } } return false; @@ -391,7 +349,7 @@ public void detectAndSendChanges(boolean init) { compactedIndexes.put(slot.getIndex(), next++); int count = requiredItems.getOrDefault(slotStack, 0) + 1; - slot.hasIngredients = simulateExtractItem(slotStack, count); + slot.hasIngredients = simulateExtractItem(slot.getIndex(), slotStack, count); if (slot.hasIngredients) { requiredItems.put(GTUtility.copy(1, slotStack), count); @@ -400,7 +358,7 @@ public void detectAndSendChanges(boolean init) { ItemStack substitute = findSubstitute(slot.getIndex(), slotStack); if (!substitute.isEmpty()) { count = requiredItems.getOrDefault(substitute, 0) + 1; - slot.hasIngredients = simulateExtractItem(substitute, count); + slot.hasIngredients = simulateExtractItem(slot.getIndex(), substitute, count); requiredItems.put(GTUtility.copy(1, substitute), count); } } From 40185124e6b5fb32f47510e83c0e147225956889 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 13 Feb 2025 09:12:17 -0700 Subject: [PATCH 179/180] fix oversight in ItemHandlerList --- .../java/gregtech/api/capability/impl/ItemHandlerList.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java index 08f8a70957b..ffb12d0dcd6 100644 --- a/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java +++ b/src/main/java/gregtech/api/capability/impl/ItemHandlerList.java @@ -48,11 +48,12 @@ public int getSlots() { public void setStackInSlot(int slot, @NotNull ItemStack stack) { if (invalidSlot(slot)) return; IItemHandler itemHandler = handlerBySlotIndex.get(slot); + int actualSlot = slot - baseIndexOffset.get(itemHandler); if (itemHandler instanceof IItemHandlerModifiable modifiable) { - modifiable.setStackInSlot(slot - baseIndexOffset.get(itemHandler), stack); + modifiable.setStackInSlot(actualSlot, stack); } else { - itemHandler.extractItem(slot, Integer.MAX_VALUE, false); - itemHandler.insertItem(slot, stack, false); + itemHandler.extractItem(actualSlot, Integer.MAX_VALUE, false); + itemHandler.insertItem(actualSlot, stack, false); } } From a6dbac5b43304c96137f740fc5c2377256170df1 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 13 Feb 2025 21:46:29 -0700 Subject: [PATCH 180/180] clarify gui actions and simplify syncing changes compact ids simplify crate change listener address todo only interact when not ghost dragging --- .../storage/CraftingRecipeLogic.java | 5 +++-- .../storage/MetaTileEntityCrate.java | 12 ++++++------ .../storage/MetaTileEntityWorkbench.java | 4 +--- .../mui/widget/workbench/CraftingInputSlot.java | 17 ++++++----------- .../gregtech/mixins/mui2/ModularPanelMixin.java | 4 ++-- 5 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java index 4557d28a9df..073d662369b 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java +++ b/src/main/java/gregtech/common/metatileentities/storage/CraftingRecipeLogic.java @@ -30,6 +30,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenCustomHashMap; @@ -43,7 +44,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; + public static final int SYNC_STACK = 3; // server only public static final int UPDATE_MATRIX = 0; @@ -71,7 +72,7 @@ public class CraftingRecipeLogic extends SyncHandler { private final Int2IntMap compactedIndexes = new Int2IntArrayMap(9); private final Int2IntMap slotMap = new Int2IntArrayMap(); - private final Map> replaceAttemptMap = new Int2ObjectArrayMap<>(); + private final Int2ObjectMap> replaceAttemptMap = new Int2ObjectArrayMap<>(); private final InventoryCrafting craftingMatrix; private final IInventory craftingResultInventory = new InventoryCraftResult(); private final CachedRecipeData cachedRecipeData; diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java index 3e00c251170..d837e3bcd80 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCrate.java @@ -152,12 +152,12 @@ 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 && !init) { - for (var facing : EnumFacing.VALUES) { - var neighbor = getNeighbor(facing); - if (neighbor instanceof IGregTechTileEntity gregTechTileEntity) { - gregTechTileEntity.getMetaTileEntity().onNeighborChanged(); - } + if (client || init) return; + + for (var facing : EnumFacing.VALUES) { + var neighbor = getNeighbor(facing); + if (neighbor instanceof IGregTechTileEntity gtte) { + gtte.getMetaTileEntity().onNeighborChanged(); } } }))); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index e234161aa73..6da4abc4031 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -325,7 +325,6 @@ 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); // todo remove on mui2 rc3 return Flow.column() .size(54) @@ -418,8 +417,7 @@ public void readHandler(PacketBuffer buf) { this.toolInventory, this.connectedInventory)); - getCraftingRecipeLogic() - .updateInventory(this.combinedInventory); + getCraftingRecipeLogic().updateInventory(this.combinedInventory); } @Override 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 0d45bdd1355..b1521bfe39f 100644 --- a/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java +++ b/src/main/java/gregtech/common/mui/widget/workbench/CraftingInputSlot.java @@ -43,6 +43,7 @@ private CraftingInputSlot(IItemHandlerModifiable handler, int index) { tooltip.addFromItem(stack); }); + // for hovering with items in hand listenGuiAction((IGuiAction.MouseDrag) (m, t) -> { if (isHovering() && dragging && syncHandler.isValid()) { var player = syncHandler.getSyncManager().getCursorItem(); @@ -53,6 +54,7 @@ private CraftingInputSlot(IItemHandlerModifiable handler, int index) { return false; }); + // dragging has stopped listenGuiAction((IGuiAction.MouseReleased) mouseButton -> { dragging = false; return true; @@ -162,7 +164,7 @@ public InputSyncHandler(IItemHandlerModifiable handler, int index) { @Override public void init(String key, PanelSyncManager syncHandler) { super.init(key, syncHandler); - this.lastStoredItem = this.handler.getStackInSlot(this.index).copy(); + this.lastStoredItem = getStack().copy(); } @Override @@ -185,16 +187,9 @@ public void readOnServer(int id, PacketBuffer buf) { 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(); - } + if (init || !ItemHandlerHelper.canItemStacksStack(this.lastStoredItem, itemStack)) { + this.listener.onChange(itemStack, false, false, init); + this.lastStoredItem = itemStack.isEmpty() ? ItemStack.EMPTY : itemStack.copy(); syncToClient(SLOT_CHANGED, buffer -> NetworkUtils.writeItemStack(buffer, itemStack)); } } diff --git a/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java b/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java index 05d287c9610..16e4a2b6b8c 100644 --- a/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java +++ b/src/main/java/gregtech/mixins/mui2/ModularPanelMixin.java @@ -68,9 +68,9 @@ public abstract class ModularPanelMixin extends ParentWidget imple loop: for (LocatedWidget widget : this.hovering) { widget.applyMatrix(getContext()); + GhostIngredientDrag drag = gregTech$getGhostDrag(); if (widget.getElement() instanceof JeiGhostIngredientSlotghostSlot && Mods.JustEnoughItems.isModLoaded()) { - GhostIngredientDrag drag = gregTech$getGhostDrag(); if (drag != null && gregTech$insertGhostIngredient(drag, ghostSlot)) { gregTech$stopDrag(); pressed = LocatedWidget.EMPTY; @@ -79,7 +79,7 @@ public abstract class ModularPanelMixin extends ParentWidget imple break; } } - if (widget.getElement() instanceof Interactable interactable) { + if (drag == null && widget.getElement() instanceof Interactable interactable) { switch (interactable.onMousePressed(mouseButton)) { case IGNORE: break;