Jump to content

Rendering help


Stormageddon

Recommended Posts

Okay so I have a new throwable weapon that I created (item, entity, and render classes as well) but I don't know how to make it render in the Minecraft world so that after I throw it I can see it fly through the air.  I've included my code, although most of it is basically the same as the snowball code; I just changed a few words/lines so that it would all work together for the spear instead of a snowball.

 

ItemSpear.java

package agathalands.item;

import net.minecraft.item.EnumToolMaterial;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import agathalands.entity.projectile.EntitySpear;
import net.minecraft.world.World;

public class ItemSpear extends Item {

public ItemSpear(int id) {
	super(id);
	this.maxStackSize = 8;
	this.setCreativeTab(CreativeTabs.tabCombat);
	this.setUnlocalizedName("itemSpear");
	this.setFull3D();
	this.setTextureName("agathalands:item_spear");
}

/**
     * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
     */
    public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
    {
        if (!par3EntityPlayer.capabilities.isCreativeMode)
        {
            --par1ItemStack.stackSize;
        }

        par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));

        if (!par2World.isRemote)
        {
            par2World.spawnEntityInWorld(new EntitySpear(par2World, par3EntityPlayer));
        }

        return par1ItemStack;
    }

}

 

EntitySpear.java

package agathalands.entity.projectile;

import java.util.Map;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;

public class EntitySpear extends EntityThrowable {

public EntitySpear(World par1World) {
	super(par1World);
}

public EntitySpear(World par1World, EntityLivingBase par2EntityLivingBase) {
	super(par1World, par2EntityLivingBase);
}

public EntitySpear(World par1World, double par2, double par4, double par6) {
	super(par1World, par2, par4, par6);
}

@Override
protected void onImpact(MovingObjectPosition movingobjectposition) {

	if (movingobjectposition.entityHit != null)
        {
            byte b0 = 6;

            movingobjectposition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), (float)b0);
        }

        for (int i = 0; i < 8; ++i)
        {
            this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
        }

        if (!this.worldObj.isRemote)
        {
            this.setDead();
        }
}

}

 

RenderSpear.java

package agathalands.client.renderer.entity;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.Entity;
import net.minecraft.entity.projectile.EntityPotion;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPotion;
import net.minecraft.potion.PotionHelper;
import net.minecraft.util.Icon;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

@SideOnly(Side.CLIENT)
public class RenderSpear extends Render
{
    private Item field_94151_a;
    private int field_94150_f;

    public RenderSpear(Item par1Item, int par2)
    {
        this.field_94151_a = par1Item;
        this.field_94150_f = par2;
    }

    public RenderSpear(Item par1Item)
    {
        this(par1Item, 0);
    }

    /**
     * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
     * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
     * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
     * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
     */
    public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
    {
        Icon icon = this.field_94151_a.getIconFromDamage(this.field_94150_f);

        if (icon != null)
        {
            GL11.glPushMatrix();
            GL11.glTranslatef((float)par2, (float)par4, (float)par6);
            GL11.glEnable(GL12.GL_RESCALE_NORMAL);
            GL11.glScalef(0.5F, 0.5F, 0.5F);
            this.bindEntityTexture(par1Entity);
            Tessellator tessellator = Tessellator.instance;

            if (icon == ItemPotion.func_94589_d("bottle_splash"))
            {
                int i = PotionHelper.func_77915_a(((EntityPotion)par1Entity).getPotionDamage(), false);
                float f2 = (float)(i >> 16 & 255) / 255.0F;
                float f3 = (float)(i >> 8 & 255) / 255.0F;
                float f4 = (float)(i & 255) / 255.0F;
                GL11.glColor3f(f2, f3, f4);
                GL11.glPushMatrix();
                this.func_77026_a(tessellator, ItemPotion.func_94589_d("overlay"));
                GL11.glPopMatrix();
                GL11.glColor3f(1.0F, 1.0F, 1.0F);
            }

            this.func_77026_a(tessellator, icon);
            GL11.glDisable(GL12.GL_RESCALE_NORMAL);
            GL11.glPopMatrix();
        }
    }

    /**
     * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
     */
    protected ResourceLocation getEntityTexture(Entity par1Entity)
    {
        return TextureMap.locationItemsTexture;
    }

