Jump to content

Recommended Posts

Posted

Hello everyone,

I have been working on a mod for a year now and am almost complete, however something about entity coding trips me up, I have my final entity, a hanging entity, almost working, however the client side function needed for the rendering of my entity is not being called and I am not sure how to call it, I have tried just simply naming the function in my class which references the vanilla class and even completely putting the client side function in my class all to no avail. Help to solve what I'm doing wrong is greatly appreciated!

 

Here is my entity class:

 

public class PapPapEntity extends EntityPainting implements IEntityAdditionalSpawnData{

  
public PapPapEntity(World world) {
	super(world);
}

public PapPapEntity(World world2, int int1, int int2, int int3, int int4) {
	super(world2, int1, int2, int3, int4);
}

@SideOnly(Side.CLIENT)
public PapPapEntity(World wo, int i, int j, int k, int l, String s){
    super(wo, i, j, k, l);
    
    PapPapEntity.EnumArt[] aenumart = PapPapEntity.EnumArt.values();
    int i1 = aenumart.length;
    
    for (int j1 = 0; j1 < i1; ++j1){
      PapPapEntity.EnumArt enumart = aenumart[j1];
      if (enumart.title.equals(s)){
        this.art = enumart;
        break;
      }
    }
    this.setDirection(l);
}

public void onBroken(Entity entit){
        if (entit instanceof EntityPlayer){
            EntityPlayer entityplayer = (EntityPlayer)entit;

            if (entityplayer.capabilities.isCreativeMode){
                return;
            }
        }

        this.entityDropItem(new ItemStack(TigerItems.PapPap), 0.0F);
    }

@Override
public void writeSpawnData(ByteBuf buffer) {

}

@Override
public void readSpawnData(ByteBuf additionalData) {

}

}

 

 

This is the function in EntityPainting which I am trying to call

 

@SideOnly(Side.CLIENT)
    public EntityPainting(World p_i1601_1_, int p_i1601_2_, int p_i1601_3_, int p_i1601_4_, int p_i1601_5_, String p_i1601_6_)
    {
        this(p_i1601_1_, p_i1601_2_, p_i1601_3_, p_i1601_4_, p_i1601_5_);
        EntityPainting.EnumArt[] aenumart = EntityPainting.EnumArt.values();
        int i1 = aenumart.length;

        for (int j1 = 0; j1 < i1; ++j1)
        {
            EntityPainting.EnumArt enumart = aenumart[j1];

            if (enumart.title.equals(p_i1601_6_))
            {
                this.art = enumart;
                break;
            }
        }

        this.setDirection(p_i1601_5_);
    }

 

 

Thanks! :)

I'm a novice programmer but I learn from others showing me how to code correctly so thank you for any help you give me! :)

Posted

While I don't know the answer off-hand, I do know that there have been many threads about this exact topic here that you could probably find the answer in if you searched.

 

There is some kind of trick to getting a painting to render correctly that isn't really obvious as it is not handled the same way that most other rendering is in Minecraft.

 

EDIT: Here is a thread with a potential solution.

Posted

Thanks for the reply! But I have spent days combing all the painting rendering related posts and tried at least a hundred things over the past year to still be unable to get it to render. I always try to figure things out myself and hate asking for help but this one problem is too much for me alone. But I do hope whoever knows the solution can help me

 

EDIT: I definitely have spent a lot of time observing that post you suggested, it helped me fix a lot of other problems, but for client side functions I believe changed a bit from 1.7.10 to 1.8, but I will keep looking at what he did

I'm a novice programmer but I learn from others showing me how to code correctly so thank you for any help you give me! :)

  • 3 weeks later...
Posted

