Posted February 12, 201510 yr So I was wondering how to create a custom child mob, I have a mob that has a child mob, but all it is, is a custom zombie, I tried to make my other mob have a child mob but it doesn't work as far as I know. I don't even know if its creating the child its self in the entity class. Here is the Entity Class: package com.feudalcraft.client.entity.monster; import java.util.Calendar; import java.util.List; import com.feudalcraft.blocksitems.Blocks_and_Items; import com.feudalcraft.client.entity.monster.FeudalSummonAidEvent.FeudalSummonAid; import cpw.mods.fml.common.eventhandler.Event.Result; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.command.IEntitySelector; import net.minecraft.entity.*; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityChicken; import net.minecraft.entity.passive.EntitySquid; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.*; import net.minecraft.world.*; import net.minecraftforge.common.ForgeModContainer; public class EntityShark extends EntityAquaticMob { private float field_146074_bv = -1.0F; private float field_146073_bw; public EntityShark(World world) { super(world); setSize(1.4F, 0.7F); this.renderDistanceWeight = 1.0D; this.isAgressive = true; this.swimRadius = 16.0F; this.moveSpeed = 0.9F; this.attackInterval = 30; this.canJumpOnLand = true; } /** * Applies the entities attributes. */ protected void applyEntityAttributes() { super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5.0D); } protected void entityInit() { super.entityInit(); this.getDataWatcher().addObject(12, Byte.valueOf((byte)0)); } /** * Called to update the entity's position/logic. */ public void onUpdate() { if ((!this.worldObj.isRemote) && (this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL)) { this.setDead(); } super.onUpdate(); } /** * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking * (Animals, Spiders at day, peaceful PigZombies). */ protected Entity findPlayerToAttack() { AxisAlignedBB area = this.boundingBox.expand(16.0D, 16.0D, 16.0D); EntityPlayer player = (EntityPlayer)super.findPlayerToAttack(); if (player != null) { return player; } return this.worldObj.findNearestEntityWithinAABB(EntityAnimal.class, area, this); } /** * Called when the entity is attacked. */ public boolean attackEntityFrom(DamageSource damagesource, float f) { if (!super.attackEntityFrom(damagesource, f)) { return false; } else { int i = MathHelper.floor_double(this.posX); int j = MathHelper.floor_double(this.posY); int k = MathHelper.floor_double(this.posZ); EntityShark entityshark; { entityshark = new EntityShark(this.worldObj); } for (int l = 0; l < 50; ++l) { int i1 = i + MathHelper.getRandomIntegerInRange(this.rand, 7, 40) * MathHelper.getRandomIntegerInRange(this.rand, -1, 1); int j1 = j + MathHelper.getRandomIntegerInRange(this.rand, 7, 40) * MathHelper.getRandomIntegerInRange(this.rand, -1, 1); int k1 = k + MathHelper.getRandomIntegerInRange(this.rand, 7, 40) * MathHelper.getRandomIntegerInRange(this.rand, -1, 1); if (World.doesBlockHaveSolidTopSurface(this.worldObj, i1, j1 - 1, k1) && this.worldObj.getBlockLightValue(i1, j1, k1) < 10) { entityshark.setPosition((double)i1, (double)j1, (double)k1); if (this.worldObj.checkNoEntityCollision(entityshark.boundingBox) && this.worldObj.getCollidingBoundingBoxes(entityshark, entityshark.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(entityshark.boundingBox)) { this.worldObj.spawnEntityInWorld(entityshark); entityshark.onSpawnWithEgg((IEntityLivingData)null); break; } } } return true; } } /** * Returns the sound this mob makes while it's alive. */ protected String getLivingSound() { return null; } /** * Returns the sound this mob makes when it is hurt. */ protected String getHurtSound() { return null; } /** * Returns the sound this mob makes on death. */ protected String getDeathSound() { return null; } /** * Checks to see if the entity can spawn at its current location. */ public boolean getCanSpawnHere() { return (this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL) && (super.getCanSpawnHere()); } /** * If Animal, checks if the age timer is negative */ public boolean isChild() { return this.getDataWatcher().getWatchableObjectByte(12) == 1; } /** * Get the experience points the entity currently has. */ protected int getExperiencePoints(EntityPlayer entity) { if (this.isChild()) { this.experienceValue = (int)((float)this.experienceValue * 2.5F); } return super.getExperiencePoints(entity); } /** * Returns the items that the mob drops upon death. */ protected Item getDropItem() { return this.isBurning() ? Blocks_and_Items.cooked_shark : Blocks_and_Items.raw_shark; } /** * 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 b, int i) { int j = this.rand.nextInt(2) + 1 + this.rand.nextInt(1 + i); for (int k = 0; k < j; ++k) { if (this.isBurning()) { this.dropItem(Blocks_and_Items.cooked_shark, 1); } else { this.dropItem(Blocks_and_Items.raw_shark, 1); } } } /** * Returns the rare items this mob drops */ protected void dropRareDrop(int i) { switch (this.rand.nextInt(2)) { case 0: this.dropItem(Blocks_and_Items.shark_tooth, 1); break; } } /** * Set whether this shark is a child. */ public void setChild(boolean b0) { this.getDataWatcher().updateObject(12, Byte.valueOf((byte)(b0 ? 1 : 0))); this.func_146071_k(b0); } /** * (abstract) Protected helper method to write subclass entity data to NBT. */ public void writeEntityToNBT(NBTTagCompound nbt) { super.writeEntityToNBT(nbt); if (this.isChild()) { nbt.setBoolean("IsBaby", true); } } /** * (abstract) Protected helper method to read subclass entity data from NBT. */ public void readEntityFromNBT(NBTTagCompound nbt) { super.readEntityFromNBT(nbt); if (nbt.getBoolean("IsBaby")) { this.setChild(true); } } /** * Returns what happens when the entity is spawned with a Spawn Egg */ public IEntityLivingData onSpawnWithEgg(IEntityLivingData entity) { Object obj = super.onSpawnWithEgg(entity); float f = this.worldObj.func_147462_b(this.posX, this.posY, this.posZ); if (obj instanceof EntityShark.GroupData) { EntityShark.GroupData groupdata = (EntityShark.GroupData)obj; if (groupdata.field_142048_a) { this.setChild(true); } } double d0 = this.rand.nextDouble() * 1.5D * (double)this.worldObj.func_147462_b(this.posX, this.posY, this.posZ); return (IEntityLivingData)entity; } /** * Handles the update on the entity's health */ @SideOnly(Side.CLIENT) public void handleHealthUpdate(byte b0) { super.handleHealthUpdate(b0); } /** * Determines if an entity can be despawned, used on idle far away entities */ protected boolean canDespawn() { return !this.isChild(); } public void func_146071_k(boolean b) { this.func_146069_a(b ? 0.5F : 1.0F); } /** * Sets the width and height of the entity. Args: width, height */ protected final void setSize(float f0, float f1) { boolean flag = this.field_146074_bv > 0.0F && this.field_146073_bw > 0.0F; this.field_146074_bv = f0; this.field_146073_bw = f1; if (!flag) { this.func_146069_a(1.0F); } } protected final void func_146069_a(float f) { super.setSize(this.field_146074_bv * f, this.field_146073_bw * f); } class GroupData implements IEntityLivingData { public boolean field_142048_a; public boolean field_142046_b; private GroupData(boolean b0, boolean b1) { this.field_142048_a = false; this.field_142046_b = false; this.field_142048_a = b0; this.field_142046_b = b1; } GroupData(boolean b0, boolean b1, Object object) { this(b0, b1); } } } Here is the Entity Class it references: package com.feudalcraft.client.entity.monster; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.passive.EntitySquid; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.passive.IAnimals; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.world.World; public class EntityAquaticMob extends EntityLiving implements IAnimals { private double aquaticTargetX; private double aquaticTargetY; private double aquaticTargetZ; private Entity targetEntity; public boolean isAttacking; protected float swimRadius = 4.0F; protected float swimRadiusHeight = 4.0F; protected boolean isAgressive = false; protected int attackInterval = 60; protected float attackSpeed = 1.2F; protected float moveSpeed = 0.7F; protected boolean canJumpOnLand = false; public EntityAquaticMob(World world) { super(world); this.experienceValue = 3; } protected boolean canTriggerWalking() { return false; } protected boolean isAIEnabled() { return true; } /** * Called when the entity is in the water */ public boolean isInWater() { return this.worldObj.handleMaterialAcceleration(this.boundingBox, Material.water, this); } /** * Called to update the entity's position/logic. */ public void onUpdate() { super.onUpdate(); if (isInWater()) { this.motionY *= 0.2D; } } /** * Updates the entities AI. */ protected void updateAITasks() { super.updateAITasks(); if (isInWater()) { double dx = this.aquaticTargetX - this.posX; double dy = this.aquaticTargetY - this.posY; double dz = this.aquaticTargetZ - this.posZ; double dist = MathHelper.sqrt_double(dx * dx + dy * dy + dz * dz); if ((dist < 1.0D) || (dist > 1000.0D)) { this.aquaticTargetX = (this.posX + (this.rand.nextFloat() * 2.0F - 1.0F) * this.swimRadius); this.aquaticTargetY = (this.posY + (this.rand.nextFloat() * 2.0F - 1.0F) * this.swimRadiusHeight); this.aquaticTargetZ = (this.posZ + (this.rand.nextFloat() * 2.0F - 1.0F) * this.swimRadius); this.isAttacking = false; } if (this.worldObj.getBlock(MathHelper.floor_double(this.aquaticTargetX), MathHelper.floor_double(this.aquaticTargetY + this.height), MathHelper.floor_double(this.aquaticTargetZ)).getMaterial() == Material.water) { this.motionX += dx / dist * 0.05D * this.moveSpeed; this.motionY += dy / dist * 0.1D * this.moveSpeed; this.motionZ += dz / dist * 0.05D * this.moveSpeed; } else { this.aquaticTargetX = this.posX; this.aquaticTargetY = (this.posY + 0.1D); this.aquaticTargetZ = this.posZ; } if (this.isAttacking) { this.motionX *= this.attackSpeed; this.motionY *= this.attackSpeed; this.motionZ *= this.attackSpeed; } if ((this.isAgressive) && (this.rand.nextInt(this.attackInterval) == 0)) { this.targetEntity = findPlayerToAttack(); if ((this.targetEntity != null) && (this.targetEntity.isInWater())) { this.aquaticTargetX = this.targetEntity.posX; this.aquaticTargetY = this.targetEntity.posY; this.aquaticTargetZ = this.targetEntity.posZ; this.isAttacking = true; } } this.renderYawOffset += (-(float)Math.atan2(this.motionX, this.motionZ) * 180.0F / 3.141593F - this.renderYawOffset) * 0.5F; this.rotationYaw = this.renderYawOffset; float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); this.rotationPitch += ((float)Math.atan2(this.motionY, f) * 180.0F / 3.141593F - this.rotationPitch) * 0.5F; } else { this.motionX = 0.0D; this.motionY -= 0.08D; this.motionY *= 0.9800000190734863D; this.motionZ = 0.0D; if ((this.canJumpOnLand) && (this.onGround) && (this.rand.nextInt(30) == 0)) { this.motionY = 0.300000011920929D; this.motionX = (-0.4F + this.rand.nextFloat() * 0.8F); this.motionZ = (-0.4F + this.rand.nextFloat() * 0.8F); } } } /** * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking * (Animals, Spiders at day, peaceful PigZombies). */ protected Entity findPlayerToAttack() { EntityPlayer player = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); return (player != null) && (canEntityBeSeen(player)) ? player : null; } /** * Applies a velocity to each of the entities pushing them away from each other. Args: entity */ public void applyEntityCollision(Entity entity) { super.applyEntityCollision(entity); if ((this.isAgressive) && (this.targetEntity == entity)) attackEntityAsMob(entity); } /** * Called when the entity is attacked. */ public boolean attackEntityAsMob(Entity entity) { float f = (float)getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue(); return entity.attackEntityFrom(DamageSource.causeMobDamage(this), f); } public boolean canBreatheUnderwater() { return true; } public void onEntityUpdate() { int air = getAir(); super.onEntityUpdate(); if ((isEntityAlive()) && (!isInWater())) { air--; setAir(air); if (getAir() == -20) { setAir(0); attackEntityFrom(DamageSource.drown, 2.0F); } } else { setAir(300); } } /** * Applies the entities attributes. */ protected void applyEntityAttributes() { super.applyEntityAttributes(); getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); } /** * Get the experience points the entity currently has. */ protected int getExperiencePoints(EntityPlayer player) { return 1 + this.worldObj.rand.nextInt(3); } /** * Checks to see if the entity can spawn at its current location. */ public boolean getCanSpawnHere() { return this.worldObj.checkNoEntityCollision(this.boundingBox); } } Here is the render class: package com.feudalcraft.client.render.entity; import org.lwjgl.opengl.GL11; 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 net.minecraft.util.ResourceLocation; import com.feudalcraft.client.entity.monster.EntityShark; import com.feudalcraft.client.entity.monster.EntityZombieSummonerMob; import com.feudalcraft.lib.Strings; import com.feudalcraft.model.ModelShark; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class RenderEntityShark extends RenderLiving { private static final ResourceLocation sharkTextures = new ResourceLocation(Strings.MOD_ID + ":textures/entity/shark/adult_shark.png"); private ModelShark sharkModel; public RenderEntityShark() { super(new ModelShark(0.5F), 1.0F); this.sharkModel = (ModelShark)this.mainModel; } public RenderEntityShark(ModelBase modelbase, float f) { super(modelbase, f); } /** * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. */ protected ResourceLocation getEntityTexture(EntityShark zombie) { return sharkTextures; } /** * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: entityLiving, partialTickTime */ protected void preRenderCallback(EntityShark entity, float f) { float f1 = 0.9375F; GL11.glScalef(f1, f1, f1); } public void createChild(EntityShark entity, float f) { if (entity.isChild()) { GL11.glScalef(-0.5F, -0.5F, -0.5F); } } /** * 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 entity, double x, double y, double z, float f0, float f1) { this.doRender((EntityShark)entity, x, y, z, f0, f1); if (entity.isChild()) { GL11.glScalef(-0.5F, -0.5F, -0.5F); } } /** * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: entityLiving, partialTickTime */ protected void preRenderCallback(EntityLivingBase entity, float f) { this.preRenderCallback((EntityShark)entity, f); this.createChild((EntityShark)entity, f); } public void doRender(EntityShark entity, double d, double d1, double d2, float f, float f1) { super.doRender(entity, d, d1, d2, f, f1); } public void doRenderLiving(EntityLiving entityliving, double d, double d1, double d2, float f, float f1) { doRender((EntityShark)entityliving, d, d1, d2, f, f1); } public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) { doRender((EntityShark)entity, d, d1, d2, f, f1); } /** * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. */ protected ResourceLocation getEntityTexture(Entity entity) { return this.getEntityTexture((EntityShark)entity); } }
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.