    private void func_77026_a(Tessellator par1Tessellator, Icon par2Icon)
    {
        float f = par2Icon.getMinU();
        float f1 = par2Icon.getMaxU();
        float f2 = par2Icon.getMinV();
        float f3 = par2Icon.getMaxV();
        float f4 = 1.0F;
        float f5 = 0.5F;
        float f6 = 0.25F;
        GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
        GL11.glRotatef(-this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
        par1Tessellator.startDrawingQuads();
        par1Tessellator.setNormal(0.0F, 1.0F, 0.0F);
        par1Tessellator.addVertexWithUV((double)(0.0F - f5), (double)(0.0F - f6), 0.0D, (double)f, (double)f3);
        par1Tessellator.addVertexWithUV((double)(f4 - f5), (double)(0.0F - f6), 0.0D, (double)f1, (double)f3);
        par1Tessellator.addVertexWithUV((double)(f4 - f5), (double)(f4 - f6), 0.0D, (double)f1, (double)f2);
        par1Tessellator.addVertexWithUV((double)(0.0F - f5), (double)(f4 - f6), 0.0D, (double)f, (double)f2);
        par1Tessellator.draw();
    }
}

Link to comment
Share on other sites

You need to register the renderer with the Render....(RenderManager?  RenderEngine?  One sec...oh, right the RenderingRegistry)

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

And...how do I do that? I looked in the RenderingRegistry class and the only method I see that seems like it might be right is public static void registerEntityRenderingHandler(Class <? extends Entity > entityClass, Render renderer) but I keep getting an error.

 

RenderingRegistry.registerEntityRenderingHandler(NameOfYourEntityClass.class, new NameOfYourRenderer());

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Even if it doesn't have a texture, you should be able to see it with the MISSING TEXTURE texture. :\

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Hm...then I don't know what's wrong. ._. The item itself has a texture, and it does everything it's supposed to do (I can throw it and it causes damage), I just can't see it fly through the air. I can't see anything fly through the air.  That method is supposed to go in my ClientProxy class right?

 

From what you say, it almost seems as though when it gets thrown, it acquires a completely transparent texture.

Link to comment
Share on other sites

Hi

 

Have you tried putting a breakpoint or System.out.println("doRender"); in RenderSpear.doRender, to see if it's actually being called?

 

-TGG

 

So I just tried that...and apparently it's NOT being called.  Although, I'm not sure where to call it, or HOW to call it (the method signature requires 3 doubles and 2 floats and I don't know what those values are supposed to be.

Link to comment
Share on other sites

Hi

 

If it's not being called, that means you almost certainly haven't registered the renderer properly.

 

Show us the part of your code where you do this?  :

 

RenderingRegistry.registerEntityRenderingHandler(NameOfYourEntityClass.class, new NameOfYourRenderer());

 

Once you have registered your handler, the vanilla code will call it whenever it needs to draw your Entity.  You don't call it yourself (that's what "handler" means).

 

-TGG

 

PS    /**

    * Renders the specified entity with the passed in position, yaw, and partialTickTime. Args: entity, x, y, z, yaw,

    * partialTickTime

    */

    public void doRender(Entity entityToRender, double x, double y, double z, float yaw, float partialTickTime)

 

 

Link to comment
Share on other sites

package agathalands.client;

import cpw.mods.fml.client.registry.RenderingRegistry;
import agathalands.AgathaLands;
import agathalands.CommonProxy;
import agathalands.client.renderer.entity.RenderSpear;
import agathalands.entity.projectile.EntitySpear;

public class ClientProxy extends CommonProxy
{
    @Override
    public void registerRenderers()
    {
        //This is for rendering entities and so forth later on
    	
    	RenderingRegistry.registerEntityRenderingHandler(EntitySpear.class, new RenderSpear(AgathaLands.itemSpear));
    }
    
}

 

The constructor for my RenderSpear method requires an item so that's why I pass that in.  I don't get any errors from it, but at the same time, the constructor doesn't call the doRender method.  (I'm not sure if it's supposed to)

Link to comment
Share on other sites

Hi

 

Hmmm I don't see anything obviously wrong with that.

 

I've always registered my handlers in

  @EventHandler
  public void load(FMLInitializationEvent event) {

}

so it might be worth trying that. (Have no idea about ClientProxy.registerRenderers.  Try a breakpoint there?).

 

It's fine to have an argument for your RenderSpear constructor (see RenderManager eg

        this.entityRenderMap.put(EntityPig.class,

                                                new RenderPig(new ModelPig(), new ModelPig(0.5F), 0.7F)  );

 

And no, the constructor doesn't call doRender.

 

That happens in RenderManager.renderEntityWithPosYaw

