Files
CustomNPC-Plus/src/main/java/noppes/npcs/ai/EntityAIRangedAttack.java
T
2025-05-20 13:53:26 -04:00

171 lines
6.3 KiB
Java

package noppes.npcs.ai;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IRangedAttackMob;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.util.MathHelper;
import noppes.npcs.constants.AiMutex;
import noppes.npcs.constants.EnumAnimation;
import noppes.npcs.constants.EnumNavType;
import noppes.npcs.entity.EntityNPCInterface;
public class EntityAIRangedAttack extends EntityAIBase {
/**
* The entity the AI instance has been applied to
*/
private final EntityNPCInterface entityHost;
/**
* The entity (as a RangedAttackMob) the AI instance has been applied to.
*/
private final IRangedAttackMob rangedAttackEntityHost;
private EntityLivingBase attackTarget;
/**
* A decrementing tick that spawns a ranged attack once this value reaches 0. It is then set back to the
* maxRangedAttackTime.
*/
private int rangedAttackTime = 0;
private int field_75318_f = 0;
private int field_70846_g = 0;
private int attackTick = 0;
private boolean hasFired = false;
private boolean navOverride = false;
private boolean isShooting = false;
public EntityAIRangedAttack(IRangedAttackMob par1IRangedAttackMob) {
if (!(par1IRangedAttackMob instanceof EntityLivingBase)) {
throw new IllegalArgumentException("ArrowAttackGoal requires Mob implements RangedAttackMob");
} else {
this.rangedAttackEntityHost = par1IRangedAttackMob;
this.entityHost = (EntityNPCInterface) par1IRangedAttackMob;
this.rangedAttackTime = this.entityHost.stats.minDelay / 2;
this.setMutexBits(this.navOverride ? AiMutex.PATHING : AiMutex.LOOK + AiMutex.PASSIVE);
}
}
/**
* Returns whether the EntityAIBase should begin execution.
*/
public boolean shouldExecute() {
EntityLivingBase var1 = this.entityHost.getAttackTarget();
if (var1 == null || !var1.isEntityAlive()) {
isShooting = false;
return false;
}
if (entityHost.getDistanceToEntity(var1) > entityHost.stats.aggroRange) {
isShooting = false;
return false;
}
if (this.entityHost.inventory.getProjectile() == null) {
isShooting = false;
return false;
}
double var2 = this.entityHost.getDistanceSq(var1.posX, var1.boundingBox.minY, var1.posZ);
double var3 = this.entityHost.ais.distanceToMelee * this.entityHost.ais.distanceToMelee;
if (this.entityHost.ais.useRangeMelee >= 1 && var2 <= var3) {
isShooting = false;
return false;
} else {
this.attackTarget = var1;
return true;
}
}
/**
* Returns whether an in-progress EntityAIBase should continue executing
*/
public boolean continueExecuting() {
return this.shouldExecute() || !this.entityHost.getNavigator().noPath();
}
/**
* Resets the task
*/
public void resetTask() {
this.attackTarget = null;
this.entityHost.setAttackTarget(null);
this.entityHost.getNavigator().clearPathEntity();
this.field_75318_f = 0;
this.hasFired = false;
this.rangedAttackTime = this.entityHost.stats.minDelay / 2;
}
/**
* Updates the task
*/
public void updateTask() {
this.entityHost.getLookHelper().setLookPositionWithEntity(this.attackTarget, 30.0F, 30.0F);
double var1 = this.entityHost.getDistanceSq(this.attackTarget.posX, this.attackTarget.boundingBox.minY, this.attackTarget.posZ);
float field_82642_h = this.entityHost.stats.rangedRange * this.entityHost.stats.rangedRange;
if (!navOverride && this.entityHost.ais.directLOS) {
if (this.entityHost.getEntitySenses().canSee(this.attackTarget)) {
++this.field_75318_f;
} else {
this.field_75318_f = 0;
}
int v = this.entityHost.ais.tacticalVariant == EnumNavType.Default ? 20 : 5;
if (var1 <= (double) field_82642_h && this.field_75318_f >= v) {
this.entityHost.getNavigator().clearPathEntity();
} else {
this.entityHost.getNavigator().tryMoveToEntityLiving(this.attackTarget, 1.0D);
}
}
this.rangedAttackTime = Math.max(this.rangedAttackTime - 1, 0);
if (this.rangedAttackTime <= 0) {
if (var1 <= (double) field_82642_h && (this.entityHost.getEntitySenses().canSee(this.attackTarget) || this.entityHost.ais.canFireIndirect == 2)) {
if (this.field_70846_g == 0) {
this.entityHost.stats.playBurstSound = true;
}
if (this.field_70846_g++ <= this.entityHost.stats.burstCount) {
this.rangedAttackTime = this.entityHost.stats.fireRate;
this.isShooting = true;
} else {
this.field_70846_g = 0;
this.hasFired = true;
this.rangedAttackTime = (this.entityHost.stats.maxDelay - MathHelper.floor_float(this.entityHost.getRNG().nextFloat() * (this.entityHost.stats.maxDelay - this.entityHost.stats.minDelay)));
this.isShooting = false;
}
if (this.field_70846_g > 1) {
boolean indirect = false;
switch (this.entityHost.ais.canFireIndirect) {
case 1:
indirect = var1 > (double) field_82642_h / 2;
break;
case 2:
indirect = !this.entityHost.getEntitySenses().canSee(this.attackTarget);
}
this.rangedAttackEntityHost.attackEntityWithRangedAttack(this.attackTarget, indirect ? 1 : 0);
if (this.entityHost.currentAnimation != EnumAnimation.AIMING) {
this.entityHost.swingItem();
}
}
}
}
}
public boolean hasFired() {
return this.hasFired;
}
public boolean isShooting() {
return this.isShooting;
}
public void navOverride(boolean nav) {
this.navOverride = nav;
this.setMutexBits(this.navOverride ? AiMutex.PATHING : AiMutex.LOOK + AiMutex.PASSIVE);
}
}