Jump to content

[1.7.10][SOLVED] Custom Mob Model isn't working?


LazerBeans

Recommended Posts

Hello all,

 

As I have been working on my Ores++ furnace for a while, and getting stuck on the TileEntity, I decided to create a side project to divert myself. It will be another module for my MC++(To Be Renamed) mod, Exploration++. Enough of the back story.

 

I used Techne to create a model for a penguin, and created the texture and ModelPenguin java files. As I am new to mobs, I did a bunch of copy/paste, simply to make my penguin more chicken-like.

 

The penguin spawns naturally, plays the correct sound, and can create a baby, but when it renders, it's just a vertical, white rectangular prism. Neither the model nor textures work.

 

You can look through what I have so far for mob-related code below. What did I do wrong?

 

EDIT: Might as well just Copy/Paste the code here! And not have you go through the hassle of .java files...

 

Main Mod

package com.LazerBeanz.LazerCraft.ArctiCraft;

import ArctiCraftMob.EntityPenguin;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.item.Item;
import net.minecraft.world.biome.BiomeGenBase;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.EntityRegistry;

@Mod(modid = "ArctiCraft Addon", version = "1.7.10-1.0.0")
public class ArctiCraft {

@Instance(value = "ArctiCraftModID")
public static ArctiCraft instance; 

@SidedProxy(clientSide="com.LazerBeanz.LazerCraft.ArctiCraft.client.ClientProxy", serverSide="com.LazerBeanz.LazerCraft.ArctiCraft.CommonProxy")
public static CommonProxy proxy;

public static Item penguinBeak = new BeakPenguin().setUnlocalizedName("penguinbeak").setTextureName("ArctiCraft:beakPenguin");
@EventHandler
public void preInit(FMLPreInitializationEvent event) {

	EntityRegistry.registerGlobalEntityID(EntityPenguin.class, "arcticpenguin", EntityRegistry.findGlobalUniqueEntityId(), 0x000000, 0xFFFFFF);
	EntityRegistry.addSpawn(EntityPenguin.class, 10, 3, 6, EnumCreatureType.creature, BiomeGenBase.icePlains);

}
@EventHandler
public void load(FMLInitializationEvent event) {

}
@EventHandler
public void postInit(FMLPostInitializationEvent event) {

}
}

 

EntityPenguin:

package ArctiCraftMob;

import com.LazerBeanz.LazerCraft.ArctiCraft.ArctiCraft;

import net.minecraft.block.Block;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFishFood;
import net.minecraft.item.ItemSeeds;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;

public class EntityPenguin extends EntityAnimal
{
   

public float field_70886_e;
    public float destPos;
    public float field_70884_g;
    public float field_70888_h;
    public float field_70889_i = 1.0F;
    public boolean field_152118_bv;
    private static final String __OBFID = "CL_00001639";

