Thread Posted October 6, 2022 Share Posted October 6, 2022 (edited) 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 October 6, 2022 by Thread Warning update Quote Link to comment Share on other sites More sharing options...
poopoodice Posted October 6, 2022 Share Posted October 6, 2022 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? Quote Link to comment Share on other sites More sharing options...
Thread Posted October 7, 2022 Author Share Posted October 7, 2022 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… Quote Link to comment Share on other sites More sharing options...
poopoodice Posted October 7, 2022 Share Posted October 7, 2022 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. Quote Link to comment Share on other sites More sharing options...
Thread Posted October 7, 2022 Author Share Posted October 7, 2022 (edited) 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 October 7, 2022 by Thread Quote Link to comment Share on other sites More sharing options...
Thread Posted October 7, 2022 Author Share Posted October 7, 2022 (edited) 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 October 7, 2022 by Thread Quote Link to comment Share on other sites More sharing options...
poopoodice Posted October 7, 2022 Share Posted October 7, 2022 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 Quote Link to comment Share on other sites More sharing options...
Thread Posted October 7, 2022 Author Share Posted October 7, 2022 2 minutes ago, poopoodice said: You should be passing your own menu type into super Done already, still not working Quote Link to comment Share on other sites More sharing options...
Thread Posted October 7, 2022 Author Share Posted October 7, 2022 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 ❤️ Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.