Posted May 3, 20214 yr Hi have a custom TileEntity in my mod, but when i place it no model is rendered and i get this message in the console: Quote [16:06:09] [Render thread/WARN] [minecraft/TileEntity]: Block entity invalid: tenchest:mini_chest @ BlockPos{x=-186, y=80, z=-273} [16:06:10] [Server thread/WARN] [minecraft/TileEntity]: Block entity invalid: tenchest:mini_chest @ BlockPos{x=-186, y=80, z=-273} What could I do?
May 3, 20214 yr Author This is the TileEntity public class BaseChestTileEntity extends LockableLootTileEntity implements IChestLid, ITickableTileEntity { private NonNullList<ItemStack> inventory; protected float lidAngle; protected float prevLidAngle; protected int numPlayerUsing; private int tickSinceSync; private Supplier<Block> blockToUse; private final int id; protected BaseChestTileEntity(TileEntityType<?> type, Supplier<Block> blockToUse, int id) { super(type); this.id = id; this.inventory = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); this.blockToUse = blockToUse; } @Override protected NonNullList<ItemStack> getItems() { return this.inventory; } @Override protected void setItems(NonNullList<ItemStack> inventory) { this.inventory = inventory; } @Override protected ITextComponent getDefaultName() { return new TranslationTextComponent("container.chest"); } @Override protected Container createMenu(int id, PlayerInventory inventory) { return BaseChestContainer.defaultContainer(id, this, inventory); } @Override public int getContainerSize() { return 27; } @Override public float getOpenNess(float partialTicks) { return MathHelper.lerp(partialTicks, this.prevLidAngle, this.lidAngle); } @Override public void load(BlockState state, CompoundNBT nbt) { super.load(state, nbt); this.inventory = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); if (!this.tryLoadLootTable(nbt)) { ItemStackHelper.loadAllItems(nbt, this.inventory); } } @Override public CompoundNBT save(CompoundNBT nbt) { super.save(nbt); if (!this.trySaveLootTable(nbt)) { ItemStackHelper.saveAllItems(nbt, this.inventory); } return nbt; } @Override public boolean isEmpty() { return this.inventory.isEmpty(); } @Override public void tick() { int i = this.worldPosition.getX(); int j = this.worldPosition.getY(); int k = this.worldPosition.getZ(); ++this.tickSinceSync; this.numPlayerUsing = getNumberOfPlayersUsing(this.level, this, this.tickSinceSync, i, j, k, this.numPlayerUsing); this.prevLidAngle = this.lidAngle; float f = 0.1F; if (this.numPlayerUsing > 0 && this.lidAngle == 0.0F) { this.playSound(SoundEvents.CHEST_OPEN); } if (this.numPlayerUsing == 0 && this.lidAngle > 0.0F || this.numPlayerUsing > 0 && this.lidAngle < 1.0F) { float f1 = this.lidAngle; if (this.numPlayerUsing > 0) { this.lidAngle += 0.1F; } else { this.lidAngle -= 0.1F; } if (this.lidAngle > 1.0F) { this.lidAngle = 1.0F; } float f2 = 0.5F; if (this.lidAngle < 0.5F && f1 >= 0.5F) { this.playSound(SoundEvents.CHEST_CLOSE); } if (this.lidAngle < 0.0F) { this.lidAngle = 0.0F; } } } public static int getNumberOfPlayersUsing(World worldIn, LockableTileEntity lockableTileEntity, int ticksSinceSync, int x, int y, int z, int numPlayersUsing) { if (!worldIn.isClientSide && numPlayersUsing != 0 && (ticksSinceSync + x + y + z) % 200 == 0) { numPlayersUsing = getNumberOfPlayersUsing(worldIn, lockableTileEntity, x, y, z); } return numPlayersUsing; } public static int getNumberOfPlayersUsing(World world, LockableTileEntity lockableTileEntity, int x, int y, int z) { int i = 0; for (PlayerEntity playerentity : world.getEntitiesOfClass(PlayerEntity.class, new AxisAlignedBB((double) ((float) x - 5.0F), (double) ((float) y - 5.0F), (double) ((float) z - 5.0F), (double) ((float) (x + 1) + 5.0F), (double) ((float) (y + 1) + 5.0F), (double) ((float) (z + 1) + 5.0F)))) { if (playerentity.containerMenu instanceof BaseChestContainer) { ++i; } } return i; } private void playSound(SoundEvent soundEvent) { double d0 = (double) this.worldPosition.getX() + 0.5D; double d1 = (double) this.worldPosition.getY() + 0.5D; double d2 = (double) this.worldPosition.getZ() + 0.5D; assert this.level != null; this.level.playSound(null, d0, d1, d2, soundEvent, SoundCategory.BLOCKS, 0.5F, this.level.random.nextFloat() * 0.1F + 0.9F); } public Supplier<Block> getBlockToUse() { return blockToUse; } } This is the Block: public class BaseChestBlock extends Block implements IWaterLoggable { public static final DirectionProperty FACING; public static final BooleanProperty WATERLOGGED; public static final VoxelShape SHAPE; private final Supplier<TileEntityType<? extends TileEntity>> tileEntityTypeSupplier; static { FACING = HorizontalBlock.FACING; WATERLOGGED = BlockStateProperties.WATERLOGGED; SHAPE = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D); } public BaseChestBlock(Properties properties, Supplier<TileEntityType<? extends TileEntity>> tileEntityTypeSupplier) { super(properties); this.tileEntityTypeSupplier = tileEntityTypeSupplier; this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(WATERLOGGED, Boolean.FALSE)); } @Override public BlockState updateShape(BlockState state, Direction dir, BlockState oldState, IWorld world, BlockPos pos, BlockPos oldPos) { if (state.hasProperty(WATERLOGGED)) { world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); } return super.updateShape(state, dir, oldState, world, pos, oldPos); } @Override public BlockRenderType getRenderShape(BlockState p_149645_1_) { return BlockRenderType.ENTITYBLOCK_ANIMATED; } @Override public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_, ISelectionContext p_220053_4_) { return SHAPE; } @Nullable @Override public BlockState getStateForPlacement(BlockItemUseContext context) { Direction nearestLookingDirection = context.getNearestLookingDirection(); Direction dir = nearestLookingDirection.getOpposite(); if (dir.equals(Direction.UP) || dir.equals(Direction.DOWN)) dir = Direction.NORTH; FluidState state = context.getLevel().getFluidState(context.getClickedPos()); System.out.println("Dir: " + dir); return this.defaultBlockState().setValue(FACING, dir).setValue(WATERLOGGED, state.getType() == Fluids.WATER); } @Override public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } @Override public void onRemove(BlockState state, World world, BlockPos pos, BlockState newState, boolean isMoving) { if (!state.is(newState.getBlock())) { TileEntity tileEntity = world.getBlockEntity(pos); if (tileEntity instanceof IInventory) { InventoryHelper.dropContents(world, pos, (IInventory) tileEntity); world.updateNeighbourForOutputSignal(pos, this); } } super.onRemove(state, world, pos, newState, isMoving); } @Override public void setPlacedBy(World p_180633_1_, BlockPos p_180633_2_, BlockState p_180633_3_, @Nullable LivingEntity p_180633_4_, ItemStack p_180633_5_) { super.setPlacedBy(p_180633_1_, p_180633_2_, p_180633_3_, p_180633_4_, p_180633_5_); } @Override public ActionResultType use(BlockState p_225533_1_, World p_225533_2_, BlockPos p_225533_3_, PlayerEntity p_225533_4_, Hand p_225533_5_, BlockRayTraceResult p_225533_6_) { if (p_225533_2_.isClientSide) { return ActionResultType.SUCCESS; } else { INamedContainerProvider inamedcontainerprovider = this.getMenuProvider(p_225533_1_, p_225533_2_, p_225533_3_); if (inamedcontainerprovider != null) { p_225533_4_.openMenu(inamedcontainerprovider); p_225533_4_.awardStat(this.getOpenChestStat()); PiglinTasks.angerNearbyPiglins(p_225533_4_, true); } return ActionResultType.CONSUME; } } private Stat<ResourceLocation> getOpenChestStat() { return Stats.CUSTOM.get(Stats.OPEN_CHEST); } @Nullable @Override public INamedContainerProvider getMenuProvider(BlockState state, World world, BlockPos pos) { TileEntity entity = world.getBlockEntity(pos); return entity instanceof INamedContainerProvider ? (INamedContainerProvider) entity : null; } @Override public boolean hasTileEntity(BlockState state) { return true; } @Override public boolean triggerEvent(BlockState state, World world, BlockPos pos, int id, int param) { super.triggerEvent(state, world, pos, id, param); TileEntity entity = world.getBlockEntity(pos); return entity != null && entity.triggerEvent(id, param); } private static boolean isBlocked(Object iWorld, Object pos) { IWorld world = (IWorld) iWorld; BlockPos blockPos = (BlockPos) pos; return isBelowSolidBlock(world, blockPos) || isCatSittingOn(world, blockPos); } private static boolean isBelowSolidBlock(IBlockReader iBlockReader, BlockPos worldIn) { BlockPos blockpos = worldIn.above(); return iBlockReader.getBlockState(blockpos).isSolidRender(iBlockReader, blockpos); } private static boolean isCatSittingOn(IWorld iWorld, BlockPos blockPos) { int z = blockPos.getZ(); int y = blockPos.getY(); int x = blockPos.getX(); List<CatEntity> list = iWorld.getEntitiesOfClass(CatEntity.class, new AxisAlignedBB((double) x, (double) (y + 1), (double) z, (double) (x + 1), (double) (y + 2), (double) (z + 1))); if (!list.isEmpty()) { for (CatEntity catentity : list) { if (catentity.isInSittingPose()) { return true; } } } return false; } @Override public boolean hasAnalogOutputSignal(BlockState p_149740_1_) { return true; } @Override public int getAnalogOutputSignal(BlockState state, World world, BlockPos pos) { return Container.getRedstoneSignalFromContainer((IInventory) world.getBlockEntity(pos)); } public BlockState rotate(BlockState state, Rotation rotation) { return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); } public BlockState mirror(BlockState state, Mirror mirror) { return state.rotate(mirror.getRotation(state.getValue(FACING))); } protected void createBlockStateDefinition(StateContainer.Builder<Block, BlockState> builder) { builder.add(FACING, WATERLOGGED); } public boolean isPathfindable(BlockState state, IBlockReader reader, BlockPos pos, PathType pathType) { return false; } public static Direction getDirectionToAttached(BlockState state) { Direction direction = state.getValue(FACING); return direction.getCounterClockWise(); } @OnlyIn(Dist.CLIENT) public static TileEntityMerger.ICallback<BaseChestTileEntity, Float2FloatFunction> getLid(final IChestLid chestLid) { return new TileEntityMerger.ICallback<BaseChestTileEntity, Float2FloatFunction>() { @Override public Float2FloatFunction acceptDouble(BaseChestTileEntity tileEntity1, BaseChestTileEntity tileEntity2) { return (value) -> Math.max(tileEntity1.getOpenNess(value), tileEntity2.getOpenNess(value)); } @Override public Float2FloatFunction acceptSingle(BaseChestTileEntity tileEntity) { return tileEntity::getOpenNess; } @Override public Float2FloatFunction acceptNone() { return chestLid::getOpenNess; } }; } public TileEntityMerger.ICallbackWrapper<? extends BaseChestTileEntity> getWrapper(BlockState state, World world, BlockPos pos, boolean b) { BiPredicate biPredicate; if (b) { biPredicate = (v1, v2) -> false; } else { biPredicate = BaseChestBlock::isBlocked; } return TileEntityMerger.combineWithNeigbour(this.tileEntityTypeSupplier.get(), BaseChestBlock::getMergerType, BaseChestBlock::getDirectionToAttached, FACING, state, world, pos, biPredicate); } public static TileEntityMerger.Type getMergerType(BlockState blockState) { return TileEntityMerger.Type.SINGLE; } } This is the TileEntityRendered: public class BaseChestTileEntityRendered<T extends TileEntity & IChestLid> extends TileEntityRenderer<T> { private final ModelRenderer chestLid; private final ModelRenderer chestBottom = new ModelRenderer(64, 64, 0, 19); private final ModelRenderer chestLock; private final int id; public BaseChestTileEntityRendered(TileEntityRendererDispatcher dispatcher) { super(dispatcher); this.id = -1; this.chestBottom.addBox(1.0f, 0.0f, 1.0f, 14.0f, 10.0f, 14.0f, 0.0f); this.chestLid = new ModelRenderer(64, 64, 0, 0); this.chestLid.addBox(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F); this.chestLid.x = 9.0f; this.chestLid.y = 1.0f; this.chestLock = new ModelRenderer(64, 64, 0, 0); this.chestLock.addBox(7.0f, -1.0f, 15.0f, 2.0f, 4.0f, 1.0f, 0.0f); this.chestLock.x = 8.0f; } @Override public void render(T tileEntity, float partialTicks, MatrixStack matrixStack, IRenderTypeBuffer buffer, int combineLight, int combineOverlay) { BaseChestTileEntity entity = (BaseChestTileEntity) tileEntity; World world = entity.getLevel(); boolean flag = world != null; BlockState state = flag ? entity.getBlockState() : entity.getBlockToUse().get().defaultBlockState().setValue(BaseChestBlock.FACING, Direction.SOUTH); Block block = state.getBlock(); if (block instanceof BaseChestBlock) { BaseChestBlock chest = (BaseChestBlock) block; matrixStack.pushPose(); float f = state.getValue(BaseChestBlock.FACING).toYRot(); matrixStack.translate(0.5D, 0.5D, 0.5D); matrixStack.mulPose(Vector3f.YP.rotationDegrees(-f)); matrixStack.translate(-0.5D, -0.5D, -0.5D); TileEntityMerger.ICallbackWrapper<? extends BaseChestTileEntity> iCallbackWrapper; if (flag) { iCallbackWrapper = chest.getWrapper(state, world, entity.getBlockPos(), true); } else { iCallbackWrapper = TileEntityMerger.ICallback::acceptNone; } float f1 = (iCallbackWrapper.apply(BaseChestBlock.getLid(entity))).get(partialTicks); f1 = 1.0f - f1; f1 = 1.0f - f1 * f1 * f1; int i = (int) (iCallbackWrapper.apply(BaseChestBlock.getLid(entity))).get(combineLight); RenderMaterial material = new RenderMaterial(Atlases.CHEST_SHEET, BaseChestModel.getChestTexture(this.id)); IVertexBuilder vertexBuilder = material.buffer(buffer, RenderType::entityCutout); this.handleModelRender(matrixStack, vertexBuilder, this.chestLid, this.chestLock, this.chestBottom, f1, i, combineOverlay); matrixStack.popPose(); } } private void handleModelRender(MatrixStack matrixStackIn, IVertexBuilder iVertexBuilder, ModelRenderer firstModel, ModelRenderer secondModel, ModelRenderer thirdModel, float f1, int p_228871_7_, int p_228871_8_) { firstModel.xRot = -(f1 * 1.5707964F); secondModel.xRot = firstModel.xRot; firstModel.render(matrixStackIn, iVertexBuilder, p_228871_7_, p_228871_8_); secondModel.render(matrixStackIn, iVertexBuilder, p_228871_7_, p_228871_8_); thirdModel.render(matrixStackIn, iVertexBuilder, p_228871_7_, p_228871_8_); } }
May 3, 20214 yr Author The Mod Main: https://pastebin.com/ehmkfGN0 The Block Registry: https://pastebin.com/2QPPXvYR The Tile Entity Registry: https://pastebin.com/325NqTgw Edited May 3, 20214 yr by Yurim64
May 3, 20214 yr Author Ok, now it renders, but with 2 problems: 1 -> It should be bronze color, but it's like on shadow 2 -> How can i animate it like a chest when open?
May 3, 20214 yr Author Ok nothing, i adjust the light value in the TileEntityRenderer and now its fine For the open animation i just see the vanilla code and make it work. Thanks for the help
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.