Блок в блок

Версия Minecraft
1.12.2
5,024
47
784
Вроде бы я уже задавал такой вопрос, а вроде бы и нет, плохо помню. В общем, есть блок - обои. Он тонкий, занимает мало места визуально и физически. Но геймплейно целый блок. Вопрос, как сделать, чтобы блок был "призрачным"? Т.е чтобы в этот блок можно было ставить еще один блок. Есть какие то мысли подглядеть в BlockAir, но там есть что то похожее вроде
Java:
    public boolean canCollideCheck(IBlockState state, boolean hitIfLiquid)
    {
        return false;
    }
Но тогда пропадут нормалли и я не смогу с ним взаимодействовать... Как бы и нормали оставить, и сделать его "воздухом с моделью"?
 
Последнее редактирование:
5,024
47
784

Icosider

Kotliner
Администратор
3,603
99
664
Java:
public class CoordSaveData extends WorldSavedData
{
    public List<BlockPos> list = new ArrayList<>();

    private final EntityPlayer player = mc.player;
    private final World world = mc.world;
    private final RayTraceResult raytraceresult = RenderWallpaper.rayTrace(world, player, true);
    private final BlockPos blockpos = raytraceresult.getBlockPos();
    int coordX, coordY, coordZ;//Чё это? Я не вижу, чтоб ты его где-то использовал(вроде как в этом файле)

    public CoordSaveData(String name)
    {
        super(name);
    }

    @Override
    public void readFromNBT(NBTTagCompound nbt)
    {
        list.clear()
        final int size = nbt.getInteger("size");
     
        for (int i = 0; i < size; i++)
        {
            final int posX = nbt.getInteger("posX_" + i);
            final int posY = nbt.getInteger("posY_" + i);
            final int posZ = nbt.getInteger("posZ_" + i);
            list.add(new BlockPos(posX, posY, posZ));
        }
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound nbt)
    {
        nbt.setInteger("size", list.size());

        for (int i = 0; i < list.size(); i++)
        {
            nbt.setInteger("posX_" + i, pos.getX())
            nbt.setInteger("posY_" + i, pos.getY())
            nbt.setInteger("posZ_" + i, pos.getZ())
        }
        return nbt;
    }
}
Ещё лучше создать подраздел(аля папку) и туда писать все свои координаты, а то данные мира быстро засрёшь и потом не очень удобно будет читать их.
 
Последнее редактирование:
5,024
47
784
5,024
47
784
Нулл по прежнему вылетает прекраснейшим образом... (
В рейтрейсе теперь правда...
Хотя проверка на нулл существует
Java:
[18:40:14] [Server thread/ERROR] [FML]: Exception caught during firing event net.minecraftforge.event.world.WorldEvent$Load@54428d90:
java.lang.NullPointerException: null
    at ru.lg.SovietMod.Event.RenderWallpaper.rayTrace(RenderWallpaper.java:193) ~[RenderWallpaper.class:?]
    at ru.lg.SovietMod.Event.RenderWallpaper$CoordSaveData.<init>(RenderWallpaper.java:78) ~[RenderWallpaper$CoordSaveData.class:?]
    at ru.lg.SovietMod.Event.RenderWallpaper.handleWorldLoad(RenderWallpaper.java:62) ~[RenderWallpaper.class:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_12_RenderWallpaper_handleWorldLoad_Load.invoke(.dynamic) ~[?:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) ~[ASMEventHandler.class:?]
    at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:179) [EventBus.class:?]
    at net.minecraft.server.integrated.IntegratedServer.loadAllWorlds(IntegratedServer.java:133) [IntegratedServer.class:?]
    at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:160) [IntegratedServer.class:?]
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:550) [MinecraftServer.class:?]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_151]
[18:40:14] [Server thread/ERROR] [FML]: Index: 3 Listeners:
[18:40:14] [Server thread/ERROR] [FML]: 0: HIGHEST
[18:40:14] [Server thread/ERROR] [FML]: 1: ASM: net.minecraftforge.common.ForgeInternalHandler@61267fa2 onDimensionLoad(Lnet/minecraftforge/event/world/WorldEvent$Load;)V
[18:40:14] [Server thread/ERROR] [FML]: 2: NORMAL
[18:40:14] [Server thread/ERROR] [FML]: 3: ASM: ru.lg.SovietMod.Event.RenderWallpaper@7862e409 handleWorldLoad(Lnet/minecraftforge/event/world/WorldEvent$Load;)V
[18:40:14] [Server thread/ERROR]: Encountered an unexpected exception
java.lang.NullPointerException: null
    at ru.lg.SovietMod.Event.RenderWallpaper.rayTrace(RenderWallpaper.java:193) ~[RenderWallpaper.class:?]
    at ru.lg.SovietMod.Event.RenderWallpaper$CoordSaveData.<init>(RenderWallpaper.java:78) ~[RenderWallpaper$CoordSaveData.class:?]
    at ru.lg.SovietMod.Event.RenderWallpaper.handleWorldLoad(RenderWallpaper.java:62) ~[RenderWallpaper.class:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_12_RenderWallpaper_handleWorldLoad_Load.invoke(.dynamic) ~[?:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) ~[ASMEventHandler.class:?]
    at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:179) ~[EventBus.class:?]
    at net.minecraft.server.integrated.IntegratedServer.loadAllWorlds(IntegratedServer.java:133) ~[IntegratedServer.class:?]
    at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:160) ~[IntegratedServer.class:?]
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:550) [MinecraftServer.class:?]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_151]
[18:40:14] [Server thread/ERROR]: This crash report has been saved to: C:\Users\Maxims\Desktop\SovietLab 1.12.2\run\.\crash-reports\crash-2018-07-04_18.40.14-server.txt
[18:40:14] [Server thread/INFO]: Stopping server
[18:40:14] [Server thread/INFO]: Saving players
[18:40:14] [Server thread/INFO]: Saving worlds
[18:40:14] [Server thread/INFO]: Saving chunks for level 'Новый мир'/overworld
[18:40:14] [Server thread/INFO]: Saving chunks for level 'Новый мир'/the_end
[18:40:14] [Server thread/INFO] [FML]: Unloading dimension 0
[18:40:14] [Server thread/INFO] [FML]: Unloading dimension 1
[18:40:14] [Server thread/INFO] [FML]: Applying holder lookups
[18:40:14] [Server thread/INFO] [FML]: Holder lookups applied
[18:40:14] [Server thread/INFO] [FML]: The state engine was in incorrect state SERVER_STARTING and forced into state SERVER_STOPPED. Errors may have been discarded.
P.S После твоего изменения там остались pos'ы которые непонятно откуда. Я их заменил на blockpos который сверху.
 
