diff --git a/src/main/java/jiink/smeltinginapinch/DemoBlockEntity.java b/src/main/java/jiink/smeltinginapinch/DemoBlockEntity.java index daa9371..ac4a2bd 100644 --- a/src/main/java/jiink/smeltinginapinch/DemoBlockEntity.java +++ b/src/main/java/jiink/smeltinginapinch/DemoBlockEntity.java @@ -31,7 +31,7 @@ public void readNbt(NbtCompound nbt) { public static void tick(World world, BlockPos pos, BlockState state, DemoBlockEntity be) { if (!world.isClient) { - SmeltingInAPinch.LOGGER.info("Tick! " + be.number); + //SmeltingInAPinch.LOGGER.info("Tick! " + be.number); } } diff --git a/src/main/java/jiink/smeltinginapinch/ImplementedInventory.java b/src/main/java/jiink/smeltinginapinch/ImplementedInventory.java new file mode 100644 index 0000000..410b3e0 --- /dev/null +++ b/src/main/java/jiink/smeltinginapinch/ImplementedInventory.java @@ -0,0 +1,213 @@ +package jiink.smeltinginapinch; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.Inventories; +import net.minecraft.inventory.Inventory; +import net.minecraft.inventory.SidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.util.math.Direction; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * A simple {@code SidedInventory} implementation with only default methods + an item list getter. + * + *

Reading and writing to tags

+ * Use {@link Inventories#writeNbt(NbtCompound, DefaultedList)} and {@link Inventories#readNbt(NbtCompound, DefaultedList)} + * on {@linkplain #getItems() the item list}. + * + * License: CC0 + * @author Juuz + */ +@FunctionalInterface +public interface ImplementedInventory extends SidedInventory { + /** + * Gets the item list of this inventory. + * Must return the same instance every time it's called. + * + * @return the item list + */ + DefaultedList getItems(); + + /** + * Creates an inventory from the item list. + * + * @param items the item list + * @return a new inventory + */ + static ImplementedInventory of(DefaultedList items) { + return () -> items; + } + + /** + * Creates a new inventory with the size. + * + * @param size the inventory size + * @return a new inventory + */ + static ImplementedInventory ofSize(int size) { + return of(DefaultedList.ofSize(size, ItemStack.EMPTY)); + } + + // SidedInventory + + /** + * Gets the available slots to automation on the side. + * + *

The default implementation returns an array of all slots. + * + * @param side the side + * @return the available slots + */ + @Override + default int[] getAvailableSlots(Direction side) { + int[] result = new int[getItems().size()]; + for (int i = 0; i < result.length; i++) { + result[i] = i; + } + + return result; + } + + /** + * Returns true if the stack can be inserted in the slot at the side. + * + *

The default implementation returns true. + * + * @param slot the slot + * @param stack the stack + * @param side the side + * @return true if the stack can be inserted + */ + @Override + default boolean canInsert(int slot, ItemStack stack, @Nullable Direction side) { + return true; + } + + /** + * Returns true if the stack can be extracted from the slot at the side. + * + *

The default implementation returns true. + * + * @param slot the slot + * @param stack the stack + * @param side the side + * @return true if the stack can be extracted + */ + @Override + default boolean canExtract(int slot, ItemStack stack, Direction side) { + return true; + } + + // Inventory + + /** + * Returns the inventory size. + * + *

The default implementation returns the size of {@link #getItems()}. + * + * @return the inventory size + */ + @Override + default int size() { + return getItems().size(); + } + + /** + * @return true if this inventory has only empty stacks, false otherwise + */ + @Override + default boolean isEmpty() { + for (int i = 0; i < size(); i++) { + ItemStack stack = getStack(i); + if (!stack.isEmpty()) { + return false; + } + } + + return true; + } + + /** + * Gets the item in the slot. + * + * @param slot the slot + * @return the item in the slot + */ + @Override + default ItemStack getStack(int slot) { + return getItems().get(slot); + } + + /** + * Takes a stack of the size from the slot. + * + *

(default implementation) If there are less items in the slot than what are requested, + * takes all items in that slot. + * + * @param slot the slot + * @param count the item count + * @return a stack + */ + @Override + default ItemStack removeStack(int slot, int count) { + ItemStack result = Inventories.splitStack(getItems(), slot, count); + if (!result.isEmpty()) { + markDirty(); + } + + return result; + } + + /** + * Removes the current stack in the {@code slot} and returns it. + * + *

The default implementation uses {@link Inventories#removeStack(List, int)} + * + * @param slot the slot + * @return the removed stack + */ + @Override + default ItemStack removeStack(int slot) { + return Inventories.removeStack(getItems(), slot); + } + + /** + * Replaces the current stack in the {@code slot} with the provided stack. + * + *

If the stack is too big for this inventory ({@link Inventory#getMaxCountPerStack()}), + * it gets resized to this inventory's maximum amount. + * + * @param slot the slot + * @param stack the stack + */ + @Override + default void setStack(int slot, ItemStack stack) { + getItems().set(slot, stack); + if (stack.getCount() > getMaxCountPerStack()) { + stack.setCount(getMaxCountPerStack()); + } + markDirty(); + } + + /** + * Clears {@linkplain #getItems() the item list}}. + */ + @Override + default void clear() { + getItems().clear(); + } + + @Override + default void markDirty() { + // Override if you want behavior. + } + + @Override + default boolean canPlayerUse(PlayerEntity player) { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/jiink/smeltinginapinch/SmeltingInAPinch.java b/src/main/java/jiink/smeltinginapinch/SmeltingInAPinch.java index 249d203..39ecf7b 100644 --- a/src/main/java/jiink/smeltinginapinch/SmeltingInAPinch.java +++ b/src/main/java/jiink/smeltinginapinch/SmeltingInAPinch.java @@ -4,14 +4,17 @@ import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; +import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType; import net.minecraft.block.Block; import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.client.gui.screen.ingame.HandledScreens; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemGroups; import net.minecraft.item.Items; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.screen.ScreenHandlerType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,6 +23,8 @@ public class SmeltingInAPinch implements ModInitializer { + + public static final String MOD_ID = "smeltinginapinch"; // This logger is used to write text to the console and the log file. // It is considered best practice to use your mod id as the logger's name. public static final Logger LOGGER = LoggerFactory.getLogger("modid"); @@ -40,7 +45,7 @@ public class SmeltingInAPinch implements ModInitializer { FabricBlockEntityTypeBuilder.create(DemoBlockEntity::new, DEMO_BLOCK).build() ); - public static final WoodenFurnaceBlock WOODEN_FURNACE_BLOCK = Registry.register( + public static final Block WOODEN_FURNACE_BLOCK = Registry.register( Registries.BLOCK, new Identifier("smeltinginapinch", "wooden_furnace"), new WoodenFurnaceBlock(Block.Settings.create().strength(1.0f)) @@ -55,6 +60,12 @@ public class SmeltingInAPinch implements ModInitializer { new Identifier("smeltinginapinch", "wooden_furnace_block_entity"), FabricBlockEntityTypeBuilder.create(WoodenFurnaceBlockEntity::new, WOODEN_FURNACE_BLOCK).build() ); + + public static final ScreenHandlerType WOODEN_FURNACE_SCREEN_HANDLER = Registry.register( + Registries.SCREEN_HANDLER, + new Identifier("smeltinginapinch", "wooden_furnace_screen_handler"), + new ExtendedScreenHandlerType<>(WoodenFurnaceScreenHandler::new) + ); @Override public void onInitialize() { // This code runs as soon as Minecraft is in a mod-load-ready state. @@ -66,5 +77,8 @@ public void onInitialize() { content.addAfter(Items.BLAST_FURNACE, WOODEN_FURANCE_BLOCK_ITEM); content.addAfter(Items.TORCH, DEMO_BLOCK_ITEM); }); + + // Make sure screen handler and screen are linked together + HandledScreens.register(SmeltingInAPinch.WOODEN_FURNACE_SCREEN_HANDLER, WoodenFurnaceScreen::new); } } \ No newline at end of file diff --git a/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlock.java b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlock.java index a8687e9..c9fe37b 100644 --- a/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlock.java +++ b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlock.java @@ -1,6 +1,7 @@ package jiink.smeltinginapinch; import net.minecraft.block.AbstractFurnaceBlock; +import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.block.BlockWithEntity; import net.minecraft.block.entity.AbstractFurnaceBlockEntity; @@ -12,6 +13,11 @@ import net.minecraft.screen.NamedScreenHandlerFactory; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.ItemScatterer; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.random.Random; import net.minecraft.world.World; @@ -22,6 +28,8 @@ import com.mojang.serialization.MapCodec; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.block.AbstractBlock; public class WoodenFurnaceBlock extends BlockWithEntity { @@ -29,17 +37,55 @@ public WoodenFurnaceBlock(AbstractBlock.Settings settings) { super(settings); } - // @Nullable - // public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { - // return world.isClient ? null : checkType(type, SmeltingInAPinch.WOODEN_FURNACE_BLOCK_ENTITY, WoodenFurnaceBlockEntity::tick); - // } - + @Nullable + public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + return validateTicker(type, SmeltingInAPinch.WOODEN_FURNACE_BLOCK_ENTITY, (world1, pos, state1, be) -> WoodenFurnaceBlockEntity.tick(world1, pos, state1)); + } @Override public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { return new WoodenFurnaceBlockEntity(pos, state); } + @Override + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { + if (state.getBlock() != newState.getBlock()) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (blockEntity instanceof WoodenFurnaceBlockEntity) { + ItemScatterer.spawn(world, pos, (WoodenFurnaceBlockEntity)blockEntity); + world.updateComparators(pos, this); + } + super.onStateReplaced(state, world, pos, newState, moved); + } + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (!world.isClient && hand == Hand.MAIN_HAND) { + NamedScreenHandlerFactory screenHandlerFactory = (WoodenFurnaceBlockEntity)world.getBlockEntity(pos); + if (screenHandlerFactory != null) { + player.openHandledScreen(screenHandlerFactory); + } + } + return ActionResult.PASS; + } + + @Environment(EnvType.CLIENT) + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + double x = (double) pos.getX() + 0.5D; + double y = (double) pos.getY() + 1.0D; + double z = (double) pos.getZ() + 0.5D; + + world.addParticle(ParticleTypes.SMOKE, x, y, z, 0.0D, 0.0D, 0.0D); + world.addParticle(ParticleTypes.FLAME, x, y, z, 0.0D, 0.0D, 0.0D); + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + public static final MapCodec CODEC = WoodenFurnaceBlock.createCodec(WoodenFurnaceBlock::new); @Override protected MapCodec getCodec() { diff --git a/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlockEntity.java b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlockEntity.java index 1e294c3..578310e 100644 --- a/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlockEntity.java +++ b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceBlockEntity.java @@ -1,34 +1,153 @@ package jiink.smeltinginapinch; +import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; import net.minecraft.block.BlockState; import net.minecraft.block.entity.AbstractFurnaceBlockEntity; +import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventories; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.network.PacketByteBuf; import net.minecraft.recipe.RecipeType; import net.minecraft.screen.FurnaceScreenHandler; +import net.minecraft.screen.PropertyDelegate; import net.minecraft.screen.ScreenHandler; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class WoodenFurnaceBlockEntity extends BlockEntity implements ExtendedScreenHandlerFactory, ImplementedInventory { + + public final DefaultedList inventory = DefaultedList.ofSize(2, ItemStack.EMPTY); + private static int INPUT_SLOT = 0; + private static int OUTPUT_SLOT = 1; + + protected final PropertyDelegate propertyDelegate; + private int progress = 0; + private int maxProgress = 64; -public class WoodenFurnaceBlockEntity extends AbstractFurnaceBlockEntity { public WoodenFurnaceBlockEntity(BlockPos pos, BlockState state) { - super(BlockEntityType.FURNACE, pos, state, RecipeType.SMELTING); + super(SmeltingInAPinch.WOODEN_FURNACE_BLOCK_ENTITY, pos, state); + this.propertyDelegate = new PropertyDelegate() { + @Override + public int get(int index) { + return switch (index) { + case 0 -> WoodenFurnaceBlockEntity.this.progress; + case 1 -> WoodenFurnaceBlockEntity.this.maxProgress; + default -> 0; + }; + } + + @Override + public void set(int index, int value) { + switch (index) { + case 0 -> WoodenFurnaceBlockEntity.this.progress = value; + case 1 -> WoodenFurnaceBlockEntity.this.maxProgress = value; + }; + } + + @Override + public int size() { + return 2; + } + + }; + } + + @Override + public Text getDisplayName() { + return Text.literal("Wooden Furnace"); } @Override - protected Text getContainerName() { - return Text.of("Wooden Furnace"); + public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) { + return new WoodenFurnaceScreenHandler(syncId, playerInventory, this, this.propertyDelegate); } @Override - protected int getFuelTime(ItemStack fuel) { - return super.getFuelTime(fuel) / 2; + public DefaultedList getItems() { + return inventory; } @Override - protected ScreenHandler createScreenHandler(int syncId, PlayerInventory playerInventory) { - return new FurnaceScreenHandler(syncId, playerInventory, this, this.propertyDelegate); + public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) { + buf.writeBlockPos(this.pos); + } + + @Override + protected void writeNbt(NbtCompound nbt) { + super.writeNbt(nbt); + Inventories.writeNbt(nbt, inventory); + } + + @Override + public void readNbt(NbtCompound nbt) { + super.readNbt(nbt); + Inventories.readNbt(nbt, inventory); + } + + public void tick(World world, BlockPos pos, BlockState state) { + if (world.isClient) { + return; + } + if (isOutputSlotEmptyOrReceivable()) { + if (this.hasRecipe()) { + this.increaseCraftProgress(); + markDirty(world, pos, state); + if (hasCraftingFinished()) { + this.craftItem(); + this.resetProgress(); + } + } else { + this.resetProgress(); + } + } else { + this.resetProgress(); + markDirty(world, pos, state ); + } + } + + private void resetProgress() { + this.progress = 0; + } + + private void craftItem() { + this.removeStack(INPUT_SLOT, 1); + ItemStack result = new ItemStack(Items.IRON_INGOT); + this.setStack(OUTPUT_SLOT, new ItemStack(result.getItem(), getStack(OUTPUT_SLOT).getCount() + result.getCount())); + } + + private boolean hasCraftingFinished() { + return progress >= maxProgress; + } + + private void increaseCraftProgress() { + progress++; + } + + private boolean hasRecipe() { + ItemStack result = new ItemStack(Items.IRON_INGOT); + boolean hasInput = getStack(INPUT_SLOT).getItem() == Items.RAW_IRON; + return hasInput && canInsertAmountIntoOutputSlot(result) && canInsertItemIntoOutputSlot(result.getItem()); + } + + private boolean canInsertItemIntoOutputSlot(Item item) { + return this.getStack(OUTPUT_SLOT).getItem() == item || this.getStack(OUTPUT_SLOT).isEmpty(); + } + + private boolean canInsertAmountIntoOutputSlot(ItemStack result) { + return this.getStack(OUTPUT_SLOT).getCount() + result.getCount() <= getStack(OUTPUT_SLOT).getMaxCount(); + } + + private boolean isOutputSlotEmptyOrReceivable() { + return this.getStack(OUTPUT_SLOT).isEmpty() || this.getStack(OUTPUT_SLOT).getCount() < this.getStack(OUTPUT_SLOT).getMaxCount(); } } diff --git a/src/main/java/jiink/smeltinginapinch/WoodenFurnaceScreen.java b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceScreen.java new file mode 100644 index 0000000..38d9b94 --- /dev/null +++ b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceScreen.java @@ -0,0 +1,51 @@ +package jiink.smeltinginapinch; + +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.render.GameRenderer; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +public class WoodenFurnaceScreen extends HandledScreen { + + private static final Identifier TEXTURE = new Identifier(SmeltingInAPinch.MOD_ID, "textures/gui/wooden_furnace_gui.png"); + + public WoodenFurnaceScreen(WoodenFurnaceScreenHandler handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + } + + @Override + protected void init() { + super.init(); + titleY = 1000; + playerInventoryTitleY = 1000; + } + + @Override + protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { + RenderSystem.setShader(GameRenderer::getPositionTexProgram); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + RenderSystem.setShaderTexture(0, TEXTURE); + int x = (width - backgroundWidth) / 2; + int y = (height - backgroundHeight) / 2; + context.drawTexture(TEXTURE, x, y, 0, 0, backgroundWidth, backgroundHeight); + renderProgressArrow(context, x, y); + } + + private void renderProgressArrow(DrawContext context, int x, int y) { + if (handler.isCrafting()) { + context.drawTexture(TEXTURE, x + 85, y + 30, 176, 0, 8, handler.getScaledProgress()); + } + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + renderBackground(context); + super.render(context, mouseX, mouseY, delta); + drawMouseoverTooltip(context, mouseX, mouseY); + } + +} diff --git a/src/main/java/jiink/smeltinginapinch/WoodenFurnaceScreenHandler.java b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceScreenHandler.java new file mode 100644 index 0000000..6289fbc --- /dev/null +++ b/src/main/java/jiink/smeltinginapinch/WoodenFurnaceScreenHandler.java @@ -0,0 +1,95 @@ +package jiink.smeltinginapinch; + +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.screen.ArrayPropertyDelegate; +import net.minecraft.screen.PropertyDelegate; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.slot.Slot; + +public class WoodenFurnaceScreenHandler extends ScreenHandler { + + private final Inventory inventory; + private final PropertyDelegate propertyDelegate; + public final WoodenFurnaceBlockEntity blockEntity; + + public WoodenFurnaceScreenHandler(int syncId, PlayerInventory inventory, PacketByteBuf buf) { + this(syncId, inventory, inventory.player.getWorld().getBlockEntity(buf.readBlockPos()), + new ArrayPropertyDelegate(2)); + } + + public WoodenFurnaceScreenHandler(int syncId, PlayerInventory playerInventory, BlockEntity blockEntity, + PropertyDelegate arrayPropertyDelegate) { + super(SmeltingInAPinch.WOODEN_FURNACE_SCREEN_HANDLER, syncId); + checkSize(((Inventory) blockEntity), 2); + this.inventory = ((Inventory) blockEntity); + playerInventory.onOpen(playerInventory.player); + this.propertyDelegate = arrayPropertyDelegate; + this.blockEntity = (WoodenFurnaceBlockEntity) blockEntity; + + this.addSlot(new Slot(inventory, 0, 80, 11)); + this.addSlot(new Slot(inventory, 1, 80, 59)); + this.addPlayerInventory(playerInventory); + addProperties(arrayPropertyDelegate); + } + + @Override + public boolean canUse(PlayerEntity player) { + return this.inventory.canPlayerUse(player); + } + + private void addPlayerInventory(PlayerInventory inventory) { + int i; + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.addSlot(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.addSlot(new Slot(inventory, i, 8 + i * 18, 142)); + } + } + + public boolean isCrafting() { + return this.propertyDelegate.get(0) > 0; + } + + public int getScaledProgress() { + int progress = this.propertyDelegate.get(0); + int maxProgress = this.propertyDelegate.get(1); + int progressArrowSize = 26; + return maxProgress != 0 && progress != 0 ? progress * progressArrowSize / maxProgress : 0; + } + + @Override + public ItemStack quickMove(PlayerEntity player, int invSlot) { + ItemStack newStack = ItemStack.EMPTY; + Slot slot = slots.get(invSlot); + if (slot != null && slot.hasStack()) { + ItemStack originalStack = slot.getStack(); + newStack = originalStack.copy(); + if (invSlot < this.inventory.size()) { + if (!this.insertItem(originalStack, this.inventory.size(), slots.size(), true)) { + return ItemStack.EMPTY; + } + } else if (!this.insertItem(originalStack, 0, this.inventory.size(), false)) { + return ItemStack.EMPTY; + } + + if (originalStack.isEmpty()) { + slot.setStack(ItemStack.EMPTY); + } else { + slot.markDirty(); + } + } + return newStack; + } + +} diff --git a/src/resources/assets/smeltinginapinch/textures/gui/wooden_furnace_gui.png b/src/resources/assets/smeltinginapinch/textures/gui/wooden_furnace_gui.png new file mode 100644 index 0000000..05b396b Binary files /dev/null and b/src/resources/assets/smeltinginapinch/textures/gui/wooden_furnace_gui.png differ