Отрисовка блока с жидкостью в инвентаре 1.12.2

Версия Minecraft
1.12.2
API
Forge
122
4
6
Здорова, вопрос в следующем. Я создал блок хранения жидкости и добавил рендер для него 2023-08-29_22.26.18.png но когда оно в руке или инвентаре то не отображается жидкость2023-08-29_22.26.21.png 2023-08-29_22.26.28.png
вод код кто знает в чем проблема прошу подскажите.
блок:
public class MysticalJar extends BlockContainer implements IHasModel {
    public MysticalJar(final String name, final Material material, float hardness, float resistanse, String hravLevel, int level, SoundType soundtype) {
        super(material);
        setRegistryName(name);
        setUnlocalizedName(name);
        setSoundType(soundtype);
        setHardness(hardness);
        setResistance(resistanse);
        setHarvestLevel(hravLevel, level);
        setCreativeTab(Main.CT_MOD);

        BlocksInit.BLOCKS.add(this);
        ItemsInit.ITEMS.add(new ItemBlock(this).setRegistryName(this.getRegistryName()));
    }
    @Override public void registerModels() { Main.proxy.registerItemRenderer(Item.getItemFromBlock(this), 0, "inventory"); }

    @Override
    public void addInformation(ItemStack stack, @Nullable World world, List<String> list, ITooltipFlag flag) {
        NBTTagCompound tag = stack.getTagCompound();
        if (tag != null) {
            NBTTagCompound nbt = tag.getCompoundTag("tank");
            FluidStack fluid = null;
            if (!nbt.hasKey("Empty")) {
                fluid = FluidStack.loadFluidStackFromNBT(nbt);
            }
            if (fluid == null) {
                list.add(I18n.translateToLocalFormatted("title.jar").concat(" empty"));
            } else {
                String name = fluid.getLocalizedName();
                list.add(I18n.translateToLocalFormatted("title.jar") + " " + name + " " + fluid.amount);
            }
        }
    }

    @Override public boolean hasTileEntity(IBlockState state) { return true; }
    @Nullable @Override public TileEntity createNewTileEntity(World world, int meta) { return new TileMysticalJar(); }
    private TileMysticalJar getTile(World w, BlockPos pos) { return (TileMysticalJar) w.getTileEntity(pos); }

    @Override
    public ItemStack getItem(World world, BlockPos pos, IBlockState state) {
        ItemStack stack = new ItemStack(Item.getItemFromBlock(this));
        NBTTagCompound nbt = new NBTTagCompound();
        TileMysticalJar jar = (TileMysticalJar) world.getTileEntity(pos);
        jar.writeRestToNBT(nbt);

        stack.setTagCompound(nbt);
        return stack;
    }

