/*******************************************************************************
* AbyssalCraft
* Copyright (c) 2012 - 2017 Shinoow.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Contributors:
* Shinoow - implementation
******************************************************************************/
package com.shinoow.abyssalcraft.common.entity.anti;
import java.util.Calendar;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.passive.EntityAmbientCreature;
import net.minecraft.entity.passive.EntityBat;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import com.shinoow.abyssalcraft.api.entity.IAntiEntity;
import com.shinoow.abyssalcraft.lib.ACLoot;
public class EntityAntiBat extends EntityAmbientCreature implements IAntiEntity {
private static final DataParameter<Byte> HANGING = EntityDataManager.<Byte>createKey(EntityAntiBat.class, DataSerializers.BYTE);
/** Coordinates of where the bat spawned. */
private BlockPos spawnPosition;
public EntityAntiBat(World par1World)
{
super(par1World);
setSize(0.5F, 0.9F);
setIsBatHanging(true);
}
@Override
protected void entityInit()
{
super.entityInit();
dataManager.register(HANGING, new Byte((byte)0));
}
@Override
protected float getSoundVolume()
{
return 0.1F;
}
@Override
protected float getSoundPitch()
{
return super.getSoundPitch() * 0.95F;
}
@Override
protected SoundEvent getAmbientSound()
{
return getIsBatHanging() && rand.nextInt(4) != 0 ? null : SoundEvents.ENTITY_BAT_AMBIENT;
}
@Override
protected SoundEvent getHurtSound()
{
return SoundEvents.ENTITY_BAT_HURT;
}
@Override
protected SoundEvent getDeathSound()
{
return SoundEvents.ENTITY_BAT_DEATH;
}
@Override
public boolean canBePushed()
{
return false;
}
@Override
protected ResourceLocation getLootTable(){
return ACLoot.ENTITY_ANTI_BAT;
}
@Override
protected void collideWithEntity(Entity par1Entity)
{
if(!world.isRemote && par1Entity instanceof EntityBat){
boolean flag = world.getGameRules().getBoolean("mobGriefing");
world.createExplosion(this, posX, posY, posZ, 5, flag);
setDead();
}
}
@Override
protected void collideWithNearbyEntities() {}
@Override
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(12.0D);
}
public boolean getIsBatHanging()
{
return (dataManager.get(HANGING) & 1) != 0;
}
public void setIsBatHanging(boolean par1)
{
byte b0 = dataManager.get(HANGING).byteValue();
if (par1)
dataManager.set(HANGING, Byte.valueOf((byte)(b0 | 1)));
else
dataManager.set(HANGING, Byte.valueOf((byte)(b0 & -2)));
}
@Override
public void onUpdate()
{
super.onUpdate();
if (getIsBatHanging())
{
motionX = motionY = motionZ = 0.0D;
posY = MathHelper.floor(posY) + 1.0D - height;
} else
motionY *= 0.6000000238418579D;
}
@Override
protected void updateAITasks()
{
super.updateAITasks();
BlockPos blockpos = new BlockPos(this);
BlockPos blockpos1 = blockpos.up();
if (getIsBatHanging())
{
if (!world.getBlockState(blockpos1).isNormalCube())
{
setIsBatHanging(false);
world.playEvent((EntityPlayer)null, 1025, blockpos, 0);
}
else
{
if (rand.nextInt(200) == 0)
rotationYawHead = rand.nextInt(360);
if (world.getClosestPlayerToEntity(this, 4.0D) != null)
{
setIsBatHanging(false);
world.playEvent((EntityPlayer)null, 1025, blockpos, 0);
}
}
}
else
{
if (spawnPosition != null && (!world.isAirBlock(spawnPosition) || spawnPosition.getY() < 1))
spawnPosition = null;
if (spawnPosition == null || rand.nextInt(30) == 0 || spawnPosition.distanceSq((int)posX, (int)posY, (int)posZ) < 4.0D)
spawnPosition = new BlockPos((int)posX + rand.nextInt(7) - rand.nextInt(7), (int)posY + rand.nextInt(6) - 2, (int)posZ + rand.nextInt(7) - rand.nextInt(7));
double d0 = spawnPosition.getX() + 0.5D - posX;
double d1 = spawnPosition.getY() + 0.1D - posY;
double d2 = spawnPosition.getZ() + 0.5D - posZ;
motionX += (Math.signum(d0) * 0.5D - motionX) * 0.10000000149011612D;
motionY += (Math.signum(d1) * 0.699999988079071D - motionY) * 0.10000000149011612D;
motionZ += (Math.signum(d2) * 0.5D - motionZ) * 0.10000000149011612D;
float f = (float)(MathHelper.atan2(motionZ, motionX) * 180.0D / Math.PI) - 90.0F;
float f1 = MathHelper.wrapDegrees(f - rotationYaw);
moveForward = 0.5F;
rotationYaw += f1;
if (rand.nextInt(100) == 0 && world.getBlockState(blockpos1).isNormalCube())
setIsBatHanging(true);
}
}
@Override
protected boolean canTriggerWalking()
{
return false;
}
@Override
public void fall(float par1, float par2) {}
@Override
protected void updateFallState(double y, boolean onGroundIn, IBlockState blockIn, BlockPos pos) {}
@Override
public boolean doesEntityNotTriggerPressurePlate()
{
return true;
}
@Override
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
{
if (isEntityInvulnerable(par1DamageSource))
return false;
else
{
if (!world.isRemote && getIsBatHanging())
setIsBatHanging(false);
return super.attackEntityFrom(par1DamageSource, par2);
}
}
@Override
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readEntityFromNBT(par1NBTTagCompound);
dataManager.set(HANGING, Byte.valueOf(par1NBTTagCompound.getByte("BatFlags")));
}
@Override
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeEntityToNBT(par1NBTTagCompound);
par1NBTTagCompound.setByte("BatFlags", dataManager.get(HANGING).byteValue());
}
@Override
public boolean getCanSpawnHere()
{
BlockPos blockpos = new BlockPos(posX, getEntityBoundingBox().minY, posZ);
if (blockpos.getY() >= world.getSeaLevel())
return false;
else
{
int i = world.getLightFromNeighbors(blockpos);
int j = 4;
if (isDateAroundHalloween(world.getCurrentDate()))
j = 7;
else if (rand.nextBoolean())
return false;
return i > rand.nextInt(j) ? false : super.getCanSpawnHere();
}
}
private boolean isDateAroundHalloween(Calendar p_175569_1_)
{
return p_175569_1_.get(2) + 1 == 10 && p_175569_1_.get(5) >= 20 || p_175569_1_.get(2) + 1 == 11 && p_175569_1_.get(5) <= 3;
}
@Override
public float getEyeHeight()
{
return height / 2.0F;
}
}