So I kind of have no clue what I did but the paintings SPAWN now and WITH my texture (kind of how programming works isn't it?), there's just one slight issue left, which I know gottsch has made a post for a while ago however was never solved, but maybe someone can help me figure this out. Whenever I spawn the painting they stay for about 5 seconds before it shift 1/2 block upwards, to just test if this still occurs when the mod is built and in a non-test environment they acted slightly different but still wrong. Small paintings (1x1 and 2x1) still move up a half block (and sometimes jump a full block up but back down to a half block immediately afterward), however larger paintings (i.e. 2x2) just jump up one block and stay stable there. I am not too sure how to debug why this jump occurs. All help is appreciated and kind thanks to all those who helped me get this far!

 

Coding

 

 

Rendering Class:

@SideOnly(Side.CLIENT)
public class PapPapRender extends Render{

@Override
protected ResourceLocation getEntityTexture(Entity textur) {
	return new ResourceLocation(RefStrings.MODID + ":textures/painting/egypt.png");
}

public void doRender(PapPapEntity ent, double doub1, double doub2, double doub3, float flo1, float flo2){
	GL11.glPushMatrix();
	GL11.glTranslated(doub1, doub2, doub3);
	GL11.glRotatef(flo1, 0.0F, 1.0F, 0.0F);
	GL11.glEnable(GL12.GL_RESCALE_NORMAL);
	this.bindEntityTexture(ent);
	PapPapEntity.EnumArt enumart = ent.art;
	float f2 = 0.0625F;
	GL11.glScalef(f2, f2, f2);
	this.funca(ent, enumart.sizeX, enumart.sizeY, enumart.offsetX, enumart.offsetY);
	GL11.glDisable(GL12.GL_RESCALE_NORMAL);
	GL11.glPopMatrix();
}

private void funca(PapPapEntity entit, int sizeX, int sizeY, int offX, int offY){
	float f = (float)(-sizeX) / 2.0F;
	float f1 = (float)(-sizeY) / 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 i1 = 0; i1 < sizeX / 16; ++i1){
		for (int j1 = 0; j1 < sizeY / 16; ++j1){
			float f15 = f + (float)((i1 + 1) * 16);
			float f16 = f + (float)(i1 * 16);
			float f17 = f1 + (float)((j1 + 1) * 16);
			float f18 = f1 + (float)(j1 * 16);
			this.funb(entit, (f15 + f16) / 2.0F, (f17 + f18) / 2.0F);
			float f19 = (float)(offX + sizeX - i1 * 16) / 256.0F;
			float f20 = (float)(offX + sizeX - (i1 + 1) * 16) / 256.0F;
			float f21 = (float)(offY + sizeY - j1 * 16) / 256.0F;
			float f22 = (float)(offY + sizeY - (j1 + 1) * 16) / 256.0F;
			Tessellator tessellator = Tessellator.instance;
			tessellator.startDrawingQuads();
			tessellator.setNormal(0.0F, 0.0F, -1.0F);
			tessellator.addVertexWithUV((double)f15, (double)f18, (double)(-f2), (double)f20, (double)f21);
			tessellator.addVertexWithUV((double)f16, (double)f18, (double)(-f2), (double)f19, (double)f21);
			tessellator.addVertexWithUV((double)f16, (double)f17, (double)(-f2), (double)f19, (double)f22);
			tessellator.addVertexWithUV((double)f15, (double)f17, (double)(-f2), (double)f20, (double)f22);
			tessellator.setNormal(0.0F, 0.0F, 1.0F);
			tessellator.addVertexWithUV((double)f15, (double)f17, (double)f2, (double)f3, (double)f5);
			tessellator.addVertexWithUV((double)f16, (double)f17, (double)f2, (double)f4, (double)f5);
			tessellator.addVertexWithUV((double)f16, (double)f18, (double)f2, (double)f4, (double)f6);
			tessellator.addVertexWithUV((double)f15, (double)f18, (double)f2, (double)f3, (double)f6);
			tessellator.setNormal(0.0F, 1.0F, 0.0F);
			tessellator.addVertexWithUV((double)f15, (double)f17, (double)(-f2), (double)f7, (double)f9);
			tessellator.addVertexWithUV((double)f16, (double)f17, (double)(-f2), (double)f8, (double)f9);
			tessellator.addVertexWithUV((double)f16, (double)f17, (double)f2, (double)f8, (double)f10);
			tessellator.addVertexWithUV((double)f15, (double)f17, (double)f2, (double)f7, (double)f10);
			tessellator.setNormal(0.0F, -1.0F, 0.0F);
			tessellator.addVertexWithUV((double)f15, (double)f18, (double)f2, (double)f7, (double)f9);
			tessellator.addVertexWithUV((double)f16, (double)f18, (double)f2, (double)f8, (double)f9);
			tessellator.addVertexWithUV((double)f16, (double)f18, (double)(-f2), (double)f8, (double)f10);
			tessellator.addVertexWithUV((double)f15, (double)f18, (double)(-f2), (double)f7, (double)f10);
			tessellator.setNormal(-1.0F, 0.0F, 0.0F);
			tessellator.addVertexWithUV((double)f15, (double)f17, (double)f2, (double)f12, (double)f13);
			tessellator.addVertexWithUV((double)f15, (double)f18, (double)f2, (double)f12, (double)f14);
			tessellator.addVertexWithUV((double)f15, (double)f18, (double)(-f2), (double)f11, (double)f14);
			tessellator.addVertexWithUV((double)f15, (double)f17, (double)(-f2), (double)f11, (double)f13);
			tessellator.setNormal(1.0F, 0.0F, 0.0F);
			tessellator.addVertexWithUV((double)f16, (double)f17, (double)(-f2), (double)f12, (double)f13);
			tessellator.addVertexWithUV((double)f16, (double)f18, (double)(-f2), (double)f12, (double)f14);
			tessellator.addVertexWithUV((double)f16, (double)f18, (double)f2, (double)f11, (double)f14);
			tessellator.addVertexWithUV((double)f16, (double)f17, (double)f2, (double)f11, (double)f13);
			tessellator.draw();
		}
	}
}

private void funb(PapPapEntity entit2, float floa, float flob){
	int i = MathHelper.floor_double(entit2.posX);
	int j = MathHelper.floor_double(entit2.posY + (double)(flob / 16.0F));
	int k = MathHelper.floor_double(entit2.posZ);

	if (entit2.hangingDirection == 2){
		i = MathHelper.floor_double(entit2.posX + (double)(floa / 16.0F));
	}

	if (entit2.hangingDirection == 1){
		k = MathHelper.floor_double(entit2.posZ - (double)(floa / 16.0F));
	}

	if (entit2.hangingDirection == 0){
		i = MathHelper.floor_double(entit2.posX - (double)(floa / 16.0F));
	}

	if (entit2.hangingDirection == 3){
		k = MathHelper.floor_double(entit2.posZ + (double)(floa / 16.0F));
	}

	int l = this.renderManager.worldObj.getLightBrightnessForSkyBlocks(i, j, k, 0);
	int i1 = l % 65536;
	int j1 = l / 65536;
	OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)i1, (float)j1);
	GL11.glColor3f(1.0F, 1.0F, 1.0F);
}
public void doRender(Entity ent, double doub1, double doub2, double doub3, float flo1, float flo2){
	this.doRender((PapPapEntity)ent, doub1, doub2, doub3, flo1, flo2);
}
}

 

