Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

Hi modders,

as title says I wanted to make a custom furnace (with same recipes as vanilla) but slightly faster.

Is it possible in forge 1.19? If it is, how?

 

So far I made these classes:

Block:

package com.angelobdev.openindustry.block.custom;

import com.angelobdev.openindustry.block.entity.IronFurnaceBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.Stats;
import net.minecraft.util.RandomSource;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.AbstractFurnaceBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;

import javax.annotation.Nullable;

public class IronFurnaceBlock extends AbstractFurnaceBlock {

    public IronFurnaceBlock(BlockBehaviour.Properties properties) {
        super(properties);
    }

    public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
        return new IronFurnaceBlockEntity(pos, state);
    }

    @Nullable
    public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState blockState, BlockEntityType<T> blockEntityType) {
        return createFurnaceTicker(level, blockEntityType, BlockEntityType.FURNACE);
    }

    protected void openContainer(Level level, BlockPos blockPos, Player player) {
        BlockEntity blockentity = level.getBlockEntity(blockPos);
        if (blockentity instanceof IronFurnaceBlockEntity) {
            player.openMenu((MenuProvider) blockentity);
            player.awardStat(Stats.INTERACT_WITH_FURNACE);
        }

    }

    public void animateTick(BlockState blockState, Level level, BlockPos blockPos, RandomSource randomSource) {
        if (blockState.getValue(LIT)) {
            double d0 = (double) blockPos.getX() + 0.5D;
            double d1 = (double) blockPos.getY();
            double d2 = (double) blockPos.getZ() + 0.5D;
            if (randomSource.nextDouble() < 0.1D) {
                level.playLocalSound(d0, d1, d2, SoundEvents.FURNACE_FIRE_CRACKLE, SoundSource.BLOCKS, 1.0F, 1.0F, false);
            }

            Direction direction = blockState.getValue(FACING);
            Direction.Axis direction$axis = direction.getAxis();
            double d3 = 0.52D;
            double d4 = randomSource.nextDouble() * 0.6D - 0.3D;
            double d5 = direction$axis == Direction.Axis.X ? (double) direction.getStepX() * 0.52D : d4;
            double d6 = randomSource.nextDouble() * 6.0D / 16.0D;
            double d7 = direction$axis == Direction.Axis.Z ? (double) direction.getStepZ() * 0.52D : d4;
            level.addParticle(ParticleTypes.SMOKE, d0 + d5, d1 + d6, d2 + d7, 0.0D, 0.0D, 0.0D);
            level.addParticle(ParticleTypes.FLAME, d0 + d5, d1 + d6, d2 + d7, 0.0D, 0.0D, 0.0D);
        }
    }


}

BlockEntity:

package com.angelobdev.openindustry.block.entity;

import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.FurnaceMenu;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull;

public class IronFurnaceBlockEntity extends AbstractFurnaceBlockEntity {
    public IronFurnaceBlockEntity(BlockPos pos, BlockState state) {
        super(BlockEntityType.FURNACE, pos, state, RecipeType.SMELTING);
    }

    protected @NotNull Component getDefaultName() {
        return Component.translatable("container.iron_furnace");
    }

    protected @NotNull AbstractContainerMenu createMenu(int id, @NotNull Inventory inventory) {
        return new FurnaceMenu(id, inventory, this, this.dataAccess);
    }
}

 

UPDATE. Got this warning:

[00:11:10] [Server thread/WARN] [minecraft/LevelChunk]: Block entity minecraft:furnace @ BlockPos{x=119, y=64, z=102} state Block{open_industry:iron_furnace}[facing=west,lit=false] invalid for ticking:

 

Edited by Thread
Warning update

  • Thread changed the title to [1.19.2] Easy way to make a custom furnace?

The warning means the block and the TE does not match, where and how do you register your TE? Is your block added to the list when constructing your TE?

  • Author
1 hour ago, poopoodice said:

The warning means the block and the TE does not match, where and how do you register your TE? Is your block added to the list when constructing your TE?

Sorry I’m new to modding. What is the TE?

Btw I solved the warn by implementing a custom Menu, but the furnace still doesn’t smelt. (BlockEntity is working fine and recipes are loaded correctly)

I don’t know what the error is…

TE = Tile Entity, or Block Entity in recent versions.

I believe you need one for yourself (both MenuType and BlockEntityType) since certain TE/BEs only allows certain blocks (e.g. Vanilla Furnace TE/BE does not work on a custom furnace).

It's also better to post your TE/BE and Menu class along with where and how you register your custom types.

  • Author

Alright, the BE class is already posted, here is the Menu:

