Initial commit
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user