    public void renderEntityWithPosYaw(Entity entityToRender, double x, double y, double z, float yaw, float partialTickTime)
    {
        Render render = null;

        try
        {
            render = this.getEntityRenderObject(entityToRender);     // retrieves your custom renderer here

            if (render != null && this.renderEngine != null)
            {
// snip
                try
                {
                    render.doRender(entityToRender, x, y, z, yaw, partialTickTime);
                }
                catch (Throwable throwable1)
                {
                    throw new ReportedException(CrashReport.makeCrashReport(throwable1, "Rendering entity in world"));
                }

 

If you're feeling up to it, you could put a breakpoint on the getEntityRenderObject above, then trace into it and examine the entityRenderMap to see if your entity has been properly registered in it or not.

Other useful spots for breakpoints:

(1) RenderingRegistry.registerEntityRenderingHandler

and

(2) RenderingRegistry.loadEntityRenderers    (copies your registered handlers into the vanilla rendering map.)

 

Perhaps your code never makes it to (1).  Or alternatively, it gets to (2) before (1) because your handler is registering too late

 

-TGG

Link to comment
Share on other sites

Hi

 

Hmmm I don't see anything obviously wrong with that.

 

I've always registered my handlers in

  @EventHandler
  public void load(FMLInitializationEvent event) {

}

so it might be worth trying that. (Have no idea about ClientProxy.registerRenderers.  Try a breakpoint there?).

 

It's fine to have an argument for your RenderSpear constructor (see RenderManager eg

        this.entityRenderMap.put(EntityPig.class,

                                                new RenderPig(new ModelPig(), new ModelPig(0.5F), 0.7F)  );

 

And no, the constructor doesn't call doRender.

 

That happens in RenderManager.renderEntityWithPosYaw

    public void renderEntityWithPosYaw(Entity entityToRender, double x, double y, double z, float yaw, float partialTickTime)
    {
        Render render = null;

        try
        {
            render = this.getEntityRenderObject(entityToRender);     // retrieves your custom renderer here

            if (render != null && this.renderEngine != null)
            {
// snip
                try
                {
                    render.doRender(entityToRender, x, y, z, yaw, partialTickTime);
                }
                catch (Throwable throwable1)
                {
                    throw new ReportedException(CrashReport.makeCrashReport(throwable1, "Rendering entity in world"));
                }

 

If you're feeling up to it, you could put a breakpoint on the getEntityRenderObject above, then trace into it and examine the entityRenderMap to see if your entity has been properly registered in it or not.

Other useful spots for breakpoints:

(1) RenderingRegistry.registerEntityRenderingHandler

and

(2) RenderingRegistry.loadEntityRenderers    (copies your registered handlers into the vanilla rendering map.)

 

Perhaps your code never makes it to (1).  Or alternatively, it gets to (2) before (1) because your handler is registering too late

 

-TGG

 

My code registers the renderer inside of the registerRenderers method in ClientProxy, and then calls that method inside the load method of the main mod class; so it does it the same way you do, just takes an extra step.  Also...I have no idea how to implement a breakpoint or "trace into it."

 

Did you register the spear entity ?

EntityRegistry.registerModEntity(EntitySpear.class, ...);

 

The entity itself is registered (otherwise it wouldn't be able to hit and cause damage to mobs), I just can't see it. Unless you meant something else by registering it?

 

EDIT: After a little testing, I've figured out that my problem is either in my RenderSpear class or in my use of the registerEntityRenderingHandler method.  The method itself is certainly called, it just doesn't seem to be doing what it's supposed to do.

Link to comment
Share on other sites

Hi

 

Hmmm I don't see anything obviously wrong with that.

 

I've always registered my handlers in

  @EventHandler
  public void load(FMLInitializationEvent event) {

}

 

In which case, your mod is not SMP compatible. :)

 

You'll get classNotFound errors when you install it into a server. :D

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

@Draco

Really?  I haven't tested my mod on a server build yet, guess I should try that before I release it..!  Thanks for the heads up! :-)

 

@Storm

Dude, breakpoints and watchpoints are awesome, you absolutely have to learn how to use them, you'll wonder how you even managed without them

try

http://www.vogella.com/articles/EclipseDebugging/article.html

 

In the meantime, you could use System.out.println("I got here"); to see what the vanilla code is doing when it tries to render your Entity:

 

eg

 

RenderManager.renderEntityWithPosYaw
    public void renderEntityWithPosYaw(Entity entityToRender, double x, double y, double z, float yaw, float partialTickTime)
    {
System.out.println("RenderManager.renderEntityWithPosYaw");
        Render render = null;

        try
        {
            render = this.getEntityRenderObject(entityToRender);     // retrieves your custom renderer here

            if (render != null && this.renderEngine != null)
            {
// snip
                try
                {
System.out.println("render.doRender");
                    render.doRender(entityToRender, x, y, z, yaw, partialTickTime);
                }

 

Based on what you've said so far, it sounds like the vanilla code is not properly mapping your EntitySpear to RenderSpear, but I can't tell why.

 

Oh, and I'd suggest you add @Override just before your RenderSpear.doRender, just in case there is some subtle mistake there (doesn't look like it, but good practice anyway...)

 

-TGG

Link to comment
Share on other sites

@Draco

Really?  I haven't tested my mod on a server build yet, guess I should try that before I release it..!  Thanks for the heads up! :-)

 

Server code does not have any class found in net.minecraft.client.*

 

Which includes all rendering classes.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Yeah so I definitely don't know what's wrong with it. >.< It's definitely calling my registerEntityRenderingHandler method, and that method is definately calling the constructor in my RenderSpear class...but the doRender method is never being called, and I can't figure out why. :/ Should I try to call the method myself? And if so, where/how should I get the three doubles and the two floats that I need in order to call it? And where should I call it at?

Link to comment
Share on other sites

Hi

 

Sorry dude, I'm at a loss now.

If I were running this on my machine, I would put a breakpoint here in RenderManager.renderEntityWithPosYaw:

 

      render = this.getEntityRenderObject(entityToRender);    // retrieves your custom renderer here

 

then trace into getEntityRenderObject and see why my entityToRender is not matching any of the classes registered in RenderManager.entityRenderMap.

 

-TGG

 

Link to comment
Share on other sites

Are you calling the registerRenderers() method?

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Link to comment
Share on other sites

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.

Announcements



×
×
  • Create New...

Important Information

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