    public EntityPenguin(World p_i1682_1_)
    {
        super(p_i1682_1_);
        this.setSize(0.3F, 0.7F);
        this.tasks.addTask(0, new EntityAISwimming(this));
        this.tasks.addTask(1, new EntityAIPanic(this, 1.4D));
        this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
        this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Items.wheat_seeds, false));
        this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D));
        this.tasks.addTask(5, new EntityAIWander(this, 1.0D));
        this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
        this.tasks.addTask(7, new EntityAILookIdle(this));
    }

    /**
     * Returns true if the newer Entity AI code should be run
     */
    public boolean isAIEnabled()
    {
        return true;
    }

    protected void applyEntityAttributes()
    {
        super.applyEntityAttributes();
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(4.0D);
        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D);
    }

    /**
     * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
     * use this to react to sunlight and start to burn.
     */
    public void onLivingUpdate()
    {
        super.onLivingUpdate();
        this.field_70888_h = this.field_70886_e;
        this.field_70884_g = this.destPos;
        this.destPos = (float)((double)this.destPos + (double)(this.onGround ? -1 : 4) * 0.3D);

        if (this.destPos < 0.0F)
        {
            this.destPos = 0.0F;
        }

        if (this.destPos > 1.0F)
        {
            this.destPos = 1.0F;
        }

        if (!this.onGround && this.field_70889_i < 1.0F)
        {
            this.field_70889_i = 1.0F;
        }

        this.field_70889_i = (float)((double)this.field_70889_i * 0.9D);

        if (!this.onGround && this.motionY < 0.0D)
        {
            this.motionY *= 0.6D;
        }

        this.field_70886_e += this.field_70889_i * 2.0F;

    }

    

    /**
     * Returns the sound this mob makes while it's alive.
     */
    protected String getLivingSound()
    {
        return "mob.chicken.say";
    }

    /**
     * Returns the sound this mob makes when it is hurt.
     */
    protected String getHurtSound()
    {
        return "mob.chicken.hurt";
    }

    /**
     * Returns the sound this mob makes on death.
     */
    protected String getDeathSound()
    {
        return "mob.chicken.hurt";
    }

    protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_)
    {
        this.playSound("mob.chicken.step", 0.15F, 1.0F);
    }

    protected Item getDropItem()
    {
        return Items.feather;
    }

    /**
     * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param
     * par2 - Level of Looting used to kill this mob.
     */
    protected void dropFewItems(boolean p_70628_1_, int p_70628_2_)
    {
        int j = this.rand.nextInt(3) + this.rand.nextInt(1 + p_70628_2_);

        for (int k = 0; k < j; ++k)
        {
            this.dropItem(Items.feather, 1);
        }

        if (this.isBurning())
        {
            this.dropItem(Items.cooked_chicken, 1);
        }
        else
        {
            this.dropItem(ArctiCraft.penguinBeak, 1);
        }
    }

    public EntityPenguin createChild(EntityAgeable p_90011_1_)
    {
        return new EntityPenguin(this.worldObj);
    }

    /**
     * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on
     * the animal type)
     */
    public boolean isBreedingItem(ItemStack p_70877_1_)
    {
        return p_70877_1_ != null && p_70877_1_.getItem() instanceof ItemFishFood;
    }

  
    /**
     * Get the experience points the entity currently has.
     */
    protected int getExperiencePoints(EntityPlayer p_70693_1_)
    {
        return this.func_152116_bZ() ? 10 : super.getExperiencePoints(p_70693_1_);
    }


    /**
     * Determines if an entity can be despawned, used on idle far away entities
     */
    protected boolean canDespawn()
    {
        return this.func_152116_bZ() && this.riddenByEntity == null;
    }

    

    public boolean func_152116_bZ()
    {
        return this.field_152118_bv;
    }

    public void func_152117_i(boolean p_152117_1_)
    {
        this.field_152118_bv = p_152117_1_;
    }
}

 

ModelPenguin:

 

package ArctiCraftMob;

import org.lwjgl.opengl.GL11;

import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;

public class ModelPenguin extends ModelBase
{
  //fields
    ModelRenderer Leg1;
    ModelRenderer Leg2;
    ModelRenderer Body;
    ModelRenderer Arm1;
    ModelRenderer Arm2;
    ModelRenderer Head; 
    ModelRenderer Foot1;
    ModelRenderer Foot2;
    ModelRenderer Shape1;
  
