package net.tropicraft.entity.hostile;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IRangedAttackMob;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIArrowAttack;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import net.tropicraft.entity.EntityTropicraftAnimal;
import net.tropicraft.entity.projectile.EntityPoisonBlot;
import net.tropicraft.registry.TCItemRegistry;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
public abstract class EntityTreeFrog extends EntityTropicraftAnimal implements IEntityAdditionalSpawnData, IRangedAttackMob {
/** 0 = peaceful green, 1 = red, 2 = blue, 3 = yellow */
public int type = 0;
public int jumpDelay = 0;
public int jumpDelayMax = 10;
public boolean wasOnGround = false;
public double leapVecX;
public double leapVecZ;
public EntityTreeFrog(World world) {
super(world);
setSize(0.8F, 0.8F);
this.entityCollisionReduction = 0.8F;
this.experienceValue = 5;
this.getNavigator().setAvoidsWater(true);
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIArrowAttack(this, 1.0D, 60, 10.0F));
this.tasks.addTask(2, new EntityAIWander(this, 1.0D));
this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
}
public EntityTreeFrog(World world, int parType) {
this(world);
type = parType;
}
@Override
public boolean isAIEnabled() {
return true;
}
@Override
public void updateAITasks() {
super.updateAITasks();
if (!getNavigator().noPath() || this.getAttackTarget() != null) {
if (onGround || isInWater()) {
if (jumpDelay > 0) jumpDelay--;
if (jumpDelay <= 0) {
jumpDelay = rand.nextInt(4);
getNavigator().onUpdateNavigation();
this.jump();
this.motionY += -0.01D + rand.nextDouble() * 0.1D;
double speed = 0.4D;
if (getNavigator().getPath() != null) {
try {
if (getNavigator().getPath().getCurrentPathIndex() > getNavigator().getPath().getCurrentPathLength()) {
//System.out.println("frog hopathing: path index: " + getNavigator().getPath().getCurrentPathIndex() + " > path size: " + getNavigator().getPath().getCurrentPathLength() + ", resetting path");
getNavigator().clearPathEntity();
return;
}
Vec3 pos = getNavigator().getPath().getPosition(this);
leapVecX = pos.xCoord - this.posX;
leapVecZ = pos.zCoord - this.posZ;
speed = 0.2D;
//leapVecX = 0;
//leapVecZ = 0;
} catch (Exception ex) {
//Why the hell does it crash when i touch the path data this way? is the cur path index invalid? error happens no matter the placing of above path code
//System.out.println("TreeFrog getPosition crash");
//ex.printStackTrace();
return;
}
} else if (this.getAttackTarget() != null) {
leapVecX = this.getAttackTarget().posX - this.posX;
leapVecZ = this.getAttackTarget().posZ - this.posZ;
//jumpDelay = 1;
}
if (leapVecX != 0) {
double dist2 = (double)Math.sqrt(leapVecX * leapVecX + leapVecZ * leapVecZ);
motionX += leapVecX / dist2 * speed;
//motionY += vecY / dist2 * speed;
motionZ += leapVecZ / dist2 * speed;
}
}
} else {
if (leapVecX != 0 /*&& this.curSpeed < 0.02*/) {
double speed = 0.1D;
if (isInWater()) speed = 0.2D;
double dist2 = (double)Math.sqrt(leapVecX * leapVecX + leapVecZ * leapVecZ);
motionX += leapVecX / dist2 * speed;
//motionY += vecY / dist2 * speed;
motionZ += leapVecZ / dist2 * speed;
}
}
if (isInWater()) {
motionY += 0.07D;
}
}
wasOnGround = onGround;
}
@Override
protected void applyEntityAttributes() {
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(5.0D);
}
@Override
protected void dropFewItems(boolean par1, int par2) {
int j = 2;
int k;
for (k = 0; k < j; ++k) {
this.dropItem(TCItemRegistry.frogLeg, 1);
}
}
@Override
public EntityAgeable createChild(EntityAgeable var1) {
//TODO
return null;
}
@Override
public void writeSpawnData(ByteBuf buf) {
buf.writeInt(type);
}
@Override
public void readSpawnData(ByteBuf buf) {
type = buf.readInt();
}
@Override
public void attackEntityWithRangedAttack(EntityLivingBase entity, float f) {
if (type == 0) return; // Make sure green tree frogs don't attack
if(f < 4F && !worldObj.isRemote && attackTime == 0 && worldObj.difficultySetting != EnumDifficulty.PEACEFUL)
{
double d = entity.posX - posX;
double d1 = entity.posZ - posZ;
EntityPoisonBlot entitypoisonblot = new EntityPoisonBlot(worldObj, this);
entitypoisonblot.posY += 1.3999999761581421D;
double d2 = (entity.posY + (double)entity.getEyeHeight()) - 0.20000000298023224D - entitypoisonblot.posY;
float f1 = MathHelper.sqrt_double(d * d + d1 * d1) * 0.2F;
worldObj.playSoundAtEntity(this, "frogspit", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F));
worldObj.spawnEntityInWorld(entitypoisonblot);
entitypoisonblot.setThrowableHeading(d, d2 + (double)f1, d1, 0.6F, 12F);
attackTime = 50;
rotationYaw = (float)((Math.atan2(d1, d) * 180D) / 3.1415927410125732D) - 90F;
hasAttacked = true;
}
}
@Override
public float getShadowSize() {
return 0.0F;
}
}