7,099
324
1,510
5,024
47
784
Все, я пошел в танки играть. Моих нервов не хватает на этот пи****. Ни то не работает, ни другое, по непонятным мне причинам...
Через часик еще раз попробую
 
5,024
47
784
Код выглядит сейчас вот так. Посмотри пожалуйста, все ли тут так, как теоретически, должно быть?

Нулл вылетает на строке data.list.add(pos);, хотя проверка на землю не проходит. Вообще чертовщина какая то...
Java:
public class RenderWallpaper {

    Minecraft mc = Minecraft.getMinecraft();
    Block block;
    boolean isClicked;
    @SideOnly(Side.CLIENT)
    @SubscribeEvent
    public void isClickRight(PlayerInteractEvent.RightClickBlock e) {
        isClicked = false;
    }
    @SideOnly(Side.CLIENT)
    @SubscribeEvent
    public void isClickLeft(PlayerInteractEvent.LeftClickBlock e) {
        isClicked = true;
    }
    private static final String DATA_NAME = SovietCore.MODID + "_coordData";
    static boolean IS_GLOBAL;
    @SubscribeEvent
    public void handleWorldLoad(WorldEvent.Load event) {
        MapStorage storage = IS_GLOBAL ? event.getWorld().getMapStorage() : event.getWorld().getPerWorldStorage();
        CoordSaveData data = (CoordSaveData) storage.getOrLoadData(CoordSaveData.class, DATA_NAME);
        event.getWorld().getMapStorage().getOrLoadData(CoordSaveData.class, DATA_NAME);
       
        if (data == null) {
            data = new CoordSaveData(DATA_NAME);
            event.getWorld().getMapStorage().setData(DATA_NAME, data);
        }
        event.getWorld().getMapStorage().setData(DATA_NAME, data);
    }


    public class CoordSaveData extends WorldSavedData
    {
        public List<BlockPos> list = new ArrayList<>();

        private final EntityPlayer player = mc.player;
        private final World world = mc.world;
        private final RayTraceResult raytraceresult = RenderWallpaper.rayTrace(world, player, true);
        private final BlockPos blockpos = raytraceresult.getBlockPos();
   

        public CoordSaveData(String name)
        {
            super(name);
        }

