package minefantasy.entity;
import java.util.List;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import minefantasy.item.ArmourDesign;
import minefantasy.item.ItemListMF;
import minefantasy.system.TacticalManager;
import minefantasy.system.cfg;
import minefantasy.system.data_minefantasy;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
import net.minecraft.entity.ai.EntityAIBreakDoor;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.passive.EntityTameable;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
public class EntityBasilisk extends EntityMob {
public EntityBasilisk(World world)
{
super(world);
this.setSize(2.0F, 1.0F);
applyRandomBreed();
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false));
this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityVillager.class, 1.0D, true));
this.tasks.addTask(6, new EntityAIWander(this, 1.0D));
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(7, new EntityAILookIdle(this));
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityVillager.class, 0, false));
}
@Override
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.followRange).setAttribute(16.0D);
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setAttribute(0.23000000417232513D);
this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setAttribute(4.0F);
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setAttribute(30.0F);
}
@Override
public boolean getCanSpawnHere()
{
if(dimension != -1 && rand.nextInt(10) != 0)
{
return false;
}
if(!canSpawnAtPos())
{
return false;
}
return super.getCanSpawnHere();
}
public boolean canSpawnAtPos() {
if(this.dimension != 0)
{
return true;
}
ChunkCoordinates spawn = worldObj.getSpawnPoint();
if(!worldObj.canBlockSeeTheSky((int)posX, (int)posY+1, (int)posZ))
{
return false;
}
return this.getDistance(spawn.posX, spawn.posY, spawn.posZ) > cfg.basiliskDistance;
}
@Override
public int getTotalArmorValue()
{
switch(getBreed())
{
case 0:return 10;
case 1:return 15;
case 2:return 20;
}
return super.getTotalArmorValue();
}
@Override
public boolean attackEntityFrom(DamageSource source, float dam)
{
this.setMouthTicks(10);
return super.attackEntityFrom(source, dam);
}
protected void entityInit()
{
super.entityInit();
this.getDataWatcher().addObject(12, Byte.valueOf((byte)-1));
this.getDataWatcher().addObject(13, Integer.valueOf(0));
this.getDataWatcher().addObject(14, Integer.valueOf(0));
}
public void setBreed(byte breed)
{
if(breed == 2)
{
isImmuneToFire = true;
}
else
{
isImmuneToFire = false;
}
getDataWatcher().updateObject(12, breed);
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setAttribute(getBreedHealth());
this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setAttribute(getAttackStrength());
}
public void setMouthTicks(int tick)
{
getDataWatcher().updateObject(13, tick);
}
/**
* gets the breed
* @return 0 = poison, 1 = petrify, 2 = nether
*/
public byte getBreed()
{
return getDataWatcher().getWatchableObjectByte(12);
}
public int getMouthTicks()
{
return getDataWatcher().getWatchableObjectInt(13);
}
public void setGazeTime(int tick)
{
getDataWatcher().updateObject(14, tick);
}
public int getGazeTime()
{
return getDataWatcher().getWatchableObjectInt(14);
}
/**
* Sets to nether in nether,
* 1:5 chance stone:poison in over
*/
public void applyRandomBreed()
{
if(this.dimension == -1)
{
setBreed((byte)2);
setSize(3.0F, 2.0F);
}
else
{
if(rand.nextInt(3) == 0 && getDistanceAway() > cfg.basiliskDistance*2)
{
setBreed((byte)1);
}
else
setBreed((byte)0);
}
this.setHealth(getMaxHealth());
}
public float getBreedHealth()
{
if(getBreed() == 2)
{
return 60F;
}
return 30F;
}
@SideOnly(Side.CLIENT)
public String getTexture()
{
return data_minefantasy.image("/mob/Basilisk" + getBreedStr() + ".png");
}
public float getAttackStrength()
{
switch(getBreed())
{
case 1:
return 10;
case 2:
return 12;
}
return 8;
}
@Override
public void onLivingUpdate()
{
super.onLivingUpdate();
if(!worldObj.isRemote)
{
int sndTimer = getGazeTime();
if(sndTimer > 0)sndTimer --;
setGazeTime(sndTimer);
int mouth = getMouthTicks();
if(mouth > 0)mouth --;
setMouthTicks(mouth);
for(int a = 0; a < worldObj.playerEntities.size(); a ++)
{
EntityPlayer pl = (EntityPlayer)worldObj.playerEntities.get(a);
if(isCrosshairOver(pl))
{
if(!pl.capabilities.isCreativeMode)
applyGaze(pl);
}
}
if(getAttackTarget() != null)
{
EntityLivingBase tar = getAITarget();
if(tar != null && tar != riddenByEntity && !(tar instanceof EntityBasilisk) && tar != this)
{
if(!(tar instanceof EntityPlayer))
{
if(this.canEntityBeSeen(tar) && !TacticalManager.isFlankedBy(this, tar, 270) && !TacticalManager.isFlankedBy(tar, this, 270))
{
applyGaze(tar);
}
}
}
}
}
}
public String getBreedStr()
{
if(getBreed() == 1)return "Stone";
if(getBreed() == 2)return "Fire";
return "";
}
@Override
protected boolean isAIEnabled()
{
return true;
}
public void writeEntityToNBT(NBTTagCompound nbt)
{
super.writeEntityToNBT(nbt);
nbt.setByte("Breed", getBreed());
nbt.setInteger("Gaze", getGazeTime());
}
public void readEntityFromNBT(NBTTagCompound nbt)
{
super.readEntityFromNBT(nbt);
setBreed(nbt.getByte("Breed"));
setGazeTime(nbt.getInteger("Gaze"));
}
public boolean isCrosshairOver(EntityPlayer player)
{
if(!TacticalManager.isFlankedBy(player, this, 270))
{
Vec3 var3 = player.getLook(1.0F).normalize();
Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX - player.posX, this.boundingBox.minY + (double)(this.height / 2.0F) - (player.posY + (double)player.getEyeHeight()), this.posZ - player.posZ);
double var5 = var4.lengthVector();
var4 = var4.normalize();
double var7 = var3.dotProduct(var4);
return var7 > 1.0D - 0.025D / var5 ? player.canEntityBeSeen(this) : false;
}
return false;
}
public void applyGaze(EntityLivingBase target)
{
if(worldObj.isRemote)return;
if(getGazeTime() > 0)return;
boolean hit = false;
byte breed = getBreed();
int diff = worldObj.difficultySetting;
if(getBreed() == 0)//Poison
{
target.addPotionEffect(new PotionEffect(Potion.poison.id, 200 * diff, 1));
}
if(getBreed() == 1)//Petrify
{
target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 300 * diff, 100));
target.addPotionEffect(new PotionEffect(Potion.digSlowdown.id, 300 * diff, 100));
}
if(getBreed() == 2)//Fire
{
target.setFire(5*diff);
}
if(getAttackTarget() == null)
{
setAttackTarget(target);
this.getNavigator().tryMoveToEntityLiving(target, 0.22F);
}
worldObj.playSoundAtEntity(target, "mob.zombie.unfect", 1.0F, 1.0F);
setGazeTime(getCooldown());
}
private int getCooldown() {
if(getBreed() == 2)
{
return 40;
}
return 60;
}
@Override
public boolean attackEntityAsMob(Entity en)
{
if(!this.canEntityBeSeen(en))return false;
this.setMouthTicks(10);
worldObj.playSoundAtEntity(this, data_minefantasy.sound("mob.bite"), 1, 1);
return super.attackEntityAsMob(en);
}
@Override
public void onDeath(DamageSource source)
{
super.onDeath(source);
this.setMouthTicks(10);
}
@Override
protected String getLivingSound()
{
return data_minefantasy.sound("mob.hiss");
}
@Override
protected String getHurtSound()
{
return "damage.hit";
}
@Override
protected String getDeathSound()
{
return "damage.hit";
}
@Override
public float getSoundPitch()
{
return 1.0F;
}
@Override
public void playLivingSound()
{
super.playLivingSound();
this.setMouthTicks(3);
}
@Override
protected void playStepSound(int x, int y, int z, int m)
{
this.playSound(data_minefantasy.sound("mob.basiliskWalk"), 1F, 1.0F);
}
@Override
public String getEntityName()
{
if(getBreed() == 2)
{
return "Nether Basilisk";
}
return "Basilisk";
}//EntitySpider
public float getScale() {
if(getBreed() == 2)
{
return 1.5F;
}
return 1.0F;
}
@Override
protected int getDropItemId()
{
return 0;
}
@Override
protected void dropFewItems(boolean playerKill, int looting)
{
int counter;
int amount = this.rand.nextInt(2) + this.rand.nextInt(1 + looting);
for (counter = 0; counter < amount; ++counter)
{
if (this.isBurning())
{
this.dropItem(ItemListMF.basiliskCooked.itemID, 1);
}
else
{
this.dropItem(ItemListMF.basiliskRaw.itemID, 1);
}
}
amount = 1 + this.rand.nextInt(1 + looting);
for (counter = 0; counter < amount; ++counter)
{
this.dropItem(ItemListMF.misc.itemID, 1, getHide());
}
if(getBreed() == 2)
{
if (playerKill && (this.rand.nextInt(3) == 0 || this.rand.nextInt(1 + looting) > 0))
{
this.dropItem(Item.netherStalkSeeds.itemID, 1);
}
}
}
private int getHide()
{
switch(getBreed())
{
case 0:return ItemListMF.hideBasiliskBlue;
case 1:return ItemListMF.hideBasiliskBrown;
case 2:return ItemListMF.hideBasiliskBlack;
}
return ItemListMF.hideBasiliskBlue;
}
public EntityItem dropItem(int id, int num, int dam)
{
return this.dropItemWithOffset(id, num, dam, 0.0F);
}
public EntityItem dropItemWithOffset(int id, int stack, int damage, float offset)
{
return this.entityDropItem(new ItemStack(id, stack, damage), offset);
}
public float getMouthAngle()
{
float ang = (float)getMouthTicks();
if(ang > 10F)ang = 10F;
return ang/10;
}
private double getDistanceAway()
{
ChunkCoordinates spawn = worldObj.getSpawnPoint();
return this.getDistance(spawn.posX, spawn.posY, spawn.posZ);
}
}