Entity Class (I know the enumart function's variables are still vanilla gibberish code but they only occur once in the function and I'm kind of scared to change anything else :/ ):

public class PapPapEntity extends EntityHanging implements IEntityAdditionalSpawnData{

public PapPapEntity.EnumArt art;

public PapPapEntity(World world) {
	super(world);
}

public PapPapEntity(World world2, int int1, int int2, int int3, int int4)
    {
        super(world2, int1, int2, int3, int4);
        ArrayList arraylist = new ArrayList();
        PapPapEntity.EnumArt[] aenumart = PapPapEntity.EnumArt.values();
        int i1 = aenumart.length;

        for (int j1 = 0; j1 < i1; ++j1)
        {
            PapPapEntity.EnumArt enumart = aenumart[j1];
            this.art = enumart;
            this.setDirection(int4);

            if (this.onValidSurface())
            {
                arraylist.add(enumart);
            }
        }

        if (!arraylist.isEmpty())
        {
            this.art = (PapPapEntity.EnumArt)arraylist.get(this.rand.nextInt(arraylist.size()));
        }

        this.setDirection(int4);
    }

@SideOnly(Side.CLIENT)
public PapPapEntity(World wo, int i, int j, int k, int l, String s){
    super(wo, i, j, k, l);
    
    PapPapEntity.EnumArt[] aenumart = PapPapEntity.EnumArt.values();
    int i1 = aenumart.length;
    
    for (int j1 = 0; j1 < i1; ++j1){
      PapPapEntity.EnumArt enumart = aenumart[j1];
      if (enumart.title.equals(s)){
        this.art = enumart;
        break;
      }
    }
    this.setDirection(l);
}

public void onBroken(Entity entit){
        if (entit instanceof EntityPlayer){
            EntityPlayer entityplayer = (EntityPlayer)entit;

            if (entityplayer.capabilities.isCreativeMode){
                return;
            }
        }

        this.entityDropItem(new ItemStack(TigerItems.PapPap), 0.0F);
    }

public void writeEntityToNBT(NBTTagCompound val1)
    {
        val1.setString("Motive", this.art.title);
        super.writeEntityToNBT(val1);
    }

public void readEntityFromNBT(NBTTagCompound val2)
    {
        String s = val2.getString("Motive");
        PapPapEntity.EnumArt[] aenumart = PapPapEntity.EnumArt.values();
        int i = aenumart.length;

        for (int j = 0; j < i; ++j)
        {
            PapPapEntity.EnumArt enumart = aenumart[j];

            if (enumart.title.equals(s))
            {
                this.art = enumart;
            }
        }

        if (this.art == null)
        {
            this.art = PapPapEntity.EnumArt.Aztec;
        }

        super.readEntityFromNBT(val2);
    }

public int getWidthPixels()
    {
        return this.art.sizeX;
    }