  public ModelPenguin()
  {
    textureWidth = 64;
    textureHeight = 32;
    
      Leg1 = new ModelRenderer(this, 42, 12);
      Leg1.addBox(0F, 0F, 0F, 1, 7, 1);
      Leg1.setRotationPoint(0F, 17F, -2F);
      Leg1.setTextureSize(64, 32);
      Leg1.mirror = true;
      setRotation(Leg1, 0F, 0F, 0F);
      Leg2 = new ModelRenderer(this, 42, 12);
      Leg2.addBox(0F, 0F, 0F, 1, 7, 1);
      Leg2.setRotationPoint(0F, 17F, 1F);
      Leg2.setTextureSize(64, 32);
      Leg2.mirror = true;
      setRotation(Leg2, 0F, 0F, 0F);
      Body = new ModelRenderer(this, 46, 12);
      Body.addBox(0F, 0F, 0F, 3, 11, 6);
      Body.setRotationPoint(-1F, 6F, -3F);
      Body.setTextureSize(64, 32);
      Body.mirror = true;
      setRotation(Body, 0F, 0F, 0F);
      Arm1 = new ModelRenderer(this, 32, 0);
      Arm1.addBox(0F, 0F, 0F, 3, 11, 1);
      Arm1.setRotationPoint(2F, 6F, -3F);
      Arm1.setTextureSize(64, 32);
      Arm1.mirror = true;
      setRotation(Arm1, 0.2617994F, 3.141593F, 0F);
      Arm2 = new ModelRenderer(this, 32, 0);
      Arm2.addBox(0F, 0F, 0F, 3, 11, 1);
      Arm2.setRotationPoint(-1F, 6F, 3F);
      Arm2.setTextureSize(64, 32);
      Arm2.mirror = true;
      setRotation(Arm2, 0.2617994F, 0F, 0F);
      Head = new ModelRenderer(this, 42, 0);
      Head.addBox(0F, -2F, -3F, 5, 6, 6);
      Head.setTextureOffset(24, 0).addBox(3F, 0F, 0F, 2, 1, 2); //beak
      Head.setRotationPoint(-2F, 2F, 0F);
      Head.setTextureSize(64, 32);
      Head.mirror = true;
      setRotation(Head, 0F, 0F, 0F);
      Foot1 = new ModelRenderer(this, 36, 26);
      Foot1.addBox(0F, 0F, -3F, 2, 0, 3);
      Foot1.setRotationPoint(0F, 24F, 0F);
      Foot1.setTextureSize(64, 32);
      Foot1.mirror = true;
      setRotation(Foot1, 0F, 0F, 0F);
      Foot2 = new ModelRenderer(this, 36, 26);
      Foot2.addBox(0F, 0F, 0F, 2, 0, 3);
      Foot2.setRotationPoint(0F, 24F, 0F);
      Foot2.setTextureSize(64, 32);
      Foot2.mirror = true;
      setRotation(Foot2, 0F, 0F, 0F);
  }
  
  public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)
  {
    super.render(entity, f, f1, f2, f3, f4, f5);
    setRotationAngles(f, f1, f2, f3, f4, f5, entity);
    
    if (this.isChild) {
    	float f6 = 2.0F;
    	GL11.glPushMatrix();
    	GL11.glTranslatef(0.0F, 5.0F * f5, 2.0F * f5);
    	this.Head.renderWithRotation(f5);
    	GL11.glPopMatrix();
    	GL11.glPushMatrix();
    	GL11.glScalef(1.0F / f6,  1.0F / f6, 1.0F / f6);
    	GL11.glTranslatef(0.0F, 24.0F * f5, 0.0F);
    	this.Body.render(f5);
    	this.Leg1.render(f5);
    	this.Leg2.render(f5);
    	this.Arm1.render(f5);
    	this.Arm2.render(f5);
    	this.Foot1.render(f5);
    	this.Foot2.render(f5);
    	GL11.glPopMatrix();
    } else {
    	this.Leg1.render(f5);
        this.Leg2.render(f5);
        this.Body.render(f5);
        this.Arm1.render(f5);
        this.Arm2.render(f5);
        this.Head.renderWithRotation(f5);
        this.Foot1.render(f5);
        this.Foot2.render(f5);
    }
  }
  
  private void setRotation(ModelRenderer model, float x, float y, float z)
  {
    model.rotateAngleX = x;
    model.rotateAngleY = y;
    model.rotateAngleZ = z;
  }
  
  public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7)
  {
float f6 = (180F / (float)Math.PI);
this.Head.rotateAngleX = par5 / (180F / (float)Math.PI);
this.Head.rotateAngleY = par4 / (180F / (float)Math.PI);
this.Body.rotateAngleX = ((float)Math.PI / 2F);
this.Leg1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2;
this.Leg2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2;
this.Arm1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F *par2;
this.Arm2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2;
  }

}

 

RenderPenguin:

 

package ArctiCraftMob;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import ArctiCraftMob.EntityPenguin;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;

@SideOnly(Side.CLIENT)
public class RenderPenguin extends RenderLiving
{
    private static final ResourceLocation penguinTextures = new ResourceLocation("textures/entity/arcticpenguin.png");
    private static final String __OBFID = "CL_00000983";

    public RenderPenguin(ModelBase p_i1252_1_, float p_i1252_2_)
    {
        super(p_i1252_1_, p_i1252_2_);
    }

