package crazypants.enderzoo.entity.ai; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.pathfinding.Path; import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class EntityAIAttackOnCollideAggressive extends EntityAIBase { World worldObj; EntityCreature attacker; int ticksToNextAttack; double speedTowardsTarget; boolean longMemory; Path entityPathEntity; Class<?> classTarget; private int ticksUntilNextPathingAttempt; private double targetX; private double targetY; private double targetZ; // private int failedPathFindingPenalty; private int attackFrequency = 20; public EntityAIAttackOnCollideAggressive(EntityCreature attacker, Class<?> targetClass, double attackSpeed, boolean longMemory) { this(attacker, attackSpeed, longMemory); classTarget = targetClass; } public EntityAIAttackOnCollideAggressive(EntityCreature attacker, double attackSpeed, boolean longMemory) { this.attacker = attacker; worldObj = attacker.world; speedTowardsTarget = attackSpeed; this.longMemory = longMemory; setMutexBits(3); } public int getAttackFrequency() { return attackFrequency; } public EntityAIAttackOnCollideAggressive setAttackFrequency(int attackFrequency) { this.attackFrequency = attackFrequency; return this; } /** * Returns whether the EntityAIBase should begin execution. */ @Override public boolean shouldExecute() { EntityLivingBase entitylivingbase = attacker.getAttackTarget(); if (entitylivingbase == null) { return false; } else if (!entitylivingbase.isEntityAlive()) { return false; } else if (classTarget != null && !classTarget.isAssignableFrom(entitylivingbase.getClass())) { return false; } else { if (--ticksUntilNextPathingAttempt <= 0) { entityPathEntity = attacker.getNavigator().getPathToEntityLiving(entitylivingbase); ticksUntilNextPathingAttempt = 4 + attacker.getRNG().nextInt(7); return entityPathEntity != null; } else { return true; } } } /** * Returns whether an in-progress EntityAIBase should continue executing */ @Override public boolean shouldContinueExecuting() { EntityLivingBase entitylivingbase = attacker.getAttackTarget(); return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!longMemory ? !attacker.getNavigator().noPath() : attacker .isWithinHomeDistanceCurrentPosition())); } @Override public void startExecuting() { attacker.getNavigator().setPath(entityPathEntity, speedTowardsTarget); ticksUntilNextPathingAttempt = 0; } @Override public void resetTask() { attacker.getNavigator().clearPathEntity(); } /** * Updates the task */ @Override public void updateTask() { EntityLivingBase entitylivingbase = attacker.getAttackTarget(); attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F); double distToTargetSq = attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.getEntityBoundingBox().minY, entitylivingbase.posZ); double attachRange = attacker.width * 2.0F * attacker.width * 2.0F + entitylivingbase.width; --ticksUntilNextPathingAttempt; if ((longMemory || attacker.getEntitySenses().canSee(entitylivingbase)) && ticksUntilNextPathingAttempt <= 0 && (targetX == 0.0D && targetY == 0.0D && targetZ == 0.0D || entitylivingbase.getDistanceSq(targetX, targetY, targetZ) >= 1.0D || attacker.getRNG() .nextFloat() < 0.05F)) { targetX = entitylivingbase.posX; targetY = entitylivingbase.getEntityBoundingBox().minY; targetZ = entitylivingbase.posZ; //ticksUntilNextPathingAttempt = failedPathFindingPenalty + 4 + attacker.getRNG().nextInt(7); // if (attacker.getNavigator().getPath() != null) { // PathPoint finalPathPoint = attacker.getNavigator().getPath().getFinalPathPoint(); // if (finalPathPoint != null && entitylivingbase.getDistanceSq(finalPathPoint.xCoord, finalPathPoint.yCoord, finalPathPoint.zCoord) < 1) { // failedPathFindingPenalty = 0; // } else { // failedPathFindingPenalty += 10; // } // } else { // failedPathFindingPenalty += 10; // } if (distToTargetSq > 1024.0D) { ticksUntilNextPathingAttempt += 10; } else if (distToTargetSq > 256.0D) { ticksUntilNextPathingAttempt += 5; } if (!attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, speedTowardsTarget)) { ticksUntilNextPathingAttempt += 15; } } ticksToNextAttack = Math.max(ticksToNextAttack - 1, 0); if (distToTargetSq <= attachRange && ticksToNextAttack <= 20) { ticksToNextAttack = attackFrequency; if (attacker.getHeldItem(EnumHand.MAIN_HAND) != null) { attacker.swingArm(EnumHand.MAIN_HAND); } attacker.attackEntityAsMob(entitylivingbase); } } }