    public int getHeightPixels()
    {
        return this.art.sizeY;
    }
    
    public static enum EnumArt
    {
        Kebab("Kebab", 16, 16, 0, 0),
        Aztec("Aztec", 16, 16, 16, 0),
        Alban("Alban", 16, 16, 32, 0),
        Aztec2("Aztec2", 16, 16, 48, 0),
        Bomb("Bomb", 16, 16, 64, 0),
        Plant("Plant", 16, 16, 80, 0),
        Wasteland("Wasteland", 16, 16, 96, 0),
        Pool("Pool", 32, 16, 0, 32),
        Courbet("Courbet", 32, 16, 32, 32),
        Sea("Sea", 32, 16, 64, 32),
        Sunset("Sunset", 32, 16, 96, 32),
        Creebet("Creebet", 32, 16, 128, 32),
        Wanderer("Wanderer", 16, 32, 0, 64),
        Graham("Graham", 16, 32, 16, 64),
        Match("Match", 32, 32, 0, 128),
        Bust("Bust", 32, 32, 32, 128),
        Stage("Stage", 32, 32, 64, 128),
        Void("Void", 32, 32, 96, 128),
        SkullAndRoses("SkullAndRoses", 32, 32, 128, 128),
        Wither("Wither", 32, 32, 160, 128),
        Fighters("Fighters", 64, 32, 0, 96),
        Pointer("Pointer", 64, 64, 0, 192),
        Pigscene("Pigscene", 64, 64, 64, 192),
        BurningSkull("BurningSkull", 64, 64, 128, 192),
        Skeleton("Skeleton", 64, 48, 192, 64),
        DonkeyKong("DonkeyKong", 64, 48, 192, 112);
        public static final int maxArtTitleLength = "SkullAndRoses".length();
        public final String title;
        public final int sizeX;
        public final int sizeY;
        public final int offsetX;
        public final int offsetY;
        