    @Override
    public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
        ItemStack stack = new ItemStack(Item.getItemFromBlock(this));
        NBTTagCompound nbt = new NBTTagCompound();
        TileMysticalJar jar = (TileMysticalJar) world.getTileEntity(pos);
        if (jar != null) {
            jar.writeRestToNBT(nbt);

            stack.setTagCompound(nbt);
            drops.add(stack);
        } else super.getDrops(drops, world, pos, state, fortune);
    }

    @Override
    public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) {
        if (willHarvest) return true;
        return super.removedByPlayer(state, world, pos, player, willHarvest);
    }

    @Override
    public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack) {
        super.harvestBlock(world, player, pos, state, te, stack);
        world.setBlockToAir(pos);
    }

    @Override
    public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
        super.onBlockPlacedBy(world, pos, state, placer, stack);
        TileMysticalJar jar = (TileMysticalJar) world.getTileEntity(pos);
        NBTTagCompound nbt = stack.getTagCompound();
        if (nbt != null) { jar.readRestFromNBT(nbt); }
    }

    @Override
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
        if (!world.isRemote) {
            FluidUtil.interactWithFluidHandler(player, hand, world, pos, facing);

            FluidStack astral_light = new FluidStack(FluidRegistry.getFluid(FluidsInit.ASTRAL_LIGHT_FLUID.getName()), 1000);
            FluidStack astral_dark = new FluidStack(FluidRegistry.getFluid(FluidsInit.ASTRAL_DARK_FLUID.getName()), 1000);
            if (player.getHeldItemMainhand().getItem() == ItemsInit.UNSTABLE_DUST) {
                if (getTile(world, pos).getTank().getInfo().fluid.getFluid().getName() == FluidRegistry.WATER.getName() && getTile(world, pos).getTank().getFluid().amount == 10000) {
                    getTile(world, pos).getTank().drain(10000, true);
                    getTile(world, pos).getTank().fill(astral_light, true);
                    if (!player.capabilities.isCreativeMode) player.getHeldItemMainhand().shrink(1);
                }
                if (getTile(world, pos).getTank().getInfo().fluid.getFluid().getName() == FluidRegistry.LAVA.getName() && getTile(world, pos).getTank().getFluid().amount == 10000) {
                    getTile(world, pos).getTank().drain(10000, true);
                    getTile(world, pos).getTank().fill(astral_dark, true);
                    if (!player.capabilities.isCreativeMode) player.getHeldItemMainhand().shrink(1);
                }
            }
        }
        return true;
    }

    @Override public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) {
        return new AxisAlignedBB(2 / 16D, 0 / 16D, 2 / 16D, 14 / 16D, 16 / 16D, 14 / 16D);
    }
    @Override public boolean isBlockNormalCube(IBlockState state) { return false; }
    @Override public boolean isOpaqueCube(IBlockState state) { return false; }
    @Override public boolean isFullCube(IBlockState state) { return false; }
    @Override public EnumBlockRenderType getRenderType(IBlockState state) { return EnumBlockRenderType.MODEL; }

    @SideOnly(Side.CLIENT)
    @Override public BlockRenderLayer getBlockLayer() { return BlockRenderLayer.CUTOUT; }
}
тайл блока:
public class TileMysticalJar extends TileEntity {
    public static final int MAX_CONTENTS = Fluid.BUCKET_VOLUME * 10;

    private FluidTank tank = new FluidTank(MAX_CONTENTS) {
        @Override protected void onContentsChanged() {
            IBlockState state = world.getBlockState(pos);
            world.notifyBlockUpdate(pos, state, state, 3);
            markDirty();
        }
    };

    @Override public NBTTagCompound getUpdateTag() {
        NBTTagCompound nbtTag = super.getUpdateTag();
        NBTTagCompound tankNBT = new NBTTagCompound();
        tank.writeToNBT(tankNBT);
        nbtTag.setTag("tank", tankNBT);
        return nbtTag;
    }

    @Nullable @Override public SPacketUpdateTileEntity getUpdatePacket() {
        return new SPacketUpdateTileEntity(pos, 1, getUpdateTag());
    }
    @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
        tank.readFromNBT(pkt.getNbtCompound().getCompoundTag("tank"));
    }

    @Override public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        readRestFromNBT(compound);
    }
    @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        writeRestToNBT(compound);
        return super.writeToNBT(compound);
    }
    public void readRestFromNBT(NBTTagCompound compound) {
        tank.readFromNBT(compound.getCompoundTag("tank"));
    }
    public void writeRestToNBT(NBTTagCompound compound) {
        NBTTagCompound tankNBT = new NBTTagCompound();
        tank.writeToNBT(tankNBT);
        compound.setTag("tank", tankNBT);
    }

    public FluidTank getTank() { return tank; }

    @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
        if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { return true; }
        return super.hasCapability(capability, facing);
    }
    @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
        if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(tank); }
        return super.getCapability(capability, facing);
    }
}
рендер:
public class RenderTileMysticalJar extends TileEntitySpecialRenderer<TileMysticalJar> {
    public static final float TANK_THICKNESS = 0.15f;
    public static final float TANK_THICKNESS_1 = 0.02f;

    public RenderTileMysticalJar() {}

