Jump to content

Recommended Posts

Posted

so as part of my mod i'm adding a chicken that is 3 times the size of a normal chicken, but the problem is that the hit box is remaining the normal size, and im not sure how to go about changing the size of it.

 

Here is my code:

 

 

ModelGiantChicken:

package mods.mochickens.mobs.models;

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 ModelGiantChicken extends ModelBase
{
  //fields
    ModelRenderer lleg;
    ModelRenderer rleg;
    ModelRenderer body;
    ModelRenderer lwing;
    ModelRenderer rwing;
    ModelRenderer head;
    ModelRenderer bill;
    ModelRenderer chin;
  
  public ModelGiantChicken()
  {
    textureWidth = 256;
    textureHeight = 128;
    
      lleg = new ModelRenderer(this, 85, 0);
      lleg.addBox(0F, 0F, -5F, 9, 15, 9);
      lleg.setRotationPoint(0F, 9F, 3F);
      lleg.setTextureSize(256, 128);
      lleg.mirror = true;
      setRotation(lleg, 0F, 0F, 0F);
      rleg = new ModelRenderer(this, 85, 0);
      rleg.addBox(-9F, 0F, -5F, 9, 15, 9);
      rleg.setRotationPoint(0F, 9F, 3F);
      rleg.setTextureSize(256, 128);
      rleg.mirror = true;
      setRotation(rleg, 0F, 0F, 0F);
      body = new ModelRenderer(this, 0, 30);
      body.addBox(-9F, -9F, -11F, 18, 18, 24);
      body.setRotationPoint(0F, 0F, 0F);
      body.setTextureSize(256, 128);
      body.mirror = true;
      setRotation(body, 0F, 0F, 0F);
      lwing = new ModelRenderer(this, 88, 30);
      lwing.addBox(0F, 0F, -9F, 4, 12, 18);
      lwing.setRotationPoint(9F, -9F, 1F);
      lwing.setTextureSize(256, 128);
      lwing.mirror = true;
      setRotation(lwing, 0F, 0F, 0F);
      rwing = new ModelRenderer(this, 88, 30);
      rwing.addBox(-4F, 0F, -9F, 4, 12, 18);
      rwing.setRotationPoint(-9F, -9F, 1F);
      rwing.setTextureSize(256, 128);
      rwing.mirror = true;
      setRotation(rwing, 0F, 0F, 0F);
      head = new ModelRenderer(this, 0, 0);
      head.addBox(-6F, -12F, -6F, 12, 18, 9);
      head.setRotationPoint(0F, -9F, -11F);
      head.setTextureSize(256, 128);
      head.mirror = true;
      setRotation(head, 0F, 0F, 0F);
      bill = new ModelRenderer(this, 44, 14);
      bill.addBox(-6F, -6F, -12F, 12, 6, 6);
      bill.setRotationPoint(0F, -9F, -11F);
      bill.setTextureSize(256, 128);
      bill.mirror = true;
      setRotation(bill, 0F, 0F, 0F);
      chin = new ModelRenderer(this, 47, 0);
      chin.addBox(-3F, 0F, -10F, 6, 6, 6);
      chin.setRotationPoint(0F, -9F, -10F);
      chin.setTextureSize(256, 128);
      chin.mirror = true;
      setRotation(chin, 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);
    
    if (this.isChild)
    {
        float f6 = 2.0F;
        GL11.glPushMatrix();
        GL11.glTranslatef(0.0F, 5.0F * f5, 2.0F * f5);
        this.head.render(f5);
        this.bill.render(f5);
        this.chin.render(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.rleg.render(f5);
        this.lleg.render(f5);
        this.rwing.render(f5);
        this.lwing.render(f5);
        GL11.glPopMatrix();
    }
    else
    {
    setRotationAngles(f, f1, f2, f3, f4, f5);
    lleg.render(f5);
    rleg.render(f5);
    body.render(f5);
    lwing.render(f5);
    rwing.render(f5);
    head.render(f5);
    bill.render(f5);
    chin.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 f, float f1, float f2, float f3, float f4, float f5)
  {
  this.head.rotateAngleX = f5 / (180F / (float)Math.PI);
      this.head.rotateAngleY = f4 / (180F / (float)Math.PI);
      this.bill.rotateAngleX = this.head.rotateAngleX;
      this.bill.rotateAngleY = this.head.rotateAngleY;
      this.chin.rotateAngleX = this.head.rotateAngleX;
      this.chin.rotateAngleY = this.head.rotateAngleY;
      this.rleg.rotateAngleX = MathHelper.cos(f1 * 0.6662F) * 1.4F * f2;
      this.lleg.rotateAngleX = MathHelper.cos(f1 * 0.6662F + (float)Math.PI) * 1.4F * f2;
      this.rwing.rotateAngleZ = f3;
      this.lwing.rotateAngleZ = -f3;
  }

}

 

RenderGiantChicken Code:

package mods.mochickens.mobs.renders;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import mods.mochickens.mobs.EntityGiantChicken;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.resources.ResourceManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.passive.EntityChicken;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;

@SideOnly(Side.CLIENT)
public class RenderGiantChicken extends RenderLiving
{
private static final ResourceLocation chickenCTextures = new ResourceLocation("mochickens:textures/mobs/giantChicken.png");


    public RenderGiantChicken(ModelBase par1ModelBase, float par2)
    {
        super(par1ModelBase, par2);
    }

    public void renderGiantChicken(EntityGiantChicken par1EntityGiantChicken, double par2, double par4, double par6, float par8, float par9)
    {
        super.doRenderLiving(par1EntityGiantChicken, par2, par4, par6, par8, par9);
    }

    protected float getWingRotation(EntityGiantChicken par1EntityGiantChicken, float par2)
    {
    	float f1 = par1EntityGiantChicken.field_70888_h + (par1EntityGiantChicken.field_70886_e - par1EntityGiantChicken.field_70888_h) * par2;
        float f2 = par1EntityGiantChicken.field_70884_g + (par1EntityGiantChicken.destPos - par1EntityGiantChicken.field_70884_g) * par2;
        return (MathHelper.sin(f1) + 1.0F) * f2;
    }

    /**
     * Defines what float the third param in setRotationAngles of ModelBase is
     */
    protected float handleRotationFloat(EntityLivingBase par1EntityLivingBase, float par2)
    {
    	return this.getWingRotation((EntityGiantChicken)par1EntityLivingBase, par2);
    }

    public void doRenderLiving(EntityLivingBase par1EntityLiving, double par2, double par4, double par6, float par8, float par9)
    {
        this.renderGiantChicken((EntityGiantChicken)par1EntityLiving, par2, par4, par6, par8, par9);
    }

    /**
     * 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)
    {
        this.renderGiantChicken((EntityGiantChicken)par1Entity, par2, par4, par6, par8, par9);
    }

@Override
protected ResourceLocation getEntityTexture(Entity entity) {
	return this.chickenCTextures;

}
}

 

EntityGiantChicken:

package mods.mochickens.mobs;

import java.util.logging.Logger;

import mods.mochickens.misc.ChickAITempt;
import mods.mochickens.misc.ChickTameable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockColored;
import net.minecraft.client.Minecraft;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentThorns;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
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.EntityTameable;
import net.minecraft.entity.passive.EntityWolf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemSeeds;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.pathfinding.PathEntity;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;

public class EntityGiantChicken extends EntityTameable {
public boolean field_70885_d = false;
public float field_70886_e = 0.0F;
public float destPos = 0.0F;
public float field_70884_g;
public float field_70888_h;
public float field_70889_i = 1.0F;
private int checked = this.worldObj.difficultySetting;

/** The time until the next egg is spawned. */
public int timeUntilNextEgg;

public EntityGiantChicken(World par1World) {
	super(par1World);
	this.setSize(0.3F, 0.7F);
	float f = 0.25F;
	this.tasks.addTask(0, new EntityAISwimming(this));
	this.tasks.addTask(2, new EntityAIMate(this, 1.0D));
	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));
	this.timeUntilNextEgg = -1;
	this.setTamed(false);
}

/**
 * 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)
			.setAttribute(4.0D);
	this.getEntityAttribute(SharedMonsterAttributes.movementSpeed)
			.setAttribute(0.25D);
}

@Override
public final void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {
	super.readEntityFromNBT(par1NBTTagCompound);
	String s = par1NBTTagCompound.getString("Owner");

	if (s.length() > 0) {
		this.setTamed(true);
		this.setOwner(s);
	}
}

@Override
public void setTamed(boolean par1) {
	byte b0 = this.dataWatcher.getWatchableObjectByte(16);

	if (par1) {
		this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 | 4)));
		this.worldObj.setEntityState(this, (byte) 7);
		this.tasks.removeTask(new EntityAIAttackOnCollide(this,
				EntityPlayer.class, 1.0D, false));
		this.targetTasks.taskEntries.clear();
		this.tasks.addTask(3, new ChickAITempt(this, 1.0D,
				0, false));
		this.timeUntilNextEgg = this.rand.nextInt(2000) + 6000;
	} else {

		this.tasks.addTask(2, new EntityAIAttackOnCollide(this,
				EntityPlayer.class, 1.0D, false));
		this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(
				this, EntityPlayer.class, 0, true));
		this.dataWatcher.updateObject(16, Byte.valueOf((byte) (b0 & -5)));
	}

	if (this.worldObj.difficultySetting == 0) {
		this.difficultyChange();
	}

}

public boolean attackEntityAsMob(Entity par1Entity) {
	if (!this.isTamed()) {
		EntityPlayer entityplayer = this.worldObj
				.getClosestVulnerablePlayerToEntity(this, 16.0D);
		// f = damage delt 2.0D = 1 heart
		float f = (float) 1.0D;
		int i = 0;

		if (entityplayer instanceof EntityLivingBase) {
			f += EnchantmentHelper.getEnchantmentModifierLiving(this,
					(EntityLivingBase) entityplayer);
			i += EnchantmentHelper.getKnockbackModifier(this,
					(EntityLivingBase) entityplayer);
			entityplayer.addPotionEffect(new PotionEffect(
					Potion.moveSlowdown.id, 200, 1));
		}

		boolean flag = par1Entity.attackEntityFrom(
				DamageSource.causeMobDamage(this), f);

		if (flag) {
			if (i > 0) {
				entityplayer.addVelocity(
						(double) (-MathHelper.sin(this.rotationYaw
								* (float) Math.PI / 180.0F)
								* (float) i * 0.5F),
						0.1D,
						(double) (MathHelper.cos(this.rotationYaw
								* (float) Math.PI / 180.0F)
								* (float) i * 0.5F));
				this.motionX *= 0.6D;
				this.motionZ *= 0.6D;
			}

			int j = EnchantmentHelper.getFireAspectModifier(this);

			if (j > 0) {
				entityplayer.setFire(j * 4);
			}

			if (entityplayer instanceof EntityLivingBase) {
				EnchantmentThorns.func_92096_a(this,
						(EntityLivingBase) entityplayer, this.rand);
			}
		}

		return flag;
	} else {
		return false;
	}
}

/**
 * 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;

	if (this.worldObj.difficultySetting != checked) {
		this.difficultyChange();
		checked = this.worldObj.difficultySetting;
	}

	if (!this.isChild() && !this.worldObj.isRemote
			&& --this.timeUntilNextEgg == 0) {
		this.playSound("mob.chicken.plop", 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);
		this.dropItem(0, 1);
		this.timeUntilNextEgg = this.rand.nextInt(2000) + 6000;
	}
}

private void difficultyChange() {
	if (this.worldObj.difficultySetting == 0) {
		this.setPathToEntity((PathEntity) null);
		this.setAttackTarget((EntityLivingBase) null);
		this.setTarget(null);
		this.tasks.removeTask(new EntityAIAttackOnCollide(this,
				EntityPlayer.class, 1.0D, false));
		this.targetTasks.taskEntries.clear();
	} else {
		String s = this.getOwnerName();

		if (s.length() > 0) {
			this.setTamed(true);
			this.setOwner(s);
		} else {
			this.setTamed(false);
		}
	}
}

/**
 * Called when the mob is falling. Calculates and applies fall damage.
 */
protected void fall(float par1) {
}

/**
 * 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";
}

/**
 * Plays step sound at given x, y, z for the entity
 */
protected void playStepSound(int par1, int par2, int par3, int par4) {
	this.playSound("mob.chicken.step", 0.15F, 1.0F);
}

/**
 * Returns the item ID for the item the mob drops on death.
 */
protected int getDropItemId() {
	return Item.feather.itemID;
}

/**
 * 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 par1, int par2) {
	int j = this.rand.nextInt(3) + this.rand.nextInt(1 + par2);

	for (int k = 0; k < j; ++k) {
		if (this.isTamed()) {
			this.dropItem(0, 1);
		} else {
			this.dropItem(Item.egg.itemID, 1);
		}
	}

	if (this.isBurning()) {
		this.dropItem(Item.chickenCooked.itemID, 1);
	} else {
		this.dropItem(Item.chickenRaw.itemID, 1);
	}
}

/**
 * Called when a player interacts with a mob. e.g. gets milk from a cow,
 * gets into the saddle on a pig.
 */
public boolean interact(EntityPlayer par1EntityPlayer) {
	ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();
	if (!this.isTamed()) {
		if (itemstack != null && itemstack.itemID == 0) {
			if (!par1EntityPlayer.capabilities.isCreativeMode) {
				--itemstack.stackSize;
			}

			if (itemstack.stackSize <= 0) {
				par1EntityPlayer.inventory.setInventorySlotContents(
						par1EntityPlayer.inventory.currentItem,
						(ItemStack) null);
			}

			if (!this.worldObj.isRemote) {
				if (this.rand.nextInt(3) == 0) {
					this.setTamed(true);
					this.setPathToEntity((PathEntity) null);
					this.setAttackTarget((EntityLivingBase) null);
					this.setTarget(null);
					this.setOwner(par1EntityPlayer.getCommandSenderName());
					this.playTameEffect(true);
				} else {
					this.playTameEffect(false);
					this.worldObj.setEntityState(this, (byte) 6);
				}
			}

			return true;
		}
	}

	return super.interact(par1EntityPlayer);
}

/**
 * This function is used when two same-species animals in 'love mode' breed
 * to generate the new baby animal.
 */
public EntityGiantChicken spawnBabyAnimal(EntityAgeable par1EntityAgeable) {
	EntityGiantChicken entitybluechicken = new EntityGiantChicken(
			this.worldObj);
	String s = this.getOwnerName();

	if (s != null && s.trim().length() > 0) {
		entitybluechicken.setOwner(s);
		entitybluechicken.setTamed(true);
	}

	return entitybluechicken;
}

/**
 * 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 par1ItemStack) {
	if (this.isTamed()) {
		return par1ItemStack != null
				&& par1ItemStack.itemID == 0;
	} else {
		return false;
	}
}

public EntityAgeable createChild(EntityAgeable par1EntityAgeable) {
	return this.spawnBabyAnimal(par1EntityAgeable);
}
}

 

 

 

a lot of the code in the entity class is place holder for now. could someone please show me where it sets the size of the hitbox?

Posted

Hi

 

The hit detection for where the user's mouse is pointing is done in

EntityRenderer.getMouseOver

 

                for (int i = 0; i < list.size(); ++i)
                {
                    Entity entity = (Entity)list.get(i);

                    if (entity.canBeCollidedWith())
                    {
                        float f2 = entity.getCollisionBorderSize();
                        AxisAlignedBB axisalignedbb = entity.boundingBox.expand((double)f2, (double)f2, (double)f2);
                        MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32);

 

So if the hitbox is the same for the other code (which I guess it probably is), then it looks like changing entity.boundingBox should do what you want, this is done in the vanilla code by setting Entity.width and Entity.height which is done in Entity.setSize().

 

So in EntityGiantChicken your

this.setSize(0.3F, 0.7F);

should be bigger.

 

Never tried it myself, but looks promising.

 

-TGG

 

Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

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