As the title says I can NOT register entities and their models properly. Yes I know the code is copy and pasted from a collection of spider classes, I am not extending the spider classes because I want to understand how to get an entity to work on my own without just extending other classes and using Vanilla entities as prefabs. Yes, I have looked online for this information, in the past I was able to get a gray rectangle to render and acted as an entity however I never got models to work. The Entity is not registering and I'm assuming the model is NOT since I have NOT gotten an Entity model to work in the past.
EntityScorpion class.
package scar430.betterthanconcrete.entities.scorpion;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackMelee;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILeapAtTarget;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityIronGolem;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.monster.EntitySpider;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.pathfinding.PathNavigate;
import net.minecraft.pathfinding.PathNavigateClimber;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import net.minecraft.world.storage.loot.LootTableList;
public class EntityScorpion extends EntityMob {
private static final DataParameter<Byte> CLIMBING = EntityDataManager.<Byte>createKey(EntityScorpion.class, DataSerializers.BYTE);
public EntityScorpion(World worldIn)
{
super(worldIn);
this.setSize(1.4F, 0.9F);
}
public static void registerFixesSpider(DataFixer fixer)
{
EntityLiving.registerFixesMob(fixer, EntityScorpion.class);
}
protected void initEntityAI()
{
this.tasks.addTask(1, new EntityAISwimming(this));
this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F));
//this.tasks.addTask(4, new EntitySpider.AISpiderAttack(this));
this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 0.8D));
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(6, new EntityAILookIdle(this));
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false, new Class[0]));
//this.targetTasks.addTask(2, new EntitySpider.AISpiderTarget(this, EntityPlayer.class));
//this.targetTasks.addTask(3, new EntitySpider.AISpiderTarget(this, EntityIronGolem.class));
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return (double)(this.height * 0.5F);
}
/**
* Returns new PathNavigateGround instance
*/
protected PathNavigate createNavigator(World worldIn)
{
return new PathNavigateClimber(this, worldIn);
}
protected void entityInit()
{
super.entityInit();
this.dataManager.register(CLIMBING, Byte.valueOf((byte)0));
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
super.onUpdate();
if (!this.world.isRemote)
{
this.setBesideClimbableBlock(this.collidedHorizontally);
}
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(16.0D);
this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.30000001192092896D);
}
protected SoundEvent getAmbientSound()
{
return SoundEvents.ENTITY_SPIDER_AMBIENT;
}
protected SoundEvent getHurtSound(DamageSource damageSourceIn)
{
return SoundEvents.ENTITY_SPIDER_HURT;
}
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_SPIDER_DEATH;
}
protected void playStepSound(BlockPos pos, Block blockIn)
{
this.playSound(SoundEvents.ENTITY_SPIDER_STEP, 0.15F, 1.0F);
}
@Nullable
protected ResourceLocation getLootTable()
{
return LootTableList.ENTITIES_SPIDER;
}
/**
* Returns true if this entity should move as if it were on a ladder (either because it's actually on a ladder, or
* for AI reasons)
*/
public boolean isOnLadder()
{
return this.isBesideClimbableBlock();
}
/**
* Sets the Entity inside a web block.
*/
public void setInWeb()
{
}
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.ARTHROPOD;
}
public boolean isPotionApplicable(PotionEffect potioneffectIn)
{
return potioneffectIn.getPotion() == MobEffects.POISON ? false : super.isPotionApplicable(potioneffectIn);
}
/**
* Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. The WatchableObject is updated using
* setBesideClimableBlock.
*/
public boolean isBesideClimbableBlock()
{
return (((Byte)this.dataManager.get(CLIMBING)).byteValue() & 1) != 0;
}
/**
* Updates the WatchableObject (Byte) created in entityInit(), setting it to 0x01 if par1 is true or 0x00 if it is
* false.
*/
public void setBesideClimbableBlock(boolean climbing)
{
byte b0 = ((Byte)this.dataManager.get(CLIMBING)).byteValue();
if (climbing)
{
b0 = (byte)(b0 | 1);
}
else
{
b0 = (byte)(b0 & -2);
}
this.dataManager.set(CLIMBING, Byte.valueOf(b0));
}
/**
* Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
* when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
*/
@Nullable
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
{
livingdata = super.onInitialSpawn(difficulty, livingdata);
if (this.world.rand.nextInt(100) == 0)
{
EntitySkeleton entityskeleton = new EntitySkeleton(this.world);
entityskeleton.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F);
entityskeleton.onInitialSpawn(difficulty, (IEntityLivingData)null);
this.world.spawnEntity(entityskeleton);
entityskeleton.startRiding(this);
}
if (livingdata == null)
{
livingdata = new EntityScorpion.GroupData();
if (this.world.getDifficulty() == EnumDifficulty.HARD && this.world.rand.nextFloat() < 0.1F * difficulty.getClampedAdditionalDifficulty())
{
((EntityScorpion.GroupData)livingdata).setRandomEffect(this.world.rand);
}
}
if (livingdata instanceof EntityScorpion.GroupData)
{
Potion potion = ((EntityScorpion.GroupData)livingdata).effect;
if (potion != null)
{
this.addPotionEffect(new PotionEffect(potion, Integer.MAX_VALUE));
}
}
return livingdata;
}
public float getEyeHeight()
{
return 0.65F;
}
static class AISpiderAttack extends EntityAIAttackMelee
{
public AISpiderAttack(EntityScorpion spider)
{
super(spider, 1.0D, true);
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean shouldContinueExecuting()
{
float f = this.attacker.getBrightness();
if (f >= 0.5F && this.attacker.getRNG().nextInt(100) == 0)
{
this.attacker.setAttackTarget((EntityLivingBase)null);
return false;
}
else
{
return super.shouldContinueExecuting();
}
}
protected double getAttackReachSqr(EntityLivingBase attackTarget)
{
return (double)(4.0F + attackTarget.width);
}
}
static class AISpiderTarget<T extends EntityLivingBase> extends EntityAINearestAttackableTarget<T>
{
public AISpiderTarget(EntitySpider spider, Class<T> classTarget)
{
super(spider, classTarget, true);
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute()
{
float f = this.taskOwner.getBrightness();
return f >= 0.5F ? false : super.shouldExecute();
}
}
public static class GroupData implements IEntityLivingData
{
public Potion effect;
public void setRandomEffect(Random rand)
{
int i = rand.nextInt(5);
if (i <= 1)
{
this.effect = MobEffects.SPEED;
}
else if (i <= 2)
{
this.effect = MobEffects.STRENGTH;
}
else if (i <= 3)
{
this.effect = MobEffects.REGENERATION;
}
else if (i <= 4)
{
this.effect = MobEffects.INVISIBILITY;
}
}
}
}
ModelScorpion class.
package scar430.betterthanconcrete.entities.scorpion;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.MathHelper;
public class ModelScorpion extends ModelBase {
/** The spider's head box */
public ModelRenderer spiderHead;
/** The spider's neck box */
public ModelRenderer spiderNeck;
/** The spider's body box */
public ModelRenderer spiderBody;
/** Spider's first leg */
public ModelRenderer spiderLeg1;
/** Spider's second leg */
public ModelRenderer spiderLeg2;
/** Spider's third leg */
public ModelRenderer spiderLeg3;
/** Spider's fourth leg */
public ModelRenderer spiderLeg4;
/** Spider's fifth leg */
public ModelRenderer spiderLeg5;
/** Spider's sixth leg */
public ModelRenderer spiderLeg6;
/** Spider's seventh leg */
public ModelRenderer spiderLeg7;
/** Spider's eight leg */
public ModelRenderer spiderLeg8;
public ModelScorpion()
{
float f = 0.0F;
int i = 15;
this.spiderHead = new ModelRenderer(this, 32, 4);
this.spiderHead.addBox(-4.0F, -4.0F, -8.0F, 8, 8, 8, 0.0F);
this.spiderHead.setRotationPoint(0.0F, 15.0F, -3.0F);
this.spiderNeck = new ModelRenderer(this, 0, 0);
this.spiderNeck.addBox(-3.0F, -3.0F, -3.0F, 6, 6, 6, 0.0F);
this.spiderNeck.setRotationPoint(0.0F, 15.0F, 0.0F);
this.spiderBody = new ModelRenderer(this, 0, 12);
this.spiderBody.addBox(-5.0F, -4.0F, -6.0F, 10, 8, 12, 0.0F);
this.spiderBody.setRotationPoint(0.0F, 15.0F, 9.0F);
this.spiderLeg1 = new ModelRenderer(this, 18, 0);
this.spiderLeg1.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg1.setRotationPoint(-4.0F, 15.0F, 2.0F);
this.spiderLeg2 = new ModelRenderer(this, 18, 0);
this.spiderLeg2.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg2.setRotationPoint(4.0F, 15.0F, 2.0F);
this.spiderLeg3 = new ModelRenderer(this, 18, 0);
this.spiderLeg3.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg3.setRotationPoint(-4.0F, 15.0F, 1.0F);
this.spiderLeg4 = new ModelRenderer(this, 18, 0);
this.spiderLeg4.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg4.setRotationPoint(4.0F, 15.0F, 1.0F);
this.spiderLeg5 = new ModelRenderer(this, 18, 0);
this.spiderLeg5.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg5.setRotationPoint(-4.0F, 15.0F, 0.0F);
this.spiderLeg6 = new ModelRenderer(this, 18, 0);
this.spiderLeg6.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg6.setRotationPoint(4.0F, 15.0F, 0.0F);
this.spiderLeg7 = new ModelRenderer(this, 18, 0);
this.spiderLeg7.addBox(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg7.setRotationPoint(-4.0F, 15.0F, -1.0F);
this.spiderLeg8 = new ModelRenderer(this, 18, 0);
this.spiderLeg8.addBox(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F);
this.spiderLeg8.setRotationPoint(4.0F, 15.0F, -1.0F);
}
/**
* Sets the models various rotation angles then renders the model.
*/
public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale)
{
this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entityIn);
this.spiderHead.render(scale);
this.spiderNeck.render(scale);
this.spiderBody.render(scale);
this.spiderLeg1.render(scale);
this.spiderLeg2.render(scale);
this.spiderLeg3.render(scale);
this.spiderLeg4.render(scale);
this.spiderLeg5.render(scale);
this.spiderLeg6.render(scale);
this.spiderLeg7.render(scale);
this.spiderLeg8.render(scale);
}
/**
* Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms
* and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how
* "far" arms and legs can swing at most.
*/
public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn)
{
this.spiderHead.rotateAngleY = netHeadYaw * 0.017453292F;
this.spiderHead.rotateAngleX = headPitch * 0.017453292F;
float f = ((float)Math.PI / 4F);
this.spiderLeg1.rotateAngleZ = -((float)Math.PI / 4F);
this.spiderLeg2.rotateAngleZ = ((float)Math.PI / 4F);
this.spiderLeg3.rotateAngleZ = -0.58119464F;
this.spiderLeg4.rotateAngleZ = 0.58119464F;
this.spiderLeg5.rotateAngleZ = -0.58119464F;
this.spiderLeg6.rotateAngleZ = 0.58119464F;
this.spiderLeg7.rotateAngleZ = -((float)Math.PI / 4F);
this.spiderLeg8.rotateAngleZ = ((float)Math.PI / 4F);
float f1 = -0.0F;
float f2 = 0.3926991F;
this.spiderLeg1.rotateAngleY = ((float)Math.PI / 4F);
this.spiderLeg2.rotateAngleY = -((float)Math.PI / 4F);
this.spiderLeg3.rotateAngleY = 0.3926991F;
this.spiderLeg4.rotateAngleY = -0.3926991F;
this.spiderLeg5.rotateAngleY = -0.3926991F;
this.spiderLeg6.rotateAngleY = 0.3926991F;
this.spiderLeg7.rotateAngleY = -((float)Math.PI / 4F);
this.spiderLeg8.rotateAngleY = ((float)Math.PI / 4F);
float f3 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + 0.0F) * 0.4F) * limbSwingAmount;
float f4 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + (float)Math.PI) * 0.4F) * limbSwingAmount;
float f5 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + ((float)Math.PI / 2F)) * 0.4F) * limbSwingAmount;
float f6 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + ((float)Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount;
float f7 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + 0.0F) * 0.4F) * limbSwingAmount;
float f8 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + (float)Math.PI) * 0.4F) * limbSwingAmount;
float f9 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + ((float)Math.PI / 2F)) * 0.4F) * limbSwingAmount;
float f10 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + ((float)Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount;
this.spiderLeg1.rotateAngleY += f3;
this.spiderLeg2.rotateAngleY += -f3;
this.spiderLeg3.rotateAngleY += f4;
this.spiderLeg4.rotateAngleY += -f4;
this.spiderLeg5.rotateAngleY += f5;
this.spiderLeg6.rotateAngleY += -f5;
this.spiderLeg7.rotateAngleY += f6;
this.spiderLeg8.rotateAngleY += -f6;
this.spiderLeg1.rotateAngleZ += f7;
this.spiderLeg2.rotateAngleZ += -f7;
this.spiderLeg3.rotateAngleZ += f8;
this.spiderLeg4.rotateAngleZ += -f8;
this.spiderLeg5.rotateAngleZ += f9;
this.spiderLeg6.rotateAngleZ += -f9;
this.spiderLeg7.rotateAngleZ += f10;
this.spiderLeg8.rotateAngleZ += -f10;
}
}
RenderScorpion class.
package scar430.betterthanconcrete.entities.scorpion;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
public class RenderScorpion<T extends EntityScorpion> extends RenderLiving<T> {
private static final ResourceLocation SPIDER_TEXTURES = new ResourceLocation("textures/entity/spider/spider.png");
public RenderScorpion(RenderManager renderManagerIn)
{
super(renderManagerIn, new ModelScorpion(), 1.0F);
//this.addLayer(new LayerSpiderEyes(this));
}
protected float getDeathMaxRotation(T entityLivingBaseIn)
{
return 180.0F;
}
/**
* Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
*/
protected ResourceLocation getEntityTexture(T entity)
{
return SPIDER_TEXTURES;
}
}
ModEntities class
package scar430.betterthanconcrete.init;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.material.MapColor;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.BiomeDictionary;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.fml.common.registry.EntityEntryBuilder;
import net.minecraftforge.registries.IForgeRegistry;
import scar430.betterthanconcrete.entities.DamnedSoul.EntityDamnedSoul;
import scar430.betterthanconcrete.entities.scorpion.EntityScorpion;
import scar430.betterthanconcrete.util.Reference;
public class ModEntities {
public static EntityEntry SCORPION;
private static final ModEntities instance = new ModEntities();
public static void load(){
SCORPION = EntityEntryBuilder.create()
.entity(EntityScorpion.class)
.id(Reference.MOD_ID + ":" + "scorpion", 0)
.name("scorpion")
.tracker(80, 3, true)
.egg(MapColor.ADOBE.colorValue, MapColor.EMERALD.colorValue)
.spawn(EnumCreatureType.CREATURE, 20, 1, 5, BiomeDictionary.getBiomes(BiomeDictionary.Type.NETHER))
.build();
MinecraftForge.EVENT_BUS.register(instance);
}
@SubscribeEvent
public void registerEntity(RegistryEvent.Register<EntityEntry> event){
IForgeRegistry<EntityEntry> registry = event.getRegistry();
registry.register(SCORPION);
}
/*
public static final Set<EntityEntry> SET_ENTITIES = ImmutableSet.of(
/*EntityEntryBuilder.create()
.entity(EntityDamnedSoul.class)
.id(new ResourceLocation(Reference.MOD_ID, "textures/entity/damned_soul.png"), 0)
.name("damned_soul")
.tracker(80, 3, false)
.egg(MapColor.BLACK.colorValue, MapColor.GRAY.colorValue)
.spawn(EnumCreatureType.CREATURE, 20, 1, 5, BiomeDictionary.getBiomes(BiomeDictionary.Type.NETHER))
.build()*/
/*
EntityEntryBuilder.create()
.entity(EntityDamnedSoul.class)
.id(new ResourceLocation(Reference.MOD_ID, "textures/entity/spider/spider.png"), 0)
.name("sand_spider")
.tracker(80, 3, false)
.egg(MapColor.BROWN.colorValue, MapColor.GREEN.colorValue)
.spawn(EnumCreatureType.MONSTER, 20, 1, 5, BiomeDictionary.getBiomes(BiomeDictionary.Type.HOT))
.build()
);
@EventBusSubscriber(modid = Reference.MOD_ID)
public static class RegistrationHandler
{
/**
* Register this mod's {@link EntityEntry}s.
*
* @param event The event
*/
/*@SubscribeEvent
public static void onEvent(final RegistryEvent.Register<EntityEntry> event)
{
final IForgeRegistry<EntityEntry> registry = event.getRegistry();
// DEBUG
System.out.println("Registering entities");
for (final EntityEntry entityEntry : SET_ENTITIES)
{
// // DEBUG
// System.out.println("Registering entity = " + entityEntry.getEntityClass());
registry.register(entityEntry);
}
}
}*/
}
Client Proxy
package scar430.betterthanconcrete.proxy;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import scar430.betterthanconcrete.entities.DamnedSoul.EntityDamnedSoul;
import scar430.betterthanconcrete.entities.DamnedSoul.ModelDamnedSoul;
import scar430.betterthanconcrete.entities.DamnedSoul.RenderDamnedSoul;
public class ClientProxy extends CommonProxy {
public void registerItemRenderer(Item item, int meta, String id) {
ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(item.getRegistryName(), id));
}
}
Here's the Common Proxy just in case, I'm trying to make this post air-tight.
package scar430.betterthanconcrete.proxy;
import net.minecraft.item.Item;
public class CommonProxy {
public void registerItemRenderer(Item item, int meta, String id) {
}
}