        @Override
        public void readFromNBT(NBTTagCompound nbt)
        {
            list.clear();
            final int size = nbt.getInteger("size");
       
            for (int i = 0; i < size; i++)
            {
                final int posX = nbt.getInteger("posX_" + i);
                final int posY = nbt.getInteger("posY_" + i);
                final int posZ = nbt.getInteger("posZ_" + i);
                list.add(new BlockPos(posX, posY, posZ));
            }
        }

        @Override
        public NBTTagCompound writeToNBT(NBTTagCompound nbt)
        {
            nbt.setInteger("size", list.size());

            for (int i = 0; i < list.size(); i++)
            {
                nbt.setInteger("posX_" + i, blockpos.getX());
                nbt.setInteger("posY_" + i, blockpos.getY());
                nbt.setInteger("posZ_" + i, blockpos.getZ());
            }
            return nbt;
        }
    }

    @SideOnly(Side.CLIENT)
    @SubscribeEvent
    public void render(RenderWorldLastEvent event) {
        EntityPlayer player = mc.player;

        World world = Minecraft.getMinecraft().world;
        RayTraceResult raytraceresult = this.rayTrace(world, player, true);
        if (raytraceresult == null)
        {
            return;
        }
        BlockPos blockpos = raytraceresult.getBlockPos();
        EnumFacing facing = raytraceresult.sideHit;
        CoordSaveData data = (CoordSaveData)world.loadData(CoordSaveData.class, DATA_NAME);

        if(!mc.isGamePaused()) {
            GlStateManager.enableBlend();
            GlStateManager.color(1.0F, 1.0F, 1.0F, 0.5F);
            GlStateManager.doPolygonOffset(-3.0F, -3.0F);
            GlStateManager.enablePolygonOffset();
            GlStateManager.alphaFunc(516, 0.1F);
            GlStateManager.enableAlpha();
            GlStateManager.pushMatrix();

            block = mc.world.getBlockState(blockpos).getBlock();


            int x = blockpos.getX();
            int y = blockpos.getY();
            int z = blockpos.getZ();

            BlockPos pos = new BlockPos(x,y,z);


            if(blockpos == null || !blockpos.equals(blockpos.down())) {
                if(block == Blocks.DIRT)
                    data.list.add(pos);
                //    drawBlockTexture(mc.player, 0.5f, data.coordX, data.coordY , data.coordZ, mc.world, "soviet:blocks/wallpaper_1");
                //data.blockpos.add(x,y,z);
            }
            GlStateManager.disableAlpha();
            GlStateManager.doPolygonOffset(0F, 0.0F);
            GlStateManager.disablePolygonOffset();
            GlStateManager.enableAlpha();
            GlStateManager.depthMask(true);
            GlStateManager.popMatrix();
        }

    }

    public static void drawBlockTexture(Entity entityIn, float partialTicks, int x,int y,int z, World world, String texture) {
        BlockPos  pos = new BlockPos(x,y,z);
        double d3 = entityIn.lastTickPosX + (entityIn.posX - entityIn.lastTickPosX) * (double) partialTicks;
        double d4 = entityIn.lastTickPosY + (entityIn.posY - entityIn.lastTickPosY) * (double) partialTicks;
        double d5 = entityIn.lastTickPosZ + (entityIn.posZ - entityIn.lastTickPosZ) * (double) partialTicks;
        Tessellator tessellatorIn = Tessellator.getInstance();
        BufferBuilder bufferBuilderIn = tessellatorIn.getBuffer();
        Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
        bufferBuilderIn.begin(7, DefaultVertexFormats.BLOCK);
        bufferBuilderIn.setTranslation(-d3, -d4, -d5);
        bufferBuilderIn.noColor();
        IBlockState state = world.getBlockState(new BlockPos(x,y,z));
        TextureMap texturemap = Minecraft.getMinecraft().getTextureMapBlocks();
        BlockModelRenderer blockModelRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelRenderer();
        BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
        BlockModelShapes bms = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
        IBakedModel ibakedmodel = bms.getModelForState(state);
        List<BakedQuad> ql = ibakedmodel.getQuads(state, EnumFacing.getFacingFromVector(x, y, z), (long)1);;
        blockModelRenderer.renderModel(world, ibakedmodel, state, pos, Tessellator.getInstance().getBuffer(), true);
        tessellatorIn.draw();
        bufferBuilderIn.setTranslation(0D, 0.0D, 0D);

    }