    @Override
    public void render(TileMysticalJar te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) {
        GlStateManager.pushMatrix();
        GlStateManager.disableRescaleNormal();
        GlStateManager.color(1, 1, 1, 1);
        GlStateManager.disableBlend();
        GlStateManager.translate((float) x, (float) y, (float) z);

        bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
        renderFluid(te);

        GlStateManager.popMatrix();
    }

    private void renderFluid(TileMysticalJar tank) {
        if (tank == null) { return; }

        FluidStack fluid = tank.getTank().getFluid();
        if (fluid == null) { return; }

        Fluid renderFluid = fluid.getFluid();
        if (renderFluid == null) { return; }

        float scale = (1f - TANK_THICKNESS_1 / 0.2f - TANK_THICKNESS_1) * fluid.amount / (tank.getTank().getCapacity());
        if (scale > 0.0f) {
            Tessellator tessellator = Tessellator.getInstance();
            BufferBuilder renderer = tessellator.getBuffer();
            ResourceLocation still = renderFluid.getStill();
            TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(still.toString());

            net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting();

            GlStateManager.color(1, 1, 1, 0.5f);
            renderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);

            float u1 = sprite.getMinU();
            float v1 = sprite.getMinV();
            float u2 = sprite.getMaxU();
            float v2 = sprite.getMaxV();

            float size = 1f;

            //Top
            renderer.pos(TANK_THICKNESS, scale + TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v1).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, scale + TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u1, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, scale + TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, scale + TANK_THICKNESS_1, TANK_THICKNESS).tex(u2, v1).color(255, 255, 255, 128).endVertex();

            //Bottom
            renderer.pos(size-TANK_THICKNESS, TANK_THICKNESS_1, TANK_THICKNESS).tex(u2, v1).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u1, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v1).color(255, 255, 255, 128).endVertex();

            //Sides
            renderer.pos(TANK_THICKNESS, scale + TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u1, v1).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u1, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, scale + TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v1).color(255, 255, 255, 128).endVertex();

            renderer.pos(size-TANK_THICKNESS, scale + TANK_THICKNESS_1, TANK_THICKNESS).tex(u2, v1).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, TANK_THICKNESS_1, TANK_THICKNESS).tex(u2, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, scale + TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v1).color(255, 255, 255, 128).endVertex();

            renderer.pos(size-TANK_THICKNESS, scale + TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v1).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(size-TANK_THICKNESS, scale + TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v1).color(255, 255, 255, 128).endVertex();

            renderer.pos(TANK_THICKNESS, scale + TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v1).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, TANK_THICKNESS_1, TANK_THICKNESS).tex(u1, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v2).color(255, 255, 255, 128).endVertex();
            renderer.pos(TANK_THICKNESS, scale + TANK_THICKNESS_1, size-TANK_THICKNESS).tex(u2, v1).color(255, 255, 255, 128).endVertex();

            tessellator.draw();

            net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting();
        }
    }
}
регистрация:
public class BlocksInit {
    public static final List<Block> BLOCKS = new ArrayList<Block>();

    public static final Block MYSTICAL_JAR = new MysticalJar("mystical_jar", Material.GLASS, 2.6f, 1200.0f, "", 0, SoundType.GLASS);

    public static void tileReg() {
        registerTile(TileMysticalJar.class, BlocksInit.MYSTICAL_JAR.getRegistryName().toString());
    }
    @SideOnly(Side.CLIENT)
    public static void tileRenderReg() {
        ClientRegistry.bindTileEntitySpecialRenderer(TileMysticalJar.class, new RenderTileMysticalJar());
    }

    private static void registerTile(Class<? extends TileEntity> clazz, String key) {
        GameRegistry.registerTileEntity(clazz, Main.MOD_ID + ":" + key);
    }
}
 
1,074
72
372
Рендерер жидкости привязан к TileEntity, который присутствует только в мире. В инвентаре есть только ItemBlock. Для того чтобы рендерить жидкость на нём, нужно регистрировать свой BlockRenderer, где реализовать рендеринг блока вместе с фейковым TileEntity.
 
Сверху