From 0c80918e4bc2648e5dded969a2d2856e3319382f Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Tue, 23 Dec 2025 17:51:34 +0100 Subject: [PATCH 01/18] Backport dupefix Refrence https://github.com/MrTJP/ProjectRed/issues/1458 https://github.com/MrTJP/ProjectRed/commit/6f8b966c514d2732d40605663c071d54b51cad00 --- .../mrtjp/projectred/expansion/TileProjectBench.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 46ece47f6..b413dbb53 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -348,6 +348,13 @@ class ContainerProjectBench(player: EntityPlayer, tile: TileProjectBench) super.slotClick(id, mouse, mode, player) } + override def transferStackInSlot(player:EntityPlayer, i:Int):ItemStack = { + if (i == 28 && !getSlot(28).canTakeStack(player)) + null + else + super.transferStackInSlot(player, i) + } + override def doMerge(stack: ItemStack, from: Int): Boolean = { if (0 until 9 contains from) // crafting grid { From 3ed7be1c99f51b96757a2f3ef1e45fcb5fc6989d Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Tue, 23 Dec 2025 18:08:31 +0100 Subject: [PATCH 02/18] Spotless :( --- .../scala/mrtjp/projectred/expansion/TileProjectBench.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index b413dbb53..c82c80bf6 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -348,7 +348,7 @@ class ContainerProjectBench(player: EntityPlayer, tile: TileProjectBench) super.slotClick(id, mouse, mode, player) } - override def transferStackInSlot(player:EntityPlayer, i:Int):ItemStack = { + override def transferStackInSlot(player: EntityPlayer, i: Int): ItemStack = { if (i == 28 && !getSlot(28).canTakeStack(player)) null else From 0a6335e5caffad223a8263f6315d7434f679488b Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 02:38:51 +0100 Subject: [PATCH 03/18] Remove slotClick that doesnt work anyhow --- dependencies.gradle | 5 +++++ .../mrtjp/projectred/expansion/TileProjectBench.scala | 11 ----------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index a7b536302..4f53f783f 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -8,6 +8,11 @@ dependencies { compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.14.6-GTNH:dev") {transitive = false} compileOnly("com.github.GTNewHorizons:StorageDrawers:2.2.1-GTNH:dev") {transitive = false} + runtimeOnly("com.github.GTNewHorizons:OpenComputers:1.12.4-GTNH:dev") {transitive = false} + runtimeOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.52.152:dev') { + exclude group: 'com.github.GTNewHorizons', module: 'ProjectRed' + } + compileOnly("curse.maven:cofh-core-69162:2388751") compileOnly("curse.maven:computercraft-67504:2269339") // https://www.curseforge.com/minecraft/mc-mods/computercraft/files/2269339 compileOnly files("dependencies/ColoredLightsCore-1.3.7.39.jar") diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index c82c80bf6..4cc0bc05a 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -337,17 +337,6 @@ class ContainerProjectBench(player: EntityPlayer, tile: TileProjectBench) detectAndSendChanges() } - override def slotClick( - id: Int, - mouse: Int, - shift: Int, - player: EntityPlayer - ) = { - var mode = shift - if (id == 28 && mode == 6) mode = 0 - super.slotClick(id, mouse, mode, player) - } - override def transferStackInSlot(player: EntityPlayer, i: Int): ItemStack = { if (i == 28 && !getSlot(28).canTakeStack(player)) null From 28ea0fca17e80948da84df792c239ef3d1f998e8 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 03:07:50 +0100 Subject: [PATCH 04/18] Make ItemPlan behave like AE2 Patterns when holding Shift Fix https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/14182 --- .../expansion/TileAutoCrafter.scala | 9 ------ .../expansion/TileProjectBench.scala | 32 ------------------- .../mrtjp/projectred/expansion/items.scala | 19 +++++++---- 3 files changed, 12 insertions(+), 48 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala index 7c1421194..02b32d1bb 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala @@ -349,15 +349,6 @@ class GuiAutoCrafter(tile: TileAutoCrafter, c: ContainerAutoCrafter) GuiDraw.drawString("Auto Crafting Bench", 8, 6, Colors.GREY.argb, false) GuiDraw.drawString("Inventory", 8, 120, Colors.GREY.argb, false) } - - override def drawFront_Impl(mouse: Point, rframe: Float) { - if ( - Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown( - Keyboard.KEY_RSHIFT - ) - ) - GuiProjectBench.drawPlanOutputOverlay(c.slots) - } } object GuiAutoCrafter extends TGuiBuilder { diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 4cc0bc05a..1963d38f3 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -451,15 +451,6 @@ class GuiProjectBench(tile: TileProjectBench, c: ContainerProjectBench) GuiDraw.drawString("Project Bench", 8, 6, Colors.GREY.argb, false) GuiDraw.drawString("Inventory", 8, 116, Colors.GREY.argb, false) } - - override def drawFront_Impl(mouse: Point, rframe: Float) { - if ( - Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown( - Keyboard.KEY_RSHIFT - ) - ) - GuiProjectBench.drawPlanOutputOverlay(c.slots) - } } object GuiProjectBench extends TGuiBuilder { @@ -473,29 +464,6 @@ object GuiProjectBench extends TGuiBuilder { case _ => null } } - - def drawPlanOutputOverlay(slots: Iterable[TSlot3]) { - for (slot <- slots) if (slot.getHasStack) { - val stack = slot.getStack - if (ItemPlan.hasRecipeInside(stack)) { - val output = ItemPlan.loadPlanOutput(stack) - GuiDraw.drawRect( - slot.xDisplayPosition, - slot.yDisplayPosition, - 16, - 16, - Colors.LIGHT_BLUE.argb(0xcc) - ) - ItemDisplayNode.renderItem( - Point(slot.xDisplayPosition + 1, slot.yDisplayPosition + 1), - Size(14, 14), - 0, - true, - output - ) - } - } - } } object RenderProjectBench extends TCubeMapRender { diff --git a/src/main/scala/mrtjp/projectred/expansion/items.scala b/src/main/scala/mrtjp/projectred/expansion/items.scala index 5f801f41e..c176da5bb 100644 --- a/src/main/scala/mrtjp/projectred/expansion/items.scala +++ b/src/main/scala/mrtjp/projectred/expansion/items.scala @@ -6,7 +6,6 @@ package mrtjp.projectred.expansion import java.util.{List => JList} - import codechicken.lib.packet.PacketCustom import codechicken.lib.vec.{BlockCoord, Rotation, Translation, Vector3} import cpw.mods.fml.common.FMLCommonHandler @@ -22,11 +21,7 @@ import mrtjp.projectred.api.IScrewdriver import net.minecraft.client.Minecraft import net.minecraft.client.model.{ModelBiped, ModelRenderer} import net.minecraft.client.renderer.texture.IIconRegister -import net.minecraft.enchantment.{ - EnchantmentHelper, - Enchantment, - EnumEnchantmentType -} +import net.minecraft.enchantment.{Enchantment, EnchantmentHelper, EnumEnchantmentType} import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.{Entity, EntityLivingBase} import net.minecraft.init.Blocks @@ -37,6 +32,7 @@ import net.minecraft.util.{DamageSource, EnumChatFormatting, IIcon} import net.minecraft.world.World import net.minecraftforge.common.ISpecialArmor import net.minecraftforge.common.ISpecialArmor.ArmorProperties +import org.lwjgl.input.Keyboard import scala.collection.mutable.{Set => MSet} @@ -184,7 +180,16 @@ class ItemPlan extends ItemCore("projectred.expansion.plan") { var iconWritten: IIcon = null override def getIconIndex(stack: ItemStack) = - if (ItemPlan.hasRecipeInside(stack)) iconWritten else iconBlank + if (ItemPlan.hasRecipeInside(stack)) + if ( + Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown( + Keyboard.KEY_RSHIFT + ) + ) + ItemPlan.loadPlanOutput(stack).getIconIndex + else + iconWritten + else iconBlank override def getIcon(stack: ItemStack, pass: Int) = getIconIndex(stack) From 2a1d11131e066ab46ff23e631fd93fc593142e04 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 04:02:20 +0100 Subject: [PATCH 05/18] remove useless ) --- .../scala/mrtjp/projectred/expansion/TileProjectBench.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 1963d38f3..36b68cf74 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -350,7 +350,7 @@ class ContainerProjectBench(player: EntityPlayer, tile: TileProjectBench) if (tryMergeItemStack(stack, 9, 27, false)) return true // merge to storage if (tryMergeItemStack(stack, 29, 65, false)) - return true // merge to inventory) + return true // merge to inventory } else if (9 until 27 contains from) // storage { if (stack.getItem.isInstanceOf[ItemPlan]) { @@ -371,7 +371,7 @@ class ContainerProjectBench(player: EntityPlayer, tile: TileProjectBench) if (tryMergeItemStack(stack, 9, 27, true)) return true // merge to storage if (tryMergeItemStack(stack, 29, 65, false)) - return true // merge to inventory) + return true // merge to inventory } else if (from == 28) // output slot { if (tryMergeItemStack(stack, 29, 65, true)) From 14807a2fd5ca75a4954f830289021feaec929aa4 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 13:41:12 +0100 Subject: [PATCH 06/18] Fix wrong OreDict matching --- .../expansion/TileAutoCrafter.scala | 6 ++--- .../expansion/TileProjectBench.scala | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala index 02b32d1bb..0f837dafe 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala @@ -172,8 +172,7 @@ class TileAutoCrafter val eq = new ItemEquality eq.matchMeta = !item.makeStack(0).isItemStackDamageable eq.matchNBT = false - eq.matchOre = currentRecipe.isInstanceOf[ShapedOreRecipe] || currentRecipe - .isInstanceOf[ShapelessOreRecipe] + eq.matchOre = CraftingHelper.matchOre(currentRecipe) var found = 0 for (i <- 9 until 27) { @@ -202,8 +201,7 @@ class TileAutoCrafter val eq = new ItemEquality eq.matchMeta = !item.makeStack(0).isItemStackDamageable eq.matchNBT = false - eq.matchOre = currentRecipe.isInstanceOf[ShapedOreRecipe] || currentRecipe - .isInstanceOf[ShapelessOreRecipe] + eq.matchOre = matchOre var left = amount for (i <- 9 until 27) { diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 36b68cf74..7617db4f5 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -294,8 +294,7 @@ class SlotProjectCrafting( val eq = new ItemEquality eq.matchMeta = !stack1.isItemStackDamageable eq.matchNBT = false - eq.matchOre = recipe.isInstanceOf[ShapedOreRecipe] || recipe - .isInstanceOf[ShapelessOreRecipe] + eq.matchOre = CraftingHelper.matchOre(recipe) eq.matches(ItemKey.get(stack1), ItemKey.get(stack2)) } @@ -492,3 +491,22 @@ object RenderProjectBench extends TCubeMapRender { iconT = new MultiIconTransformation(bottom, top, side1, side1, side2, side2) } } + +object CraftingHelper { + def matchOre (recipe : IRecipe) : Boolean = { + recipe match { + case r: ShapedOreRecipe => + r.getInput.exists(isOreIngredient) + case r: ShapelessOreRecipe => + r.getInput.exists(isOreIngredient) + case _ => + false + } + } + + def isOreIngredient(in: Any): Boolean = in match { + case _: String => true + case l: java.util.List[_] => true // ore stack list + case _ => false + } +} From 30510153ec144ff27b5df3c859868a7bc5a3edcc Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 13:56:03 +0100 Subject: [PATCH 07/18] Add Recipe Validation before allowing Output --- .../mrtjp/projectred/expansion/TileProjectBench.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 7617db4f5..2833e7d43 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -200,11 +200,14 @@ class SlotProjectCrafting( tile.currentRecipe, tile.currentInputs, storage - ) + ) && tile.currentRecipe.matches(tile.invCrafting, tile.world) } // copied from super for obfuscation bug - canRemoveDelegate() + canRemoveDelegate() && tile.currentRecipe.matches( + tile.invCrafting, + tile.world + ) } override def onPickupFromSlot(player: EntityPlayer, stack: ItemStack) { From 1c18b6c462cb48ea30848c72cc238d9581f0afbe Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 13:56:39 +0100 Subject: [PATCH 08/18] Move onCrafting() to correct Position --- .../scala/mrtjp/projectred/expansion/TileProjectBench.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 2833e7d43..51469948a 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -211,7 +211,6 @@ class SlotProjectCrafting( } override def onPickupFromSlot(player: EntityPlayer, stack: ItemStack) { - onCrafting(stack) val storage = ((9 until 27) ++ (0 until 9)).map { i => val s = tile.getStackInSlot(i) @@ -241,6 +240,7 @@ class SlotProjectCrafting( FMLCommonHandler .instance() .firePlayerCraftingEvent(player, stack, invCrafting) + onCrafting(stack) tile.updateRecipe() } From 733fe3055479288e825773661153d37527d18672 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 13:57:45 +0100 Subject: [PATCH 09/18] Use tile.invCrafting --- .../projectred/expansion/TileProjectBench.scala | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 51469948a..7c09fabd7 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -234,12 +234,11 @@ class SlotProjectCrafting( } } - val invCrafting = new InventoryCrafting(new NodeContainer, 3, 3) - for (i <- 0 until 9) - invCrafting.setInventorySlotContents(i, tile.currentInputs(i)) - FMLCommonHandler - .instance() - .firePlayerCraftingEvent(player, stack, invCrafting) + FMLCommonHandler.instance.firePlayerCraftingEvent( + player, + stack, + tile.invCrafting + ) onCrafting(stack) tile.updateRecipe() @@ -252,15 +251,14 @@ class SlotProjectCrafting( storage: Array[ItemStack] ): Boolean = { i = 0 - val invCrafting = new InventoryCrafting(new NodeContainer, 3, 3) for (i <- 0 until 9) { val item = inputs(i) if (item != null) { if (!eatResource(recipe, item, storage)) return false - invCrafting.setInventorySlotContents(i, item) + tile.invCrafting.setInventorySlotContents(i, eatenItem) } } - recipe.matches(invCrafting, world) + recipe.matches(tile.invCrafting, world) } private var i = 0 From 80579f8fcfd33bb1bbc9881f5db9a239d25b69e3 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 13:59:21 +0100 Subject: [PATCH 10/18] Port #16 to Project Bench --- .../expansion/TileProjectBench.scala | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 7c09fabd7..1da51928a 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -254,7 +254,8 @@ class SlotProjectCrafting( for (i <- 0 until 9) { val item = inputs(i) if (item != null) { - if (!eatResource(recipe, item, storage)) return false + val eatenItem = eatResource(recipe, item, storage) + if (eatenItem == null) return false tile.invCrafting.setInventorySlotContents(i, eatenItem) } } @@ -266,25 +267,24 @@ class SlotProjectCrafting( recipe: IRecipe, stack1: ItemStack, storage: Array[ItemStack] - ): Boolean = { + ): ItemStack = { def increment() = { i = (i + 1) % storage.length; i } if (i < 18) i = 0 else increment() val start = i do { val stack2 = storage(i) if (stack2 != null && ingredientMatch(recipe, stack1, stack2)) { - if (stack2.getItem.hasContainerItem(stack2)) { - val cStack = stack2.getItem.getContainerItem(stack2) - storage(i) = - if (cStack.getItemDamage < cStack.getMaxDamage) cStack else null - return true - } else if (stack2.stackSize >= 1) { - stack2.stackSize -= 1 - return true + stack2.stackSize -= 1; + if (stack2.stackSize <= 0) { + storage(i) = null; } + + val copy = stack2.copy(); + copy.stackSize = 1; + return copy; } } while (increment() != start) - false + null } private def ingredientMatch( From a0e3868dc2a58f424e20c5e98b1ce5f20d94fff4 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 14:00:36 +0100 Subject: [PATCH 11/18] Port #16 to Project Bench Part 2: Move back Remainders --- .../expansion/TileProjectBench.scala | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 1da51928a..f37b85c16 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -241,7 +241,68 @@ class SlotProjectCrafting( ) onCrafting(stack) + for (i <- 0 until 9) { + + val gridStack = tile.invCrafting.getStackInSlot( + i + ) // current real item in grid (maybe null or decreased) + val remainder = getRemaining(i, tile.invCrafting) + + if (remainder != null && gridStack != null) { + // Case 1: No plan active AND this grid slot is now empty → put remainder back in grid + if (!tile.isPlanRecipe && (gridStack.isItemEqual(remainder))) { + tile.setInventorySlotContents(i, remainder) + } + // Case 2: Try to merge remainder into storage slots (9-26) or player inventory + else if ( + !tryAddToStorageSlots(remainder) && + !player.inventory.addItemStackToInventory(remainder) + ) { + // If no space anywhere, drop it + player.dropPlayerItemWithRandomChoice(remainder, false) + } + } + } tile.updateRecipe() + + } + def tryAddToStorageSlots(stack: ItemStack): Boolean = { + // Try to merge into storage slots 9-26 + for (j <- 9 until 27) { + val slotStack = tile.getStackInSlot(j) + if ( + slotStack != null && slotStack.isItemEqual(stack) && + ItemStack.areItemStackTagsEqual(slotStack, stack) && + slotStack.stackSize < slotStack.getMaxStackSize + ) { + val space = slotStack.getMaxStackSize - slotStack.stackSize + val toAdd = Math.min(space, stack.stackSize) + slotStack.stackSize += toAdd + stack.stackSize -= toAdd + if (stack.stackSize <= 0) return true + } + } + + // Try to place in empty storage slot + for (j <- 9 until 27) { + if (tile.getStackInSlot(j) == null) { + tile.setInventorySlotContents(j, stack) + return true + } + } + + false + } + + def getRemaining(i: Int, invCrafting: InventoryCrafting): ItemStack = { + val stack = invCrafting.getStackInSlot(i) + + if (stack != null) { + val item = stack.getItem + if (item != null && item.hasContainerItem(stack)) { + item.getContainerItem(stack) + } else null + } else null } def searchFor( From 0bba7da2d18363189bae0b43396e232a277606d5 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Wed, 24 Dec 2025 14:05:42 +0100 Subject: [PATCH 12/18] Spotless --- dependencies.gradle | 5 ----- .../scala/mrtjp/projectred/expansion/TileAutoCrafter.scala | 2 +- .../scala/mrtjp/projectred/expansion/TileProjectBench.scala | 5 ++--- src/main/scala/mrtjp/projectred/expansion/items.scala | 6 +++++- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 4f53f783f..a7b536302 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -8,11 +8,6 @@ dependencies { compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.14.6-GTNH:dev") {transitive = false} compileOnly("com.github.GTNewHorizons:StorageDrawers:2.2.1-GTNH:dev") {transitive = false} - runtimeOnly("com.github.GTNewHorizons:OpenComputers:1.12.4-GTNH:dev") {transitive = false} - runtimeOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.52.152:dev') { - exclude group: 'com.github.GTNewHorizons', module: 'ProjectRed' - } - compileOnly("curse.maven:cofh-core-69162:2388751") compileOnly("curse.maven:computercraft-67504:2269339") // https://www.curseforge.com/minecraft/mc-mods/computercraft/files/2269339 compileOnly files("dependencies/ColoredLightsCore-1.3.7.39.jar") diff --git a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala index 0f837dafe..91a728574 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala @@ -201,7 +201,7 @@ class TileAutoCrafter val eq = new ItemEquality eq.matchMeta = !item.makeStack(0).isItemStackDamageable eq.matchNBT = false - eq.matchOre = matchOre + eq.matchOre = CraftingHelper.matchOre(currentRecipe) var left = amount for (i <- 9 until 27) { diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index f37b85c16..46ed690bd 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -6,7 +6,6 @@ package mrtjp.projectred.expansion import java.util.{List => JList} - import codechicken.lib.data.MCDataInput import codechicken.lib.gui.GuiDraw import codechicken.lib.render.uv.{MultiIconTransformation, UVTransformation} @@ -36,7 +35,6 @@ import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.IIcon import net.minecraft.world.{IBlockAccess, World} import net.minecraftforge.oredict.{ShapedOreRecipe, ShapelessOreRecipe} -import org.lwjgl.input.Keyboard import scala.collection.JavaConversions._ @@ -353,6 +351,7 @@ class SlotProjectCrafting( stack1: ItemStack, stack2: ItemStack ) = { + val eq = new ItemEquality eq.matchMeta = !stack1.isItemStackDamageable eq.matchNBT = false @@ -555,7 +554,7 @@ object RenderProjectBench extends TCubeMapRender { } object CraftingHelper { - def matchOre (recipe : IRecipe) : Boolean = { + def matchOre(recipe: IRecipe): Boolean = { recipe match { case r: ShapedOreRecipe => r.getInput.exists(isOreIngredient) diff --git a/src/main/scala/mrtjp/projectred/expansion/items.scala b/src/main/scala/mrtjp/projectred/expansion/items.scala index c176da5bb..c050bafcb 100644 --- a/src/main/scala/mrtjp/projectred/expansion/items.scala +++ b/src/main/scala/mrtjp/projectred/expansion/items.scala @@ -21,7 +21,11 @@ import mrtjp.projectred.api.IScrewdriver import net.minecraft.client.Minecraft import net.minecraft.client.model.{ModelBiped, ModelRenderer} import net.minecraft.client.renderer.texture.IIconRegister -import net.minecraft.enchantment.{Enchantment, EnchantmentHelper, EnumEnchantmentType} +import net.minecraft.enchantment.{ + Enchantment, + EnchantmentHelper, + EnumEnchantmentType +} import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.{Entity, EntityLivingBase} import net.minecraft.init.Blocks From 950adeac9a3c8f77a24438079dc547a4a641f188 Mon Sep 17 00:00:00 2001 From: Worive <13164341+Worive@users.noreply.github.com> Date: Sat, 13 Dec 2025 15:07:04 +0100 Subject: [PATCH 13/18] Fix Auto Crafter able to craft items with different NBT Make it match NBT --- .../scala/mrtjp/projectred/expansion/TileAutoCrafter.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala index 91a728574..e8ea6572e 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala @@ -171,7 +171,7 @@ class TileAutoCrafter def containsEnoughResource(item: ItemKey, amount: Int): Boolean = { val eq = new ItemEquality eq.matchMeta = !item.makeStack(0).isItemStackDamageable - eq.matchNBT = false + eq.matchNBT = true eq.matchOre = CraftingHelper.matchOre(currentRecipe) var found = 0 @@ -200,7 +200,7 @@ class TileAutoCrafter def eatResource(item: ItemKey, amount: Int) { val eq = new ItemEquality eq.matchMeta = !item.makeStack(0).isItemStackDamageable - eq.matchNBT = false + eq.matchNBT = true eq.matchOre = CraftingHelper.matchOre(currentRecipe) var left = amount From 72f7a312f06b2d73634cc7cdbaa06650caaea7db Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Thu, 25 Dec 2025 02:14:16 +0100 Subject: [PATCH 14/18] Port #60 to ProjectBench --- .../scala/mrtjp/projectred/expansion/TileProjectBench.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 46ed690bd..5ef6fb587 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -354,7 +354,7 @@ class SlotProjectCrafting( val eq = new ItemEquality eq.matchMeta = !stack1.isItemStackDamageable - eq.matchNBT = false + eq.matchNBT = true eq.matchOre = CraftingHelper.matchOre(recipe) eq.matches(ItemKey.get(stack1), ItemKey.get(stack2)) } From 37c6b4e8e0db2e03112a157e0259ac092ef51b1d Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Thu, 25 Dec 2025 03:14:16 +0100 Subject: [PATCH 15/18] Make ItemPlan behave like AE2 Patterns when holding Shift --- .../mrtjp/projectred/expansion/items.scala | 82 +++++++++++++++---- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/items.scala b/src/main/scala/mrtjp/projectred/expansion/items.scala index c050bafcb..3058a1da8 100644 --- a/src/main/scala/mrtjp/projectred/expansion/items.scala +++ b/src/main/scala/mrtjp/projectred/expansion/items.scala @@ -19,13 +19,12 @@ import mrtjp.core.item.ItemCore import mrtjp.projectred.ProjectRedExpansion import mrtjp.projectred.api.IScrewdriver import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiScreen import net.minecraft.client.model.{ModelBiped, ModelRenderer} +import net.minecraft.client.renderer.RenderHelper +import net.minecraft.client.renderer.entity.RenderItem import net.minecraft.client.renderer.texture.IIconRegister -import net.minecraft.enchantment.{ - Enchantment, - EnchantmentHelper, - EnumEnchantmentType -} +import net.minecraft.enchantment.{Enchantment, EnchantmentHelper, EnumEnchantmentType} import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.{Entity, EntityLivingBase} import net.minecraft.init.Blocks @@ -34,9 +33,11 @@ import net.minecraft.item.{Item, ItemArmor, ItemStack} import net.minecraft.nbt.{NBTTagCompound, NBTTagList} import net.minecraft.util.{DamageSource, EnumChatFormatting, IIcon} import net.minecraft.world.World +import net.minecraftforge.client.{IItemRenderer, MinecraftForgeClient} import net.minecraftforge.common.ISpecialArmor import net.minecraftforge.common.ISpecialArmor.ArmorProperties import org.lwjgl.input.Keyboard +import org.lwjgl.opengl.GL11 import scala.collection.mutable.{Set => MSet} @@ -179,20 +180,13 @@ class ItemElectronicScrewdriver class ItemPlan extends ItemCore("projectred.expansion.plan") { setCreativeTab(ProjectRedExpansion.tabExpansion) + if (FMLCommonHandler.instance().getEffectiveSide.isClient) MinecraftForgeClient.registerItemRenderer(this, new ItemPlanRenderer) var iconBlank: IIcon = null var iconWritten: IIcon = null override def getIconIndex(stack: ItemStack) = - if (ItemPlan.hasRecipeInside(stack)) - if ( - Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown( - Keyboard.KEY_RSHIFT - ) - ) - ItemPlan.loadPlanOutput(stack).getIconIndex - else - iconWritten + if (ItemPlan.hasRecipeInside(stack)) iconWritten else iconBlank override def getIcon(stack: ItemStack, pass: Int) = getIconIndex(stack) @@ -209,13 +203,67 @@ class ItemPlan extends ItemCore("projectred.expansion.plan") { flag: Boolean ) { if (ItemPlan.hasRecipeInside(stack)) { - val s = - s"${EnumChatFormatting.BLUE}Output: ${EnumChatFormatting.GRAY + ItemPlan.loadPlanOutput(stack).getDisplayName}" - list.asInstanceOf[JList[String]].add(s) + val output = ItemPlan.loadPlanOutput(stack); + val inputs = ItemPlan.loadPlanInputs(stack); + + val tooltip = list.asInstanceOf[JList[String]] + + // Output line (with amount) + tooltip.add( + s"${EnumChatFormatting.BLUE}Output: " + + s"${EnumChatFormatting.GRAY}${output.stackSize}x ${output.getDisplayName}" + ) + + // Inputs header + tooltip.add( + s"${EnumChatFormatting.BLUE}Inputs:" + ) + + // Each input item + inputs.foreach { in => + if (in != null) { + tooltip.add( + s" ${EnumChatFormatting.DARK_GRAY}- " + + s"${EnumChatFormatting.GRAY}${in.getDisplayName}" + ) + } else { + tooltip.add( + s" ${EnumChatFormatting.DARK_GRAY}- " + + s"${EnumChatFormatting.GRAY}Empty") + } + } } } } +class ItemPlanRenderer extends IItemRenderer { + final private val ri = new RenderItem + private var recursive = false + + override def handleRenderType(item: ItemStack, `type`: IItemRenderer.ItemRenderType): Boolean = { + val isShiftHeld = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT) + if (!this.recursive && (`type` eq IItemRenderer.ItemRenderType.INVENTORY) && isShiftHeld) { + if (ItemPlan.hasRecipeInside(item)) return true + } + false + } + + override def shouldUseRenderHelper(`type`: IItemRenderer.ItemRenderType, item: ItemStack, helper: IItemRenderer.ItemRendererHelper) = false + + override def renderItem(`type`: IItemRenderer.ItemRenderType, item: ItemStack, data: AnyRef*): Unit = { + this.recursive = true + + val is = ItemPlan.loadPlanOutput(item) + val mc = Minecraft.getMinecraft + GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT) + RenderHelper.enableGUIStandardItemLighting() + this.ri.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager, is, 0, 0) + RenderHelper.disableStandardItemLighting() + GL11.glPopAttrib() + this.recursive = false + } +} + object ItemPlan { private def assertStackTag(stack: ItemStack) { if (!stack.hasTagCompound) From f0da73e675d61ef7627ee03605cb7f76bd8259b2 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Thu, 25 Dec 2025 03:15:03 +0100 Subject: [PATCH 16/18] spotless --- .../mrtjp/projectred/expansion/items.scala | 52 +++++++++++++++---- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/items.scala b/src/main/scala/mrtjp/projectred/expansion/items.scala index 3058a1da8..948f54d5d 100644 --- a/src/main/scala/mrtjp/projectred/expansion/items.scala +++ b/src/main/scala/mrtjp/projectred/expansion/items.scala @@ -24,7 +24,11 @@ import net.minecraft.client.model.{ModelBiped, ModelRenderer} import net.minecraft.client.renderer.RenderHelper import net.minecraft.client.renderer.entity.RenderItem import net.minecraft.client.renderer.texture.IIconRegister -import net.minecraft.enchantment.{Enchantment, EnchantmentHelper, EnumEnchantmentType} +import net.minecraft.enchantment.{ + Enchantment, + EnchantmentHelper, + EnumEnchantmentType +} import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.{Entity, EntityLivingBase} import net.minecraft.init.Blocks @@ -180,7 +184,8 @@ class ItemElectronicScrewdriver class ItemPlan extends ItemCore("projectred.expansion.plan") { setCreativeTab(ProjectRedExpansion.tabExpansion) - if (FMLCommonHandler.instance().getEffectiveSide.isClient) MinecraftForgeClient.registerItemRenderer(this, new ItemPlanRenderer) + if (FMLCommonHandler.instance().getEffectiveSide.isClient) + MinecraftForgeClient.registerItemRenderer(this, new ItemPlanRenderer) var iconBlank: IIcon = null var iconWritten: IIcon = null @@ -229,35 +234,60 @@ class ItemPlan extends ItemCore("projectred.expansion.plan") { } else { tooltip.add( s" ${EnumChatFormatting.DARK_GRAY}- " + - s"${EnumChatFormatting.GRAY}Empty") + s"${EnumChatFormatting.GRAY}Empty" + ) } } } } } -class ItemPlanRenderer extends IItemRenderer { +class ItemPlanRenderer extends IItemRenderer { final private val ri = new RenderItem private var recursive = false - override def handleRenderType(item: ItemStack, `type`: IItemRenderer.ItemRenderType): Boolean = { - val isShiftHeld = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT) - if (!this.recursive && (`type` eq IItemRenderer.ItemRenderType.INVENTORY) && isShiftHeld) { + override def handleRenderType( + item: ItemStack, + `type`: IItemRenderer.ItemRenderType + ): Boolean = { + val isShiftHeld = + Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown( + Keyboard.KEY_RSHIFT + ) + if ( + !this.recursive && (`type` eq IItemRenderer.ItemRenderType.INVENTORY) && isShiftHeld + ) { if (ItemPlan.hasRecipeInside(item)) return true } false } - override def shouldUseRenderHelper(`type`: IItemRenderer.ItemRenderType, item: ItemStack, helper: IItemRenderer.ItemRendererHelper) = false + override def shouldUseRenderHelper( + `type`: IItemRenderer.ItemRenderType, + item: ItemStack, + helper: IItemRenderer.ItemRendererHelper + ) = false - override def renderItem(`type`: IItemRenderer.ItemRenderType, item: ItemStack, data: AnyRef*): Unit = { + override def renderItem( + `type`: IItemRenderer.ItemRenderType, + item: ItemStack, + data: AnyRef* + ): Unit = { this.recursive = true val is = ItemPlan.loadPlanOutput(item) val mc = Minecraft.getMinecraft - GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT) + GL11.glPushAttrib( + GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT + ) RenderHelper.enableGUIStandardItemLighting() - this.ri.renderItemAndEffectIntoGUI(mc.fontRenderer, mc.getTextureManager, is, 0, 0) + this.ri.renderItemAndEffectIntoGUI( + mc.fontRenderer, + mc.getTextureManager, + is, + 0, + 0 + ) RenderHelper.disableStandardItemLighting() GL11.glPopAttrib() this.recursive = false From 44496450863b259c070e7463fe5b8c63a9e3bf47 Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Thu, 25 Dec 2025 04:00:26 +0100 Subject: [PATCH 17/18] Prefer Crafting Grid Materials when not PlanRecipe --- .../scala/mrtjp/projectred/expansion/TileProjectBench.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 5ef6fb587..839078ea1 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -309,7 +309,7 @@ class SlotProjectCrafting( inputs: Array[ItemStack], storage: Array[ItemStack] ): Boolean = { - i = 0 + if (tile.isPlanRecipe) i = 0 else i = 17 for (i <- 0 until 9) { val item = inputs(i) if (item != null) { @@ -328,7 +328,7 @@ class SlotProjectCrafting( storage: Array[ItemStack] ): ItemStack = { def increment() = { i = (i + 1) % storage.length; i } - if (i < 18) i = 0 else increment() + if (!tile.isPlanRecipe) increment() val start = i do { val stack2 = storage(i) From f81021889db705f4c392affa50766f32d624f9ee Mon Sep 17 00:00:00 2001 From: PLASMAchicken Date: Thu, 25 Dec 2025 22:51:03 +0100 Subject: [PATCH 18/18] Disabe OreDict because it ignores NBT check --- .../expansion/TileAutoCrafter.scala | 4 ++-- .../expansion/TileProjectBench.scala | 21 +------------------ 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala index e8ea6572e..989c6a586 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileAutoCrafter.scala @@ -172,7 +172,7 @@ class TileAutoCrafter val eq = new ItemEquality eq.matchMeta = !item.makeStack(0).isItemStackDamageable eq.matchNBT = true - eq.matchOre = CraftingHelper.matchOre(currentRecipe) + eq.matchOre = false var found = 0 for (i <- 9 until 27) { @@ -201,7 +201,7 @@ class TileAutoCrafter val eq = new ItemEquality eq.matchMeta = !item.makeStack(0).isItemStackDamageable eq.matchNBT = true - eq.matchOre = CraftingHelper.matchOre(currentRecipe) + eq.matchOre = false var left = amount for (i <- 9 until 27) { diff --git a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala index 839078ea1..64c60eda4 100644 --- a/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala +++ b/src/main/scala/mrtjp/projectred/expansion/TileProjectBench.scala @@ -355,7 +355,7 @@ class SlotProjectCrafting( val eq = new ItemEquality eq.matchMeta = !stack1.isItemStackDamageable eq.matchNBT = true - eq.matchOre = CraftingHelper.matchOre(recipe) + eq.matchOre = false eq.matches(ItemKey.get(stack1), ItemKey.get(stack2)) } @@ -552,22 +552,3 @@ object RenderProjectBench extends TCubeMapRender { iconT = new MultiIconTransformation(bottom, top, side1, side1, side2, side2) } } - -object CraftingHelper { - def matchOre(recipe: IRecipe): Boolean = { - recipe match { - case r: ShapedOreRecipe => - r.getInput.exists(isOreIngredient) - case r: ShapelessOreRecipe => - r.getInput.exists(isOreIngredient) - case _ => - false - } - } - - def isOreIngredient(in: Any): Boolean = in match { - case _: String => true - case l: java.util.List[_] => true // ore stack list - case _ => false - } -}