    public static RayTraceResult rayTrace(World worldIn, EntityPlayer playerIn, boolean useLiquids)
    {
        float f = playerIn.rotationPitch;
        float f1 = playerIn.rotationYaw;
        double d0 = playerIn.posX;
        double d1 = playerIn.posY + (double)playerIn.getEyeHeight();
        double d2 = playerIn.posZ;
        Vec3d vec3d = new Vec3d(d0, d1, d2);
        float f2 = MathHelper.cos(-f1 * 0.017453292F - (float)Math.PI);
        float f3 = MathHelper.sin(-f1 * 0.017453292F - (float)Math.PI);
        float f4 = -MathHelper.cos(-f * 0.017453292F);
        float f5 = MathHelper.sin(-f * 0.017453292F);
        float f6 = f3 * f4;
        float f7 = f2 * f4;
        double d3 = playerIn.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue();
        Vec3d vec3d1 = vec3d.addVector((double)f6 * d3, (double)f5 * d3, (double)f7 * d3);
        return worldIn.rayTraceBlocks(vec3d, vec3d1, useLiquids, !useLiquids, false);
    }

}
 
5,024
47
784
В общем, я родил, наконец-то. Через рендер и всд сделать так ничего и не получилось, сделал через сущности. Если кому в будущем пригодится может, вот:
Java:
@SideOnly(Side.CLIENT)
public class RenderEntityWallpaper extends Render<EntityWallpaper>
{
    private static final ResourceLocation wallpaper_1 = new ResourceLocation(SovietCore.MODID + ":textures/blocks/wallpaper_1.png");

    public RenderEntityWallpaper(RenderManager renderManagerIn)
    {
        super(renderManagerIn);
    }

    public void doRender(EntityWallpaper entity, double x, double y, double z, float entityYaw, float partialTicks)
    {
        GlStateManager.pushMatrix();
        GlStateManager.translate(x, y, z);
        GlStateManager.rotate(180.0F - entityYaw, 0.0F, 1.0F, 0.0F);
        GlStateManager.enableRescaleNormal();
        this.bindEntityTexture(entity);
    
        float f = 0.5F;
        GlStateManager.scale(0.0625F, 0.0625F, 0.0625F);

        if (this.renderOutlines)
        {
            GlStateManager.enableColorMaterial();
            GlStateManager.enableOutlineMode(this.getTeamColor(entity));
        }

        this.renderPainting(entity, 16, 16, 1, 0);

        if (this.renderOutlines)
        {
            GlStateManager.disableOutlineMode();
            GlStateManager.disableColorMaterial();
        }

        GlStateManager.disableRescaleNormal();
        GlStateManager.popMatrix();
        super.doRender(entity, x, y, z, entityYaw, partialTicks);
    }

    protected ResourceLocation getEntityTexture(EntityWallpaper entity)
    {
        return wallpaper_1;
    }
    
    public class WPRenderFactory implements IRenderFactory {

