Files
AdapativeMobs/src/main/java/net/fretux/adaptivemobs/ai/goals/AdaptiveEvokerTacticsGoal.java
T
2026-06-29 15:59:48 +02:00

81 lines
3.2 KiB
Java

package net.fretux.adaptivemobs.ai.goals;
import net.fretux.adaptivemobs.ai.AdaptiveAIGoalUtils;
import net.fretux.adaptivemobs.ai.AdaptivePositioningUtils;
import net.fretux.adaptivemobs.ai.AdaptiveTargetingUtils;
import net.fretux.adaptivemobs.config.AMConfig;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.monster.AbstractIllager;
import net.minecraft.world.entity.monster.Evoker;
import net.minecraft.world.phys.Vec3;
import java.util.EnumSet;
import java.util.function.IntSupplier;
public class AdaptiveEvokerTacticsGoal extends Goal {
private final Evoker evoker;
private final IntSupplier tierSupplier;
private int cooldown;
private int lastSpellTicks;
private int stillTicks;
private Vec3 lastPos = Vec3.ZERO;
public AdaptiveEvokerTacticsGoal(Evoker evoker, IntSupplier tierSupplier) {
this.evoker = evoker;
this.tierSupplier = tierSupplier;
setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK));
}
@Override
public boolean canUse() {
return AMConfig.ENABLE_RAID_MOB_AI.get()
&& AMConfig.ENABLE_EVOKER_AI.get()
&& AMConfig.AI_EVOKER.get()
&& tierSupplier.getAsInt() >= 2
&& evoker.getTarget() != null
&& evoker.getTarget().isAlive()
&& --cooldown <= 0;
}
@Override
public void start() {
cooldown = evoker.isCastingSpell() ? 35 + evoker.getRandom().nextInt(35) : 55 + evoker.getRandom().nextInt(55);
LivingEntity target = evoker.getTarget();
if (target == null) {
return;
}
int tier = tierSupplier.getAsInt();
double distance = Math.sqrt(evoker.distanceToSqr(target));
boolean justCast = lastSpellTicks > 0 || evoker.isCastingSpell();
lastSpellTicks = evoker.isCastingSpell() ? 60 : Math.max(0, lastSpellTicks - cooldown);
updateStillTicks();
boolean meleeRush = distance < 7.0D && !AdaptiveAIGoalUtils.isUsingRangedWeapon(target);
boolean exposed = evoker.hasLineOfSight(target) && !AdaptiveAIGoalUtils.isBlockingShield(target);
boolean useCover = tier >= 4 && AdaptiveTargetingUtils.nearbyHostiles(evoker, 8.0D,
other -> other instanceof AbstractIllager && other != evoker && other.getTarget() == target).size() > 0;
if (meleeRush || justCast || stillTicks > 3 || (useCover && exposed)) {
Vec3 dest = useCover
? AdaptivePositioningUtils.sidePosition(evoker, target, 10.0D, evoker.getRandom().nextBoolean() ? 1.0D : -1.0D, 0.0D)
: AdaptivePositioningUtils.retreatPosition(evoker, target, meleeRush ? 6.0D : 4.0D);
if (AdaptivePositioningUtils.isReasonableGround(evoker, dest)) {
evoker.getNavigation().moveTo(dest.x, dest.y, dest.z, 1.0D);
AdaptiveAIGoalUtils.debug(evoker, tierSupplier, "evoker reposition");
}
}
}
private void updateStillTicks() {
Vec3 pos = evoker.position();
if (pos.distanceToSqr(lastPos) < 0.08D) {
stillTicks++;
} else {
stillTicks = 0;
}
lastPos = pos;
}
}