/**
  * Helper generation method for skeletons
  *
  * @param type the new type of the arrow
  * @param arrow the original arrow fired by the skeleton
  * @param skeleton the shooter
  * @return
  */
 public static AbstractMBArrow generate(int type, EntityArrow arrow, EntitySkeleton skeleton) {
   AbstractMBArrow mbArrow = null;
   if (arrow != null
       && skeleton != null
       && skeleton.getAttackTarget() != null
       && type < ItemMBArrow.arrows.length) {
     try {
       mbArrow =
           ItemMBArrow.arrows[type]
               .getConstructor(
                   World.class,
                   EntityLivingBase.class,
                   EntityLivingBase.class,
                   float.class,
                   float.class)
               .newInstance(
                   arrow.worldObj,
                   skeleton,
                   skeleton.getAttackTarget(),
                   1.6F,
                   (float) (14 - skeleton.worldObj.getDifficulty().getDifficultyId() * 4));
     } catch (Exception e) {
       e.printStackTrace();
     }
   }
   return mbArrow;
 }
  public Entity spawnEntity(Entity par1Entity) {

    if (par1Entity instanceof EntityLivingBase && par1Entity.worldObj != null) {
      if (par1Entity instanceof EntitySkeleton) {
        ((EntitySkeleton) par1Entity).setSkeletonType(skeletonType);
        if (skeletonType == 1) {
          par1Entity.setCurrentItemOrArmor(0, new ItemStack(Items.stone_sword));
          ((EntitySkeleton) par1Entity).setEquipmentDropChance(0, 0f);
        } else {
          par1Entity.setCurrentItemOrArmor(0, new ItemStack(Items.bow));
        }
      } else ((EntityLiving) par1Entity).onSpawnWithEgg(null);

      if (!requiresPlayer) {
        ((EntityLiving) par1Entity).func_110163_bv();
        par1Entity
            .getEntityData()
            .setLong("SpawnedByDESpawner", getSpawnerWorld().getTotalWorldTime());
      }

      this.getSpawnerWorld().spawnEntityInWorld(par1Entity);
    }

    return par1Entity;
  }
  public void upgradeMob(EntityLivingBase mob) {
    int diff = mob.worldObj.difficultySetting.getDifficultyId();

    if (ConfigHardcore.upgradeZombieWep) {
      if (mob instanceof EntitySkeleton) {
        if (((EntitySkeleton) mob).getSkeletonType() == 1) {
          giveEntityWeapon(mob, 5, rand.nextInt(7));
        }
      }
      if (mob instanceof EntityZombie) {
        int tier = 2;
        if (mob instanceof EntityPigZombie) {
          tier = 7;
          giveEntityWeapon(mob, tier, rand.nextInt(4));
        } else {
          if (mob.getHeldItem() != null && mob.getHeldItem().getItem() == Items.iron_sword) {
            giveEntityWeapon(mob, tier, 0);
          } else {
            if (rand.nextFloat() * (zombieWepChance * ConfigHardcore.zombieWepChance) < diff) {
              giveEntityWeapon(mob, tier, rand.nextInt(4));
            }
          }
        }
        if (rand.nextFloat() * (zombieKnightChance * ConfigHardcore.zombieWepChance) < diff) {
          createZombieKnight((EntityZombie) mob);
        } else if (rand.nextFloat() * (zombieBruteChance * ConfigHardcore.zombieWepChance) < diff) {
          createZombieBrute((EntityZombie) mob);
        }
      }
    }
    if (mob instanceof EntitySpider) {
      if (mob.riddenByEntity == null) {
        if (rand.nextFloat() * (skeletalRiderChance * ConfigHardcore.zombieWepChance) < diff) {
          EntitySkeleton rider = new EntitySkeleton(mob.worldObj);
          rider.setPosition(mob.posX, mob.posY, mob.posZ);
          mob.worldObj.spawnEntityInWorld(rider);
          rider.setCurrentItemOrArmor(0, new ItemStack(ToolListMF.lances[2]));
          rider.mountEntity(mob);
          mob.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(64.0D);
          mob.addPotionEffect(new PotionEffect(Potion.moveSpeed.id, Integer.MAX_VALUE, 10));
        } else if (rand.nextFloat() * (witchRiderChance * ConfigHardcore.zombieWepChance) < diff) {
          EntityWitch rider = new EntityWitch(mob.worldObj);
          rider.setPosition(mob.posX, mob.posY, mob.posZ);
          mob.worldObj.spawnEntityInWorld(rider);
          rider.mountEntity(mob);
        } else if (rand.nextFloat() * (creeperJockeyChance * ConfigHardcore.zombieWepChance)
            < diff) {
          EntityCreeper rider = new EntityCreeper(mob.worldObj);
          rider.setPosition(mob.posX, mob.posY, mob.posZ);
          mob.worldObj.spawnEntityInWorld(rider);
          rider.mountEntity(mob);
        }
      }
    }
  }
  @Override
  public void doSpellCasterEffect(EntityPlayer caster) {
    caster.worldObj.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, 1.0F);

    final EntitySkeleton witherSkeleton = new EntitySkeleton(caster.worldObj);
    witherSkeleton.setSkeletonType(1);
    witherSkeleton.setPosition(caster.posX, caster.posY, caster.posZ);

    caster.worldObj.spawnEntityInWorld(witherSkeleton);
    PacketDispatcher.sendPacketToAllPlayers(
        PacketHandler.createSummonGFXPacket(
            witherSkeleton.posX, witherSkeleton.posY, witherSkeleton.posZ));
  }
  @Override
  public void onLivingUpdate() {
    //        if (this.isRiding() && this.getAttackTarget() != null && this.ridingEntity instanceof
    // EntityUndeadHorse) {
    //            ((EntityLiving)
    // this.ridingEntity).getNavigator().setPath(this.getNavigator().getPath(), 1.5D);
    //        }

    super.onLivingUpdate();
  }
  @SideOnly(Side.CLIENT)
  public Entity getEntityForRenderer() {
    if (this.renderedEntity == null) {
      Entity entity = EntityList.createEntityByName(this.getEntityNameToSpawn(), getSpawnerWorld());
      entity = this.spawnEntity(entity);
      if (entity instanceof EntitySkeleton) ((EntitySkeleton) entity).setSkeletonType(skeletonType);
      this.renderedEntity = entity;
    }

    return this.renderedEntity;
  }
  /** Called when the mob's health reaches 0. */
  @Override
  public void onDeath(DamageSource par1DamageSource) {
    super.onDeath(par1DamageSource);

    if (par1DamageSource.getSourceOfDamage() instanceof EntityArrow
        && par1DamageSource.getEntity() instanceof EntityPlayer) {
      final EntityPlayer var2 = (EntityPlayer) par1DamageSource.getEntity();
      final double var3 = var2.posX - this.posX;
      final double var5 = var2.posZ - this.posZ;

      if (var3 * var3 + var5 * var5 >= 2500.0D) {
        var2.triggerAchievement(AchievementList.snipeSkeleton);
      }
    }
  }
  /**
   * 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.
   */
  @Override
  public void onLivingUpdate() {
    if (this.worldObj.isDaytime() && !this.worldObj.isRemote) {
      final float var1 = this.getBrightness(1.0F);

      if (var1 > 0.5F
          && this.worldObj.canBlockSeeTheSky(
              MathHelper.floor_double(this.posX),
              MathHelper.floor_double(this.posY),
              MathHelper.floor_double(this.posZ))
          && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F) {
        this.setFire(8);
      }
    }

    super.onLivingUpdate();
  }
 /**
  * Returns the location of an entity's texture. Doesn't seem to be called unless you call
  * Render.bindEntityTexture.
  */
 protected ResourceLocation getEntityTexture(EntitySkeleton p_110775_1_) {
   return p_110775_1_.getSkeletonType() == 1 ? witherSkeletonTextures : skeletonTextures;
 }
 /**
  * Allows the render to do any OpenGL state modifications necessary before the model is rendered.
  * Args: entityLiving, partialTickTime
  */
 protected void preRenderCallback(EntitySkeleton p_77041_1_, float p_77041_2_) {
   if (p_77041_1_.getSkeletonType() == 1) {
     GL11.glScalef(1.2F, 1.2F, 1.2F);
   }
 }
 @Override
 public void onUpdate() {
   super.onUpdate();
 }
 @Override
 protected void applyEntityAttributes() {
   super.applyEntityAttributes();
   this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setAttribute(25);
   this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setAttribute(0.35F);
 }
  @Override
  public List<RandomMob> getRandomMobs(World world) {
    List<RandomMob> mobs = new ArrayList<RandomMob>();

    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityMooshroom.class, world), 20));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntitySlime.class, world), 20));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityCow.class, world), 100));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityChicken.class, world), 100));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntitySheep.class, world), 100));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityWitch.class, world), 10));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityGhast.class, world), 15));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityPig.class, world), 100));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityCreeper.class, world), 25));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntitySquid.class, world), 30));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityOcelot.class, world), 20));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityWolf.class, world), 20));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityBat.class, world), 35));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityHorse.class, world), 20));
    mobs.add(new RandomMob(MFRUtil.prepareMob(EntityMinecartHopper.class, world), 15));

    EntityCreeper chargedCreeper = (EntityCreeper) MFRUtil.prepareMob(EntityCreeper.class, world);
    NBTTagCompound creeperNBT = new NBTTagCompound();
    chargedCreeper.writeToNBT(creeperNBT);
    creeperNBT.setBoolean("powered", true);
    creeperNBT.setShort("Fuse", (short) 120);
    chargedCreeper.readFromNBT(creeperNBT);
    mobs.add(new RandomMob(chargedCreeper, 5));

    EntityTNTPrimed armedTNT = (EntityTNTPrimed) MFRUtil.prepareMob(EntityTNTPrimed.class, world);
    armedTNT.fuse = 120;
    mobs.add(new RandomMob(armedTNT, 5));

    EntitySlime invisislime = (EntitySlime) MFRUtil.prepareMob(EntitySlime.class, world);
    invisislime.addPotionEffect(new PotionEffect(Potion.invisibility.id, 120 * 20));
    mobs.add(new RandomMob(invisislime, 5));

    EntityMooshroom invisishroom =
        (EntityMooshroom) MFRUtil.prepareMob(EntityMooshroom.class, world);
    invisishroom.addPotionEffect(new PotionEffect(Potion.invisibility.id, 120 * 20));
    mobs.add(new RandomMob(invisishroom, 5));

    EntityWolf invisiwolf = (EntityWolf) MFRUtil.prepareMob(EntityWolf.class, world);
    invisiwolf.addPotionEffect(new PotionEffect(Potion.invisibility.id, 120 * 20));
    invisiwolf.setAngry(true);
    mobs.add(new RandomMob(invisiwolf, 5));

    EntityTNTPrimed tntJockey = (EntityTNTPrimed) MFRUtil.prepareMob(EntityTNTPrimed.class, world);
    EntityBat tntMount = (EntityBat) MFRUtil.prepareMob(EntityBat.class, world);
    tntJockey.fuse = 120;
    tntJockey.mountEntity(tntMount);
    mobs.add(new RandomMob(tntMount, 2));

    EntitySkeleton skeleton1 = (EntitySkeleton) MFRUtil.prepareMob(EntitySkeleton.class, world);
    EntitySkeleton skeleton2 = (EntitySkeleton) MFRUtil.prepareMob(EntitySkeleton.class, world);
    EntitySkeleton skeleton3 = (EntitySkeleton) MFRUtil.prepareMob(EntitySkeleton.class, world);
    EntitySkeleton skeleton4 = (EntitySkeleton) MFRUtil.prepareMob(EntitySkeleton.class, world);
    skeleton4.mountEntity(skeleton3);
    skeleton3.mountEntity(skeleton2);
    skeleton2.mountEntity(skeleton1);
    mobs.add(new RandomMob(skeleton1, 2));

    EntityBlaze blazeJockey = (EntityBlaze) MFRUtil.prepareMob(EntityBlaze.class, world);
    EntityGhast blazeMount = (EntityGhast) MFRUtil.prepareMob(EntityGhast.class, world);
    blazeJockey.mountEntity(blazeMount);
    mobs.add(new RandomMob(blazeMount, 2));

    EntityCreeper creeperJockey = (EntityCreeper) MFRUtil.prepareMob(EntityCreeper.class, world);
    EntityCaveSpider creeperMount =
        (EntityCaveSpider) MFRUtil.prepareMob(EntityCaveSpider.class, world);
    creeperJockey.mountEntity(creeperMount);
    mobs.add(new RandomMob(creeperMount, 2));

    tntJockey = (EntityTNTPrimed) MFRUtil.prepareMob(EntityTNTPrimed.class, world);
    EntityXPOrb tntMount2 = (EntityXPOrb) MFRUtil.prepareMob(EntityXPOrb.class, world);
    tntJockey.fuse = 120;
    tntMount2.xpValue = 1;
    tntMount2.xpOrbAge = Short.MIN_VALUE;
    tntMount2.field_70532_c = Short.MAX_VALUE;
    tntJockey.mountEntity(tntMount2);
    mobs.add(new RandomMob(tntMount2, 2));

    creeperJockey = (EntityCreeper) MFRUtil.prepareMob(EntityCreeper.class, world);
    EntityXPOrb creeperMount2 = (EntityXPOrb) MFRUtil.prepareMob(EntityXPOrb.class, world);
    creeperMount2.xpValue = 1;
    creeperMount2.xpOrbAge = Short.MIN_VALUE;
    creeperMount2.field_70532_c = Short.MAX_VALUE;
    creeperJockey.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 20));
    creeperJockey.onStruckByLightning(null);
    creeperJockey.mountEntity(creeperMount2);
    mobs.add(new RandomMob(creeperMount2, 1));

    EntityEnderman direBane = (EntityEnderman) MFRUtil.prepareMob(EntityEnderman.class, world);
    direBane.addPotionEffect(new PotionEffect(Potion.regeneration.id, 120 * 20));
    direBane.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 120 * 20));
    direBane.getEntityAttribute(SharedMonsterAttributes.maxHealth).setAttribute(120);
    direBane.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setAttribute(0.7);
    direBane.getEntityAttribute(SharedMonsterAttributes.attackDamage).setAttribute(15);
    direBane.getEntityAttribute(SharedMonsterAttributes.followRange).setAttribute(32);
    direBane.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setAttribute(1);
    direBane.stepHeight = 2;
    EntityPlayer player = world.getPlayerEntityByName("direwolf20");
    if (player != null) {
      direBane.setCustomNameTag("Bane of direwolf");
      direBane.setAlwaysRenderNameTag(true);
      direBane.func_110163_bv();
      ItemStack armor = new ItemStack(Item.plateGold);
      AutoEnchantmentHelper.addRandomEnchantment(direBane.getRNG(), armor, 60);
      int i = EntityLiving.getArmorPosition(armor);
      direBane.setCurrentItemOrArmor(i, armor);
      direBane.setEquipmentDropChance(i, 2.0F);
    }
    mobs.add(new RandomMob(direBane, 1));

    return mobs;
  }