    /**
     * 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 probability, the class Render is generic
     * (Render<T extends Entity) and this method has signature public void func_76986_a(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(EntityPenguin p_76986_1_, double p_76986_2_, double p_76986_4_, double p_76986_6_, float p_76986_8_, float p_76986_9_)
    {
        super.doRender((EntityLiving)p_76986_1_, p_76986_2_, p_76986_4_, p_76986_6_, p_76986_8_, p_76986_9_);
    }

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

    /**
     * Defines what float the third param in setRotationAngles of ModelBase is
     */
    protected float handleRotationFloat(EntityPenguin p_77044_1_, float p_77044_2_)
    {
        float f1 = p_77044_1_.field_70888_h + (p_77044_1_.field_70886_e - p_77044_1_.field_70888_h) * p_77044_2_;
        float f2 = p_77044_1_.field_70884_g + (p_77044_1_.destPos - p_77044_1_.field_70884_g) * p_77044_2_;
        return (MathHelper.sin(f1) + 1.0F) * f2;
    }

    /**
     * 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 func_76986_a(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(EntityLiving p_76986_1_, double p_76986_2_, double p_76986_4_, double p_76986_6_, float p_76986_8_, float p_76986_9_)
    {
        this.doRender((EntityPenguin)p_76986_1_, p_76986_2_, p_76986_4_, p_76986_6_, p_76986_8_, p_76986_9_);
    }

    /**
     * Defines what float the third param in setRotationAngles of ModelBase is
     */
    protected float handleRotationFloat(EntityLivingBase p_77044_1_, float p_77044_2_)
    {
        return this.handleRotationFloat((EntityPenguin)p_77044_1_, p_77044_2_);
    }

    /**
     * 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 func_76986_a(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(EntityLivingBase p_76986_1_, double p_76986_2_, double p_76986_4_, double p_76986_6_, float p_76986_8_, float p_76986_9_)
    {
        this.doRender((EntityPenguin)p_76986_1_, p_76986_2_, p_76986_4_, p_76986_6_, p_76986_8_, p_76986_9_);
    }

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

    /**
     * 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 func_76986_a(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 p_76986_1_, double p_76986_2_, double p_76986_4_, double p_76986_6_, float p_76986_8_, float p_76986_9_)
    {
        this.doRender((EntityPenguin)p_76986_1_, p_76986_2_, p_76986_4_, p_76986_6_, p_76986_8_, p_76986_9_);
    }
}

 

ClientProxy:

 

package com.LazerBeanz.LazerCraft.ArctiCraft.client;

import net.minecraftforge.client.MinecraftForgeClient;
import ArctiCraftMob.EntityPenguin;
import ArctiCraftMob.ModelPenguin;
import ArctiCraftMob.RenderPenguin;

import com.LazerBeanz.LazerCraft.ArctiCraft.CommonProxy;

import cpw.mods.fml.client.registry.RenderingRegistry;

public class ClientProxy extends CommonProxy {

public void registerRenderers() {
	RenderingRegistry.registerEntityRenderingHandler(EntityPenguin.class, new RenderPenguin(new ModelPenguin(), 0.8F));
}
}

 

Apologies for copy/paste, I'm new to this!

Developer of small, unreleased, basic, and incomplete mods since 2014!

Link to comment
Share on other sites

You don't call registerRenderers.

 

Should the code be :

public class ClientProxy extends CommonProxy {

	RenderingRegistry.registerEntityRenderingHandler(EntityPenguin.class, new RenderPenguin(new ModelPenguin(), 0.8F));
}

 

Instead of :

 

public class ClientProxy extends CommonProxy {

public void registerRenderers() {
	RenderingRegistry.registerEntityRenderingHandler(EntityPenguin.class, new RenderPenguin(new ModelPenguin(), 0.8F));
}
}

Developer of small, unreleased, basic, and incomplete mods since 2014!

Link to comment
Share on other sites

No, you should call the method in the main class. This is basic java.

ClientProxy.registerRenderers();

Put it after you register the entity in preInit().

 

I've done so, but now ClientProxy and ArctiCraft are quarreling over .registerRenderers() being static or not. In ArctiCraft, I get an error that ClientProxy.registerRenderers() is not static, and even if I make it so in ClientProxy, I get an error in there that is telling me to remove the static modifier.

Developer of small, unreleased, basic, and incomplete mods since 2014!

Link to comment
Share on other sites

Never mind. I was referencing registerRenderers() in CommonProxy, which did not have the static modifier. I added all static modifiers, and now errors. Now to test... The model renders. I need to look over the texture and model itself, as neither are as they should be (It should be easy enough).

Developer of small, unreleased, basic, and incomplete mods since 2014!

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.