From f11a8a77a71bda770c884e4dbf9238d1d63f25ea Mon Sep 17 00:00:00 2001 From: hammy3502 Date: Sat, 7 May 2022 15:49:11 -0400 Subject: [PATCH] Backpack Crafting --- model/Crafting.bbmodel | 1 + .../config/screen/BackpackConfigScreen.java | 2 +- .../config/screen/ImmersivesConfigScreen.java | 2 +- .../client/immersive/BackpackImmersive.java | 69 +++++++++++++++++- .../client/immersive/info/BackpackInfo.java | 26 ++++--- .../client/model/BackpackCraftingModel.java | 41 +++++++++++ .../subscribe/ClientLogicSubscriber.java | 6 +- .../common/network/NetworkClientHandlers.java | 9 +++ .../common/network/packet/CraftPacket.java | 25 +++++-- .../blf02/immersivemc/server/swap/Swap.java | 10 ++- .../resources/assets/immersivemc/crafting.png | Bin 0 -> 3316 bytes 11 files changed, 162 insertions(+), 29 deletions(-) create mode 100644 model/Crafting.bbmodel create mode 100644 src/main/java/net/blf02/immersivemc/client/model/BackpackCraftingModel.java create mode 100644 src/main/resources/assets/immersivemc/crafting.png diff --git a/model/Crafting.bbmodel b/model/Crafting.bbmodel new file mode 100644 index 00000000..2286cee0 --- /dev/null +++ b/model/Crafting.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.0","creation_time":1651947086,"model_format":"modded_entity","box_uv":true},"name":"BackpackCrafting","geometry_name":"","modded_entity_version":"1.15_mojmaps","visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"resolution":{"width":32,"height":32},"elements":[{"name":"table","rescale":false,"locked":false,"from":[-4,-4,-4],"to":[4,4,4],"autouv":0,"color":0,"origin":[0,0,0],"faces":{"north":{"uv":[8,8,16,16],"texture":0},"east":{"uv":[0,8,8,16],"texture":0},"south":{"uv":[24,8,32,16],"texture":0},"west":{"uv":[16,8,24,16],"texture":0},"up":{"uv":[16,8,8,0],"texture":0},"down":{"uv":[24,0,16,8],"texture":0}},"type":"cube","uuid":"55203d27-0b71-1cef-1b4c-a7995d3b3b20"}],"outliner":[{"name":"table","origin":[0,0,0],"color":0,"uuid":"e15e2c02-2573-f919-6f81-55536df2b501","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["55203d27-0b71-1cef-1b4c-a7995d3b3b20"]}],"textures":[{"path":"C:\\Users\\hammy3502\\Desktop\\Forge\\immersive-mc\\src\\main\\resources\\assets\\immersivemc\\crafting.png","name":"crafting.png","folder":"block","namespace":"","id":"0","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"c8c866b2-f2e8-9229-266e-60f81c6e90ec","relative_path":"../../src/main/resources/assets/immersivemc/crafting.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAYxJREFUWEdjZCAAtlx5+B+fkvm9k/GasHZ+DyM+BXglQRpBDrBQkWEQ4WBmePPjL4pZJ+48YQA5QFpcAqsdT1++YKCLA9bO78HqgODEEuo6ANkWUGjAQgDkgLwKiCMmdZSA2SB6+DkAVxqgWxQMWCKkaTZ0ftGLN59LXEnHm89nnpqEV54l/A1eeUaQAyzExRhaGWNRFFb/X8xw4uUrBpADFCS44XKtOpCio/rKf4YHL74ygBzArSgHFmOMjIGr+798CcPX+48YQA7gUO7DcMT/HzMZfj69yYDiAJClyACXA0CWgwCyA0CWgyxFBsgOAFmIDjAcAPYZkiNIdQBIP7IjYA5gl1ZnYORIZ0B3BIoDYK4DRQXMEeRGAcwRyA4ARxEHJD3BHAJ3wF6JYoz4BwlgcwBIHJQOkNMAT1UVin50B8DSAMhi5JDAGgLoaQDdcTB5bIkQPY7RowAmjxEC+PIJKBcsdeFhiN7zBasyirMhPsvpIUewPUBrR4w6YDQERkNgNARGQ2A0BEZDAAAY10NgBpvC7AAAAABJRU5ErkJggg=="}]} \ No newline at end of file diff --git a/src/main/java/net/blf02/immersivemc/client/config/screen/BackpackConfigScreen.java b/src/main/java/net/blf02/immersivemc/client/config/screen/BackpackConfigScreen.java index ed86f62f..9f14838a 100644 --- a/src/main/java/net/blf02/immersivemc/client/config/screen/BackpackConfigScreen.java +++ b/src/main/java/net/blf02/immersivemc/client/config/screen/BackpackConfigScreen.java @@ -31,7 +31,7 @@ public class BackpackConfigScreen extends Screen { protected final Screen parentScreen; protected OptionsRowList list; - protected static int BUTTON_WIDTH = 256; + protected static int BUTTON_WIDTH = 128; protected static int BUTTON_HEIGHT = 20; public BackpackConfigScreen(Screen lastScreen) { diff --git a/src/main/java/net/blf02/immersivemc/client/config/screen/ImmersivesConfigScreen.java b/src/main/java/net/blf02/immersivemc/client/config/screen/ImmersivesConfigScreen.java index c8d970e2..3d87ea24 100644 --- a/src/main/java/net/blf02/immersivemc/client/config/screen/ImmersivesConfigScreen.java +++ b/src/main/java/net/blf02/immersivemc/client/config/screen/ImmersivesConfigScreen.java @@ -15,7 +15,7 @@ public class ImmersivesConfigScreen extends Screen { protected OptionsRowList list; protected boolean notInWorld; - protected static int BUTTON_WIDTH = 256; + protected static int BUTTON_WIDTH = 128; protected static int BUTTON_HEIGHT = 20; public ImmersivesConfigScreen(Screen screen) { diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java b/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java index f89932f4..af012bfe 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java @@ -4,11 +4,16 @@ import net.blf02.immersivemc.client.config.ClientConstants; import net.blf02.immersivemc.client.immersive.info.AbstractImmersiveInfo; import net.blf02.immersivemc.client.immersive.info.BackpackInfo; +import net.blf02.immersivemc.client.model.BackpackCraftingModel; import net.blf02.immersivemc.client.model.BackpackModel; import net.blf02.immersivemc.common.config.ActiveConfig; +import net.blf02.immersivemc.common.network.Network; +import net.blf02.immersivemc.common.network.packet.CraftPacket; +import net.blf02.immersivemc.common.network.packet.InventorySwapPacket; import net.blf02.immersivemc.common.util.Util; import net.blf02.immersivemc.common.vr.VRPlugin; import net.blf02.immersivemc.common.vr.VRPluginVerify; +import net.blf02.immersivemc.server.swap.Swap; import net.blf02.vrapi.api.data.IVRData; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ActiveRenderInfo; @@ -28,6 +33,8 @@ public class BackpackImmersive extends AbstractImmersive { public static final BackpackImmersive singleton = new BackpackImmersive(); public static final BackpackModel model = new BackpackModel(); + public static final BackpackCraftingModel craftingModel = new BackpackCraftingModel(); + private final double spacing = 3d/8d; public BackpackImmersive() { @@ -110,6 +117,36 @@ protected void doTick(BackpackInfo info, boolean isInVR) { info.setPosition(i, slotPos); info.setHitbox(i, createHitbox(info.getPosition(i), 0.05f)); } + + Vector3d upVec = info.downVec.multiply(-1, -1, -1); + + double upMult = 0.05; + + // Multiply these by 4 since rightVec is multiplied by 0.25 above + Vector3d leftCraftingPos = info.centerTopPos.add(rightVec.multiply(0.3125*4, 0.3125*4, 0.3125*4)) + .add(upVec.multiply(upMult, upMult, upMult)); + Vector3d rightCraftingPos = info.centerTopPos.add(rightVec.multiply(0.4375*4, 0.4375*4, 0.4375*4)) + .add(upVec.multiply(upMult, upMult, upMult)); + Vector3d centerCraftingPos = info.centerTopPos.add(rightVec.multiply(0.375*4, 0.375*4, 0.375*4)) + .add(upVec.multiply(upMult, upMult, upMult)); + + double craftingOffset = 0.625; + Vector3d[] craftingPositions = new Vector3d[]{ + leftCraftingPos.add(topOffset.multiply(craftingOffset, craftingOffset, craftingOffset)), + rightCraftingPos.add(topOffset.multiply(craftingOffset, craftingOffset, craftingOffset)), + leftCraftingPos.add(botOffset.multiply(craftingOffset, craftingOffset, craftingOffset)), + rightCraftingPos.add(botOffset.multiply(craftingOffset, craftingOffset, craftingOffset)) + }; + + for (int i = 27; i <= 30; i++) { + info.setPosition(i, craftingPositions[i - 27]); + info.setHitbox(i, createHitbox(info.getPosition(i), 0.05f)); + } + + info.setPosition(31, centerCraftingPos.add(upVec.multiply(0.125, 0.125, 0.125))); + info.setHitbox(31, createHitbox(info.getPosition(31), 0.05f)); + + Optional hitboxIntersect = Util.getFirstIntersect(handController.position(), info.getAllHitboxes()); if (hitboxIntersect.isPresent()) { @@ -119,6 +156,20 @@ protected void doTick(BackpackInfo info, boolean isInVR) { } } + public static void onHitboxInteract(PlayerEntity player, BackpackInfo info, int slot) { + if (slot <= 26) { // Inventory handle + Network.INSTANCE.sendToServer(new InventorySwapPacket(slot + 9)); + Swap.handleInventorySwap(player, slot + 9, Hand.MAIN_HAND); // Do swap on both sides + } else if (slot <= 30) { + info.craftingInput[slot - 27] = player.getItemInHand(Hand.MAIN_HAND); + Network.INSTANCE.sendToServer(new CraftPacket(info.craftingInput, player.blockPosition(), + true)); + } else if (slot == 31) { + Network.INSTANCE.sendToServer(new CraftPacket(info.craftingInput, player.blockPosition(), + false)); + } + } + protected boolean inRange(int num, int start, int end) { return start <= num && num <= end; } @@ -133,7 +184,7 @@ public boolean shouldRender(BackpackInfo info, boolean isInVR) { @Override protected void render(BackpackInfo info, MatrixStack stack, boolean isInVR) { - for (int i = 0; i <= 26; i++) { + for (int i = 0; i <= 31; i++) { AxisAlignedBB hitbox = info.getHibtox(i); renderHitbox(stack, hitbox, info.getPosition(i)); } @@ -147,6 +198,13 @@ protected void render(BackpackInfo info, MatrixStack stack, boolean isInVR) { } } + for (int i = 27; i <= 31; i++) { + ItemStack item = i == 31 ? info.craftingOutput : info.craftingInput[i - 27]; + if (!item.isEmpty() && info.getPosition(i) != null) { + renderItem(item, stack, info.getPosition(i), ClientConstants.itemScaleSizeBackpack, null, info.getHibtox(i), i == 31); + } + } + stack.pushPose(); Vector3d pos = info.renderPos; @@ -174,6 +232,15 @@ protected void render(BackpackInfo info, MatrixStack stack, boolean isInVR) { 15728880, OverlayTexture.NO_OVERLAY, info.rgb.x(), info.rgb.y(), info.rgb.z(), 1); + // Translate and render the crafting on the side of the backpack and down a bit + // (yes, positive y in this context moves it down lol) + stack.translate(ActiveConfig.leftHandedBackpack ? -0.75 : 0.75, 0.25, 0); + craftingModel.renderToBuffer(stack, + Minecraft.getInstance().renderBuffers().bufferSource() + .getBuffer(RenderType.entityCutout(BackpackCraftingModel.textureLocation)), + 15728880, OverlayTexture.NO_OVERLAY, + 1, 1, 1, 1); + Minecraft.getInstance().renderBuffers().bufferSource().endBatch(); stack.popPose(); } diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/info/BackpackInfo.java b/src/main/java/net/blf02/immersivemc/client/immersive/info/BackpackInfo.java index 3efa5622..be6d769c 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/info/BackpackInfo.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/info/BackpackInfo.java @@ -2,6 +2,7 @@ import net.blf02.immersivemc.client.config.ClientConstants; import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; @@ -9,8 +10,11 @@ public class BackpackInfo extends AbstractImmersiveInfo { - protected final Vector3d[] itemPositions = new Vector3d[27]; - protected final AxisAlignedBB[] itemHitboxes = new AxisAlignedBB[27]; + protected final Vector3d[] positions = new Vector3d[32]; + protected final AxisAlignedBB[] hitboxes = new AxisAlignedBB[32]; + // 0-26: Inventory + // 27-31: Input crafting + // 32: Output crafting public Vector3d handPos = Vector3d.ZERO; public Vector3d lookVec = Vector3d.ZERO; @@ -23,6 +27,8 @@ public class BackpackInfo extends AbstractImmersiveInfo { public Vector3f rgb = new Vector3f(0, 0, 0); public int topRow = 0; public int slotHovered = -1; + public ItemStack[] craftingInput = new ItemStack[]{ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY}; + public ItemStack craftingOutput = ItemStack.EMPTY; public BackpackInfo() { super(ClientConstants.ticksToRenderBackpack); @@ -30,42 +36,42 @@ public BackpackInfo() { @Override public AxisAlignedBB getHibtox(int slot) { - return itemHitboxes[slot]; + return hitboxes[slot]; } @Override public AxisAlignedBB[] getAllHitboxes() { - return itemHitboxes; + return hitboxes; } @Override public void setHitbox(int slot, AxisAlignedBB hitbox) { - itemHitboxes[slot] = hitbox; + hitboxes[slot] = hitbox; } @Override public boolean hasHitboxes() { - return itemHitboxes[26] != null; + return hitboxes[26] != null; } @Override public Vector3d getPosition(int slot) { - return itemPositions[slot]; + return positions[slot]; } @Override public Vector3d[] getAllPositions() { - return itemPositions; + return positions; } @Override public void setPosition(int slot, Vector3d position) { - itemPositions[slot] = position; + positions[slot] = position; } @Override public boolean hasPositions() { - return itemPositions[26] != null; + return positions[26] != null; } @Override diff --git a/src/main/java/net/blf02/immersivemc/client/model/BackpackCraftingModel.java b/src/main/java/net/blf02/immersivemc/client/model/BackpackCraftingModel.java new file mode 100644 index 00000000..5064023e --- /dev/null +++ b/src/main/java/net/blf02/immersivemc/client/model/BackpackCraftingModel.java @@ -0,0 +1,41 @@ +package net.blf02.immersivemc.client.model; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import net.blf02.immersivemc.ImmersiveMC; +import net.minecraft.client.renderer.entity.model.EntityModel; +import net.minecraft.client.renderer.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; + +// 99% exported from BlockBench +public class BackpackCraftingModel extends EntityModel { + + public static final ResourceLocation textureLocation = new ResourceLocation(ImmersiveMC.MOD_ID, "crafting.png"); + private final ModelRenderer table; + + public BackpackCraftingModel() { + texWidth = 32; + texHeight = 32; + + table = new ModelRenderer(this); + table.setPos(0.0F, 24.0F, 0.0F); + table.texOffs(0, 0).addBox(-4.0F, -4.0F, -4.0F, 8.0F, 8.0F, 8.0F, 0.0F, false); + } + + @Override + public void setupAnim(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch){ + //previously the render function, render code was moved to a method below + } + + @Override + public void renderToBuffer(MatrixStack matrixStack, IVertexBuilder buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha){ + table.render(matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha); + } + + public void setRotationAngle(ModelRenderer modelRenderer, float x, float y, float z) { + modelRenderer.xRot = x; + modelRenderer.yRot = y; + modelRenderer.zRot = z; + } +} diff --git a/src/main/java/net/blf02/immersivemc/client/subscribe/ClientLogicSubscriber.java b/src/main/java/net/blf02/immersivemc/client/subscribe/ClientLogicSubscriber.java index 0e7b65d8..3e1d7f80 100644 --- a/src/main/java/net/blf02/immersivemc/client/subscribe/ClientLogicSubscriber.java +++ b/src/main/java/net/blf02/immersivemc/client/subscribe/ClientLogicSubscriber.java @@ -9,13 +9,10 @@ import net.blf02.immersivemc.client.immersive.info.InfoTriggerHitboxes; import net.blf02.immersivemc.client.tracker.ClientTrackerInit; import net.blf02.immersivemc.common.config.ActiveConfig; -import net.blf02.immersivemc.common.network.Network; -import net.blf02.immersivemc.common.network.packet.InventorySwapPacket; import net.blf02.immersivemc.common.tracker.AbstractTracker; import net.blf02.immersivemc.common.util.Util; import net.blf02.immersivemc.common.vr.VRPlugin; import net.blf02.immersivemc.common.vr.VRPluginVerify; -import net.blf02.immersivemc.server.swap.Swap; import net.blf02.vrapi.api.data.IVRData; import net.minecraft.block.AbstractChestBlock; import net.minecraft.block.AnvilBlock; @@ -201,8 +198,7 @@ public static boolean handleLeftClick(PlayerEntity player) { BackpackImmersive.singleton.getTrackedObjects().get(0) : null; // Move to next row on left click if backpack is out if (backpackInfo != null && backpackInfo.slotHovered > -1) { - Network.INSTANCE.sendToServer(new InventorySwapPacket(backpackInfo.slotHovered + 9)); - Swap.handleInventorySwap(player, backpackInfo.slotHovered + 9, Hand.MAIN_HAND); // Do swap on both sides + BackpackImmersive.onHitboxInteract(player, backpackInfo, backpackInfo.slotHovered); return true; } diff --git a/src/main/java/net/blf02/immersivemc/common/network/NetworkClientHandlers.java b/src/main/java/net/blf02/immersivemc/common/network/NetworkClientHandlers.java index 3523a85d..be1718cf 100644 --- a/src/main/java/net/blf02/immersivemc/common/network/NetworkClientHandlers.java +++ b/src/main/java/net/blf02/immersivemc/common/network/NetworkClientHandlers.java @@ -2,9 +2,11 @@ import net.blf02.immersivemc.client.immersive.AbstractImmersive; import net.blf02.immersivemc.client.immersive.AbstractTileEntityImmersive; +import net.blf02.immersivemc.client.immersive.BackpackImmersive; import net.blf02.immersivemc.client.immersive.Immersives; import net.blf02.immersivemc.client.immersive.info.AbstractImmersiveInfo; import net.blf02.immersivemc.client.immersive.info.AbstractTileEntityImmersiveInfo; +import net.blf02.immersivemc.client.immersive.info.BackpackInfo; import net.blf02.immersivemc.client.immersive.info.ChestInfo; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; @@ -13,6 +15,13 @@ public class NetworkClientHandlers { + public static void setBackpackOutput(ItemStack output) { + if (BackpackImmersive.singleton.getTrackedObjects().size() > 0) { + BackpackInfo info = BackpackImmersive.singleton.getTrackedObjects().get(0); + info.craftingOutput = output; + } + } + public static void handleReceiveInvData(ItemStack[] stacks, BlockPos pos) { Objects.requireNonNull(stacks); for (AbstractImmersive singleton : Immersives.IMMERSIVES) { diff --git a/src/main/java/net/blf02/immersivemc/common/network/packet/CraftPacket.java b/src/main/java/net/blf02/immersivemc/common/network/packet/CraftPacket.java index d6709c42..8921c3d0 100644 --- a/src/main/java/net/blf02/immersivemc/common/network/packet/CraftPacket.java +++ b/src/main/java/net/blf02/immersivemc/common/network/packet/CraftPacket.java @@ -3,6 +3,7 @@ import net.blf02.immersivemc.client.storage.ClientStorage; import net.blf02.immersivemc.common.config.ActiveConfig; import net.blf02.immersivemc.common.network.Network; +import net.blf02.immersivemc.common.network.NetworkClientHandlers; import net.blf02.immersivemc.common.network.NetworkUtil; import net.blf02.immersivemc.server.swap.Swap; import net.minecraft.entity.player.ServerPlayerEntity; @@ -22,16 +23,19 @@ public class CraftPacket { protected final BlockPos tablePos; protected final ItemStack resItem; + protected final boolean is2x2; public CraftPacket(ItemStack[] inv, BlockPos tablePos, boolean retrieveRecipe) { this.inv = inv; this.tablePos = tablePos; this.isAskingForRecipe = retrieveRecipe; this.resItem = null; + this.is2x2 = false; } - protected CraftPacket(ItemStack resItem) { + protected CraftPacket(ItemStack resItem, boolean is2x2) { this.resItem = resItem; + this.is2x2 = is2x2; this.isAskingForRecipe = false; this.inv = null; this.tablePos = null; @@ -40,26 +44,29 @@ protected CraftPacket(ItemStack resItem) { public static void encode(CraftPacket packet, PacketBuffer buffer) { buffer.writeBoolean(packet.resItem == null); if (packet.resItem == null) { - for (int i = 0; i < 9; i++) { + buffer.writeInt(packet.inv.length); + for (int i = 0; i < packet.inv.length; i++) { buffer.writeItem(packet.inv[i]); } buffer.writeBlockPos(packet.tablePos); buffer.writeBoolean(packet.isAskingForRecipe); } else { buffer.writeItem(packet.resItem); + buffer.writeBoolean(packet.is2x2); } } public static CraftPacket decode(PacketBuffer buffer) { if (buffer.readBoolean()) { - ItemStack[] inv = new ItemStack[9]; - for (int i = 0; i < 9; i++) { + int numItems = buffer.readInt(); + ItemStack[] inv = new ItemStack[numItems]; + for (int i = 0; i < numItems; i++) { inv[i] = buffer.readItem(); } return new CraftPacket(inv, buffer.readBlockPos(), buffer.readBoolean()); } else { - return new CraftPacket(buffer.readItem()); + return new CraftPacket(buffer.readItem(), buffer.readBoolean()); } @@ -74,12 +81,16 @@ public static void handle(final CraftPacket message, Supplier player), - new CraftPacket(result)); + new CraftPacket(result, message.inv.length == 4)); } else { Swap.handleCrafting(player, message.inv, message.tablePos); } } else if (player == null) { - ClientStorage.craftingOutput = message.resItem; + if (message.is2x2) { + NetworkClientHandlers.setBackpackOutput(message.resItem); + } else { + ClientStorage.craftingOutput = message.resItem; + } } }); diff --git a/src/main/java/net/blf02/immersivemc/server/swap/Swap.java b/src/main/java/net/blf02/immersivemc/server/swap/Swap.java index 3a0dc3a3..6b88a06b 100644 --- a/src/main/java/net/blf02/immersivemc/server/swap/Swap.java +++ b/src/main/java/net/blf02/immersivemc/server/swap/Swap.java @@ -148,8 +148,9 @@ public static void handleEnderChest(PlayerEntity player, Hand hand, int slot) { public static void handleCrafting(ServerPlayerEntity player, ItemStack[] stacksIn, BlockPos tablePos) { - CraftingInventory inv = new CraftingInventory(new NullContainer(), 3, 3); - for (int i = 0; i < 9; i++) { + int invDim = stacksIn.length == 9 ? 3 : 2; + CraftingInventory inv = new CraftingInventory(new NullContainer(), invDim, invDim); + for (int i = 0; i < stacksIn.length; i++) { inv.setItem(i, stacksIn[i]); } ICraftingRecipe res = getReecipe(player, stacksIn); @@ -179,8 +180,9 @@ public static void handleCrafting(ServerPlayerEntity player, ItemStack[] stacksI } public static ICraftingRecipe getReecipe(ServerPlayerEntity player, ItemStack[] stacksIn) { - CraftingInventory inv = new CraftingInventory(new NullContainer(), 3, 3); - for (int i = 0; i < 9; i++) { + int invDim = stacksIn.length == 9 ? 3 : 2; + CraftingInventory inv = new CraftingInventory(new NullContainer(), invDim, invDim); + for (int i = 0; i < stacksIn.length; i++) { inv.setItem(i, stacksIn[i]); } Optional res = player.getServer().getRecipeManager().getRecipeFor(IRecipeType.CRAFTING, diff --git a/src/main/resources/assets/immersivemc/crafting.png b/src/main/resources/assets/immersivemc/crafting.png new file mode 100644 index 0000000000000000000000000000000000000000..2751ce85ef019f92b27dacdc9c3eec9b00143ce7 GIT binary patch literal 3316 zcmVKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0006XNklYNtWgyS-vU%Ge{KX6ep8j2#*Y#UUHOF;OZL#Ngyc7QzI@OMz> zG)^BZ0r0qP{*nW9T45}fOZfc(O<-QlqGU9tL1vHe0~ckVPC;J;pinNMWHkK1r8DSE zeO}sW0+9vLB*ra>;@WDJVmX{hdu$TzmKoKhl?xC5egc#JPu45T)!6&}wOY*UHJxVL zKv&hhTQKSQcmL&O^ zhOxo*TTf^h8+64myljWA?EsK8FXwX#MzBpjr^HILnb1ft5G2jd-dulrV`#kM&HFFB z{ECl1GIljh}YMy1hc@YQzc ziecOuYfPpc96mCq?8&C8zUV)g{>-WDIa;m4!?wn=G0#q5bV yCdEtBe#c2;hX0IIKq?>=kP1izqyka_-vtvS#D0000