        @Override
        public Render createRenderFor(RenderManager manager) {
            return new RenderEntityWallpaper(manager);
        }

    }
    private void renderPainting(EntityWallpaper painting, int width, int height, int textureU, int textureV)
    {
        float f = (float)(-width) / 2.0F;
        float f1 = (float)(-height) / 2.0F;
        float f2 = 0.5F;
        float f3 = 0.75F;
        float f4 = 0.8125F;
        float f5 = 0.0F;
        float f6 = 0.0625F;
        float f7 = 0.75F;
        float f8 = 0.8125F;
        float f9 = 0.001953125F;
        float f10 = 0.001953125F;
        float f11 = 0.7519531F;
        float f12 = 0.7519531F;
        float f13 = 0.0F;
        float f14 = 0.0625F;

        for (int i = 0; i < width / 16; ++i)
        {
            for (int j = 0; j < height / 16; ++j)
            {
                float f15 = f + (float)((i + 1) * 16);
                float f16 = f + (float)(i * 16);
                float f17 = f1 + (float)((j + 1) * 16);
                float f18 = f1 + (float)(j * 16);
                this.setLightmap(painting, (f15 + f16) / 2.0F, (f17 + f18) / 2.0F);
                float f19 = (float)(textureU + width - i * 16) / 16.0F;
                float f20 = (float)(textureU + width - (i + 1) * 16) / 16.0F;
                float f21 = (float)(textureV + height - j * 16) / 16.0F;
                float f22 = (float)(textureV + height - (j + 1) * 16) / 16.0F;
                Tessellator tessellator = Tessellator.getInstance();
                BufferBuilder bufferbuilder = tessellator.getBuffer();
                bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_NORMAL);
                bufferbuilder.pos((double)f15, (double)f18, -0.5D).tex((double)f20, (double)f21).normal(0.0F, 0.0F, -1.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f18, -0.5D).tex((double)f19, (double)f21).normal(0.0F, 0.0F, -1.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f17, -0.5D).tex((double)f19, (double)f22).normal(0.0F, 0.0F, -1.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f17, -0.5D).tex((double)f20, (double)f22).normal(0.0F, 0.0F, -1.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f17, 0.5D).tex(0.75D, 0.0D).normal(0.0F, 0.0F, 1.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f17, 0.5D).tex(0.8125D, 0.0D).normal(0.0F, 0.0F, 1.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f18, 0.5D).tex(0.8125D, 0.0625D).normal(0.0F, 0.0F, 1.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f18, 0.5D).tex(0.75D, 0.0625D).normal(0.0F, 0.0F, 1.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f17, -0.5D).tex(0.75D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f17, -0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f17, 0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f17, 0.5D).tex(0.75D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f18, 0.5D).tex(0.75D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f18, 0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f18, -0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f18, -0.5D).tex(0.75D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f17, 0.5D).tex(0.751953125D, 0.0D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f18, 0.5D).tex(0.751953125D, 0.0625D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f18, -0.5D).tex(0.751953125D, 0.0625D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f15, (double)f17, -0.5D).tex(0.751953125D, 0.0D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f17, -0.5D).tex(0.751953125D, 0.0D).normal(1.0F, 0.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f18, -0.5D).tex(0.751953125D, 0.0625D).normal(1.0F, 0.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f18, 0.5D).tex(0.751953125D, 0.0625D).normal(1.0F, 0.0F, 0.0F).endVertex();
                bufferbuilder.pos((double)f16, (double)f17, 0.5D).tex(0.751953125D, 0.0D).normal(1.0F, 0.0F, 0.0F).endVertex();
                tessellator.draw();
            }
        }
    }

    private void setLightmap(EntityWallpaper painting, float p_77008_2_, float p_77008_3_)
    {
        int i = MathHelper.floor(painting.posX);
        int j = MathHelper.floor(painting.posY + (double)(p_77008_3_ / 16.0F));
        int k = MathHelper.floor(painting.posZ);
        EnumFacing enumfacing = painting.facingDirection;

        if (enumfacing == EnumFacing.NORTH)
        {
            i = MathHelper.floor(painting.posX + (double)(p_77008_2_ / 16.0F));
        }

        if (enumfacing == EnumFacing.WEST)
        {
            k = MathHelper.floor(painting.posZ - (double)(p_77008_2_ / 16.0F));
        }

        if (enumfacing == EnumFacing.SOUTH)
        {
            i = MathHelper.floor(painting.posX - (double)(p_77008_2_ / 16.0F));
        }

        if (enumfacing == EnumFacing.EAST)
        {
            k = MathHelper.floor(painting.posZ + (double)(p_77008_2_ / 16.0F));
        }

        int l = this.renderManager.world.getCombinedLight(new BlockPos(i, j, k), 0);
        int i1 = l % 65536;
        int j1 = l / 65536;
        OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)i1, (float)j1);
        GlStateManager.color(1.0F, 1.0F, 1.0F);
    }
}
Код:
public class EntityWallpaper extends EntityHanging {


    public EntityWallpaper(World worldIn)
    {
        super(worldIn);

    }

    public EntityWallpaper(World worldIn, BlockPos pos, EnumFacing facing)
    {
        super(worldIn, pos);
        this.updateFacingWithBoundingBox(facing);

    }

@Override
    public void writeEntityToNBT(NBTTagCompound compound)
    {
        super.writeEntityToNBT(compound);
    }
@Override
    public void readEntityFromNBT(NBTTagCompound compound)
    {
        super.readEntityFromNBT(compound);
    }
    public int getWidthPixels()
    {
        return 16;
    }

    public int getHeightPixels()
    {
        return 16;
    }

    @Override
    public boolean attackEntityFrom(DamageSource source, float amount)
    {
        if(this.getEntityWorld().isRemote) this.setDead();
        return true;
    }

    @Override
    public void onBroken(@Nullable Entity brokenEntity)
    {
        return;
    }

    public void playPlaceSound()
    {
        this.playSound(SoundEvents.ENTITY_PAINTING_PLACE, 1.0F, 1.0F);
    }

    /**
     * Sets the location and Yaw/Pitch of an entity in the world
     */
    public void setLocationAndAngles(double x, double y, double z, float yaw, float pitch)
    {
        this.setPosition(x, y, z);
    }

    @SideOnly(Side.CLIENT)
    public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport)
    {
        BlockPos blockpos = this.hangingPosition.add(x - this.posX, y - this.posY, z - this.posZ);
        this.setPosition((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ());
    }
}

Есть один недочет, сущность почему то пропадает после перезахода. Об этом давайте уже обсудим тут.
 
Сверху