package com.angelobdev.openindustry.block.entity.menu;

import net.minecraft.core.Registry;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.*;
import net.minecraft.world.item.crafting.RecipeType;

public class IronFurnaceMenu extends AbstractFurnaceMenu {

    //public static final MenuType<IronFurnaceMenu> IRON_FURNACE = Registry.register(Registry.MENU, "iron_furnace", new MenuType<>(IronFurnaceMenu::new));

//    public IronFurnaceMenu(int ID, Inventory inventory) {
//        super(MenuType.FURNACE, RecipeType.SMELTING, RecipeBookType.FURNACE, ID, inventory);
//    }

    public IronFurnaceMenu(int ID, Inventory inventory, Container container, ContainerData data) {
        super(MenuType.FURNACE, RecipeType.SMELTING, RecipeBookType.FURNACE, ID, inventory, container, data);
    }
}

As you can see I tried to register a custom MenuType (obv it crashed)

Here, instead the BlockEntityType register:

package com.angelobdev.openindustry.block.entity;

import com.angelobdev.openindustry.OpenIndustry;
import com.angelobdev.openindustry.block.OIBlocks;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;

public class OIBlockEntities {

    public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, OpenIndustry.MODID);

    public static final RegistryObject<BlockEntityType<IronFurnaceBlockEntity>> IRON_FURNACE = BLOCK_ENTITIES.register(
            "iron_furnace",
            () -> BlockEntityType.Builder.of(
                    IronFurnaceBlockEntity::new,
                    OIBlocks.IRON_FURNACE.get()
            ).build(null)
    );

    public static void register(IEventBus eventBus) {
        BLOCK_ENTITIES.register(eventBus);
    }
}

I updated the BE class too:

package com.angelobdev.openindustry.block.entity;

import com.angelobdev.openindustry.block.entity.menu.IronFurnaceMenu;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull;

public class IronFurnaceBlockEntity extends AbstractFurnaceBlockEntity {

    public IronFurnaceBlockEntity(BlockPos blockPos, BlockState blockState) {
        super(OIBlockEntities.IRON_FURNACE.get(), blockPos, blockState, RecipeType.SMELTING);
    }

    protected @NotNull Component getDefaultName() {
        return Component.literal("Iron Furnace");
    }

    protected @NotNull AbstractContainerMenu createMenu(int id, @NotNull Inventory inventory) {
        return new IronFurnaceMenu(id, inventory, this, this.dataAccess);
    }

    @Override
    protected int getBurnDuration(@NotNull ItemStack itemStack) {
        return super.getBurnDuration(itemStack) / 2;
    }


}

 

 

Edited by Thread

  • Author

Update, I got some progress. I've registered the custom MenuType as:

package com.angelobdev.openindustry.block.entity.menu;

import com.angelobdev.openindustry.OpenIndustry;
import net.minecraft.world.inventory.MenuType;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;

public class OIMenuType {

    public static final DeferredRegister<MenuType<?>> MENU_TYPES = DeferredRegister.create(ForgeRegistries.MENU_TYPES, OpenIndustry.MODID);

    public static final RegistryObject<MenuType<IronFurnaceMenu>> IRON_FURNACE_MENU = MENU_TYPES.register(
            "name",
            () -> new MenuType<>(IronFurnaceMenu::new)
    );

    public static void register(IEventBus eventBus) {
        MENU_TYPES.register(eventBus);
    }

}

But now I got this warn in the console:

[10:44:16] [Render thread/WARN] [minecraft/MenuScreens]: Failed to create screen for menu type: open_industry:iron_furnace_menu

I'll figure it out, hopefully.

Edited by Thread

Quote

public IronFurnaceMenu(int ID, Inventory inventory, Container container, ContainerData data) { super(MenuType.FURNACE, RecipeType.SMELTING, RecipeBookType.FURNACE, ID, inventory, container, data); }

You should be passing your own menu type into super

  • Author
2 minutes ago, poopoodice said:

You should be passing your own menu type into super

Done already, still not working

  • Author

Alright I solved.

The problem was in registering the screen. I did it by passing this command in the commonSetup.

MenuScreens.register(OIMenuType.IRON_FURNACE_MENU.get(), IronFurnaceScreen::new);

Instead it has to be passed in the clientSetup like so:

    @Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
    public static class ClientModEvents{
        @SubscribeEvent
        public static void onClientSetup(FMLClientSetupEvent event){
            MenuScreens.register(OIMenuType.IRON_FURNACE_MENU.get(), IronFurnaceScreen::new);
        }
    }

Thanks @poopoodice you have been really helpful ❤️

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.