Hello, i got an issue registering my Screen Container.
I followed Jorrit Tybergheins Tutorial on creating a GUI. Again, everything works just fine but the GUI doesnt show up.
After checking the logs, i found the error:
[m[1;31m[21:24:18] [Server thread/FATAL] [minecraft/ThreadTaskExecutor]: Error executing task on Server
java.lang.UnsupportedOperationException: Unable to construct this menu by type
at net.minecraft.inventory.container.Container.getType(Container.java:52) ~[?:?] {re:classloading}
at net.minecraftforge.fml.network.NetworkHooks.openGui(NetworkHooks.java:207) ~[?:?] {re:classloading}
at net.minecraftforge.fml.network.NetworkHooks.openGui(NetworkHooks.java:172) ~[?:?] {re:classloading}
at com.kahmi.elementcrops.objects.blocks.DungInfuserBlock.onBlockActivated(DungInfuserBlock.java:65) ~[?:?] {re:classloading}
at net.minecraft.block.BlockState.onBlockActivated(BlockState.java:294) ~[?:?] {re:classloading}
at net.minecraft.server.management.PlayerInteractionManager.func_219441_a(PlayerInteractionManager.java:343) ~[?:?] {re:classloading}
at net.minecraft.network.play.ServerPlayNetHandler.processTryUseItemOnBlock(ServerPlayNetHandler.java:881) ~[?:?] {re:classloading}
at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.processPacket(CPlayerTryUseItemOnBlockPacket.java:45) ~[?:?] {re:classloading}
at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.processPacket(CPlayerTryUseItemOnBlockPacket.java:12) ~[?:?] {re:classloading}
at net.minecraft.network.PacketThreadUtil.lambda$checkThreadAndEnqueue$0(PacketThreadUtil.java:19) ~[?:?] {re:classloading}
at net.minecraft.util.concurrent.TickDelayedTask.run(TickDelayedTask.java:20) ~[?:?] {re:classloading}
at net.minecraft.util.concurrent.ThreadTaskExecutor.run(ThreadTaskExecutor.java:140) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.util.concurrent.RecursiveEventLoop.run(RecursiveEventLoop.java:22) [?:?] {re:classloading}
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:759) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:141) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.util.concurrent.ThreadTaskExecutor.driveOne(ThreadTaskExecutor.java:110) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.server.MinecraftServer.driveOneInternal(MinecraftServer.java:742) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.server.MinecraftServer.driveOne(MinecraftServer.java:736) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.util.concurrent.ThreadTaskExecutor.driveUntil(ThreadTaskExecutor.java:123) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.server.MinecraftServer.runScheduledTasks(MinecraftServer.java:722) [?:?] {re:classloading,pl:accesstransformer:B}
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:666) [?:?] {re:classloading,pl:accesstransformer:B}
at java.lang.Thread.run(Unknown Source) [?:1.8.0_241] {}
After hours of searching for a solution, i came to the point that it must be failing at the registration of my Container, but i cant get why it doesnt work.
Here is my Registry Class:
package com.kahmi.elementcrops.init;
import com.kahmi.elementcrops.ElementCrops;
import com.kahmi.elementcrops.objects.container.DungInfuserBlockContainer;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.registries.ObjectHolder;
@Mod.EventBusSubscriber(modid = ElementCrops.MOD_ID, bus = Bus.MOD)
@ObjectHolder(ElementCrops.MOD_ID)
public class ContainerInitializer {
@SubscribeEvent
public static void registerContainer(final RegistryEvent.Register<ContainerType<?>> pEvent) {
pEvent.getRegistry().register(IForgeContainerType.create((pWindowID, pInventory, pData) -> {
BlockPos pos = pData.readBlockPos();
return new DungInfuserBlockContainer(pWindowID, ElementCrops.PROXY.getClientWorld(), pos, pInventory, ElementCrops.PROXY.getClientPlayer());
}).setRegistryName("dunginfuser"));
}
}
Here is my Container Class:
package com.kahmi.elementcrops.objects.container;
import com.kahmi.elementcrops.ElementCrops;
import com.kahmi.elementcrops.objects.blocks.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IWorldPosCallable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.registries.ObjectHolder;
@ObjectHolder(ElementCrops.MOD_ID)
public class DungInfuserBlockContainer extends Container {
private TileEntity mEntity;
private PlayerEntity mPlayer;
private IItemHandler mPlayerInventory;
public DungInfuserBlockContainer(int pId, World pWorld, BlockPos pPos, PlayerInventory pInventory, PlayerEntity pPlayer) {
super(Containers.DUNGINFUSERBLOCK_CONTAINER, pId);
this.mEntity = pWorld.getTileEntity(pPos);
this.mPlayer = pPlayer;
this.mPlayerInventory = new InvWrapper(mPlayer.inventory);
this.mEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(h -> {
addSlot(h, 0, 13, 34);
addSlot(h, 1, 34, 34);
addSlotRange(h, 2, 55, 34, 3, 18);
addSlot(h, 5, 141, 34);
});
layoutPlayerInventorySlots(7, 83);
}
@Override
public boolean canInteractWith(PlayerEntity pPlayerIn) {
return isWithinUsableDistance(IWorldPosCallable.of(mEntity.getWorld(), mEntity.getPos()), pPlayerIn, Blocks.DUNGINFUSER);
}
private void addSlot(IItemHandler pItemHandler, int pIndex, int pX, int pY) {
addSlot(new SlotItemHandler(pItemHandler, pIndex, pX, pY));
}
private int addSlotRange(IItemHandler pItemHandler, int pIndex, int pX, int pY, int pAmount, int pDistanceX) {
for (int i = 0; i < pAmount; i++) {
addSlot(pItemHandler, pIndex, pX, pY);
pX += pDistanceX;
pIndex++;
}
return pIndex;
}
private int addSlotBox(IItemHandler pItemHandler, int pIndex, int pX, int pY, int pColumns, int pDistanceX, int pRows, int pDistanceY) {
for (int i = 0; i < pRows; i++) {
pIndex = addSlotRange(pItemHandler, pIndex, pX, pY, pColumns, pDistanceX);
pY += pDistanceY;
}
return pIndex;
}
private void layoutPlayerInventorySlots(int pX, int pY) {
addSlotBox(this.mPlayerInventory, 9, pX, pY, 9, 18, 3, 18);
pY += 58;
addSlotRange(this.mPlayerInventory, 0, pX, pY, 9, 18);
}
}
Here is my Block Class:
package com.kahmi.elementcrops.objects.blocks;
import javax.annotation.Nullable;
import com.kahmi.elementcrops.objects.entities.DungInfuserTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.pathfinding.PathType;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;
public class DungInfuserBlock extends Block {
public static final IntegerProperty LEVEL = IntegerProperty.create("level", 0, 5);
private static final VoxelShape INSIDE = makeCuboidShape(2.0D, 4.0D, 2.0D, 14.0D, 16.0D, 14.0D);
private static final VoxelShape SHAPE = VoxelShapes.combineAndSimplify(VoxelShapes.fullCube(), VoxelShapes.or(makeCuboidShape(0.0D, 0.0D, 4.0D, 16.0D, 3.0D, 12.0D), makeCuboidShape(4.0D, 0.0D, 0.0D, 12.0D, 3.0D, 16.0D), makeCuboidShape(2.0D, 0.0D, 2.0D, 14.0D, 3.0D, 14.0D), INSIDE), IBooleanFunction.ONLY_FIRST);
public DungInfuserBlock(Properties pProperties) {
super(pProperties);
this.setDefaultState(this.stateContainer.getBaseState().with(LEVEL, Integer.valueOf(0)));
}
@Override
public boolean hasTileEntity(BlockState pState) {
return true;
}
@Nullable
@Override
public TileEntity createTileEntity(BlockState pState, IBlockReader pWorld) {
return new DungInfuserTileEntity();
}
@Override
public VoxelShape getShape(BlockState pState, IBlockReader pWorldIn, BlockPos pPos, ISelectionContext pContext) {
return SHAPE;
}
@Override
public VoxelShape getRaytraceShape(BlockState pState, IBlockReader pWworldIn, BlockPos pPos) {
return INSIDE;
}
@Override
public ActionResultType onBlockActivated(BlockState pState, World pWorldIn, BlockPos pPos, PlayerEntity pPlayer, Hand pHandIn, BlockRayTraceResult pResult) {
if (!pWorldIn.isRemote) {
TileEntity entity = pWorldIn.getTileEntity(pPos);
if (entity instanceof INamedContainerProvider) {
NetworkHooks.openGui((ServerPlayerEntity)pPlayer, (INamedContainerProvider)entity, entity.getPos());
} else {
throw new IllegalStateException("Our named container provider is missing!");
}
return ActionResultType.SUCCESS;
}
return super.onBlockActivated(pState, pWorldIn, pPos, pPlayer, pHandIn, pResult);
}
public void setContentLevel(World pWorldIn, BlockPos pPos, BlockState pState, int pLevel) {
pWorldIn.setBlockState(pPos, pState.with(LEVEL, Integer.valueOf(MathHelper.clamp(pLevel, 0, 5))), 2);
pWorldIn.updateComparatorOutputLevel(pPos, this);
}
/**
* @deprecated call via {@link IBlockState#hasComparatorInputOverride()} whenever possible. Implementing/overriding
* is fine.
*/
public boolean hasComparatorInputOverride(BlockState pState) {
return true;
}
/**
* @deprecated call via {@link IBlockState#getComparatorInputOverride(World,BlockPos)} whenever possible.
* Implementing/overriding is fine.
*/
public int getComparatorInputOverride(BlockState pBlockState, World pWorldIn, BlockPos pPos) {
return pBlockState.get(LEVEL);
}
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> pBuilder) {
pBuilder.add(LEVEL);
}
public boolean allowsMovement(BlockState pState, IBlockReader pWorldIn, BlockPos pPos, PathType pType) {
return false;
}
}
if you need more code, i will setup github tomorrow.
Thanks in advance! EDIT: this is my GitHub