        private EnumArt(String p_i1598_3_, int p_i1598_4_, int p_i1598_5_, int p_i1598_6_, int p_i1598_7_)
        {
            this.title = p_i1598_3_;
            this.sizeX = p_i1598_4_;
            this.sizeY = p_i1598_5_;
            this.offsetX = p_i1598_6_;
            this.offsetY = p_i1598_7_;
        }
    }

public void writeSpawnData(ByteBuf buffer) {
	buffer.writeInt(this.art.ordinal());
        buffer.writeInt(this.chunkCoordX);       
        buffer.writeInt(this.chunkCoordY);       
        buffer.writeInt(this.chunkCoordZ);       
}

public void readSpawnData(ByteBuf buffer) {
	PapPapEntity.EnumArt[] aenumart = PapPapEntity.EnumArt.values();
	this.art = aenumart[buffer.readInt()];
        this.chunkCoordX = buffer.readInt();
        this.chunkCoordY = buffer.readInt();
        this.chunkCoordZ = buffer.readInt();
}


}

 

Item Class:

public class PapPapHanging extends Item{

private final Class hangpap;
public PapPapHanging(Class clas1) {
	super();
	this.hangpap = clas1;
}

public boolean onItemUse(ItemStack stak, EntityPlayer entplay, World world1, int int1, int int2, int int3, int int4, float flt1, float flt2, float flt3){
	if (int4 == 0){
		return false;
	}
	else if (int4 == 1){
		return false;
	}
	else{
		int i1 = Direction.facingToDirection[int4];
		EntityHanging entitypap = this.createPapPapEntity(world1, int1, int2, int3, i1);

			if (!entplay.canPlayerEdit(int1, int2, int3, int4, stak)){
				return false;
			}
			else{
				if (entitypap != null && entitypap.onValidSurface()){
					if (!world1.isRemote){
						world1.spawnEntityInWorld(entitypap);
					}

					--stak.stackSize;
				}

				return true;
			}
	}
}

private EntityHanging createPapPapEntity(World world2, int int5, int int6, int int7, int int8){
		return (EntityHanging) new PapPapEntity(world2, int5, int6, int7, int8);
}

}

 

Registration:

EntityRegistry.registerGlobalEntityID(PapPapEntity.class, "PapPapEntity", EntityRegistry.findGlobalUniqueEntityId());
    EntityRegistry.registerModEntity(PapPapEntity.class, "PapPapEntity", 113, MainRegistry.modInstance, 64, 1, true);

 

 

 

I hope this also helps anyone else out there struggling to get a custom painting to work in 1.7.10

I'm a novice programmer but I learn from others showing me how to code correctly so thank you for any help you give me! :)

Posted

So after messing around with the code this morning I finally solved the issue, firstly I @Override the readSpawnData and writeSpawnData functions in my entity class which didn't directly solve the issue however did appear to smooth-en the rendering process. However while combing through the forums again I found a post by diesieben07 and changed my registering function to EntityRegistry.registerModEntity(PapPapEntity.class, "PapPapEntity", 113, MainRegistry.modInstance, 128, Integer.MAX_VALUE, false); and wall-la it works wonderfully, thank you very much diesieben07. And thank you kindly jeffryfisher, jabelar, Izzy Axel, and Abastro for helping me progress to this point in my older posts on older issues with my custom painting.

 

Try using the registering parameters that vanilla uses for Paintings, they work good for my posters:

EntityRegistry.registerModEntity(EntityPoster.class, "poster", 0, this, 160, Integer.MAX_VALUE, false);

 

After a year (I started this mod on April 29, 2015) I can finally clean it up and get this puppy out there, but thank you all for the help, I definitely have a much more hefty knowledge of entity coding now.  :D

I'm a novice programmer but I learn from others showing me how to code correctly so thank you for any help you give me! :)

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.